Skip to content

Commit

Permalink
Merge pull request #1066 from mozilla/qa-stage
Browse files Browse the repository at this point in the history
Hubs Cloud QA Update 2021-01-07
  • Loading branch information
Softvision-GeluHaiduc authored Jan 15, 2021
2 parents 8ad1657 + 2f03ef0 commit e37746b
Show file tree
Hide file tree
Showing 18 changed files with 1,557 additions and 123 deletions.
2 changes: 1 addition & 1 deletion REMIXING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Remixing

Allowing remixing means that others can download, edit, change, and re-publish your Spoke scene as long as they give credit to the creators of the scene. If you allow allow remixing, you agree to license your scene under a [CC-BY 3.0](https://creativecommons.org/licenses/by/3.0/legalcode) license. We’ll provide you an opportunity to include the attribution information you want to include. This information will be associated with the scene, but not stored with you account.
Allowing remixing means that others can download, edit, change, and re-publish your Spoke scene as long as they give credit to the creators of the scene. If you allow allow remixing, you agree to license your scene under a [CC-BY 3.0](https://creativecommons.org/licenses/by/3.0/legalcode) license. We’ll provide you an opportunity to include the attribution information you want to include. This information will be associated with the scene, but not stored with your account.

You can change this setting at any time, by re-publishing your scene.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"test": "concurrently --success \"first\" --kill-others \"yarn test-all\" \"yarn test-server\"",
"test-server": "cross-env NODE_ENV=test webpack-dev-server --mode development --content-base ./test/fixtures",
"test-all": "ava --verbose",
"test-ci": "ava --tap | tap-xunit > ./test/reports/ava.xml",
"test-ci": "ava --serial --tap | tap-xunit > ./test/reports/ava.xml",
"unit-tests": "ava ./test/unit/**/*.test.js",
"integration-tests": "concurrently --success \"first\" --kill-others \"ava ./test/integration\" \"yarn test-server\"",
"update-test-snapshots": "concurrently --success \"first\" --kill-others \"ava -u\" \"yarn test-server\"",
Expand Down
2 changes: 1 addition & 1 deletion src/editor/MeshCombinationGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export default class MeshCombinationGroup {
}

await asyncTraverse(rootObject, async object => {
if (isStatic(object) && object.isMesh) {
if (isStatic(object) && object.isMesh && object._combine !== false) {
let added = false;

for (const group of meshCombinationGroups) {
Expand Down
7 changes: 7 additions & 0 deletions src/editor/nodes/EditorNodeMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,13 @@ export default function EditorNodeMixin(Object3DClass) {
}
}

/**
* Adds a GLTF component
* @param {String} name The component name to be replaced
* @param {Object} props The component properties to be set
* @param {boolean} params Parameters object
* @param {{THREE.Object3D} params.node The target Object3D element
*/
addGLTFComponent(name, props) {
if (!this.userData.gltfExtensions) {
this.userData.gltfExtensions = {};
Expand Down
53 changes: 34 additions & 19 deletions src/editor/nodes/KitPieceNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Model from "../objects/Model";
import { PropertyBinding } from "three";
import { setStaticMode, StaticModes } from "../StaticMode";
import cloneObject3D from "../utils/cloneObject3D";
import { getComponents } from "../gltf/moz-hubs-components";
import { isKitPieceNode, getComponent, getGLTFComponent, traverseGltfNode } from "../gltf/moz-hubs-components";
import { RethrownError } from "../utils/errors";

Expand All @@ -28,17 +29,22 @@ export default class KitPieceNode extends EditorNodeMixin(Model) {

node.collidable = !!json.components.find(c => c.name === "collidable");
node.walkable = !!json.components.find(c => c.name === "walkable");
node.combine = !!json.components.find(c => c.name === "combine");

const loopAnimationComponent = json.components.find(c => c.name === "loop-animation");

if (loopAnimationComponent && loopAnimationComponent.props) {
const { clip, activeClipIndex } = loopAnimationComponent.props;
const { clip, activeClipIndices } = loopAnimationComponent.props;

if (activeClipIndex !== undefined) {
node.activeClipIndex = loopAnimationComponent.props.activeClipIndex;
} else if (clip !== undefined && node.model && node.model.animations) {
if (clip !== undefined && node.model && node.model.animations) {
// DEPRECATED: Old loop-animation component stored the clip name rather than the clip index
node.activeClipIndex = node.model.animations.findIndex(animation => animation.name === clip);
const clipIndex = node.model.animations.findIndex(animation => animation.name === clip);

if (clipIndex !== -1) {
node.activeClipItems = node.getActiveItems([clipIndex]);
}
} else {
node.activeClipItems = node.getActiveItems(activeClipIndices);
}
}

Expand All @@ -60,6 +66,7 @@ export default class KitPieceNode extends EditorNodeMixin(Model) {
this._canonicalUrl = "";
this.collidable = true;
this.walkable = true;
this.combine = true;
this._kitId = null;
this._pieceId = null;
this.subPieces = [];
Expand Down Expand Up @@ -422,9 +429,9 @@ export default class KitPieceNode extends EditorNodeMixin(Model) {
}
};

if (this.activeClipIndex !== -1) {
if (this.activeClipIndices.length > 0) {
components["loop-animation"] = {
activeClipIndex: this.activeClipIndex
activeClipIndices: this.activeClipIndices
};
}

Expand All @@ -436,6 +443,10 @@ export default class KitPieceNode extends EditorNodeMixin(Model) {
components.walkable = {};
}

if (this.combine) {
components.combine = {};
}

return super.serialize(components);
}

Expand All @@ -448,6 +459,7 @@ export default class KitPieceNode extends EditorNodeMixin(Model) {
this._pieceId = source._pieceId;
this.collidable = source.collidable;
this.walkable = source.walkable;
this.combine = source.combine;

// TODO update the sub-piece copy method
if (this.model) {
Expand Down Expand Up @@ -502,19 +514,22 @@ export default class KitPieceNode extends EditorNodeMixin(Model) {
receive: this.receiveShadow
});

// TODO: Support exporting more than one active clip.
if (this.activeClip) {
const activeClipIndex = ctx.animations.indexOf(this.activeClip);

if (activeClipIndex === -1) {
throw new Error(
`Error exporting model "${this.name}" with url "${this._canonicalUrl}". Animation could not be found.`
);
} else {
this.addGLTFComponent("loop-animation", {
activeClipIndex: activeClipIndex
});
const clipIndices = this.activeClipIndices.map(index => {
return ctx.animations.indexOf(this.model.animations[index]);
});

this.model.traverse(child => {
const components = getComponents(child);

if (components && components["loop-animation"]) {
delete components["loop-animation"];
}
});

if (clipIndices.length > 0) {
this.addGLTFComponent("loop-animation", {
activeClipIndices: clipIndices
});
}

if (this.model) {
Expand Down
51 changes: 33 additions & 18 deletions src/editor/nodes/ModelNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Model from "../objects/Model";
import EditorNodeMixin from "./EditorNodeMixin";
import { setStaticMode, StaticModes } from "../StaticMode";
import cloneObject3D from "../utils/cloneObject3D";
import { getComponents } from "../gltf/moz-hubs-components";
import { RethrownError } from "../utils/errors";
import { getObjectPerfIssues, maybeAddLargeFileIssue } from "../utils/performance";

Expand Down Expand Up @@ -48,17 +49,22 @@ export default class ModelNode extends EditorNodeMixin(Model) {

node.collidable = !!json.components.find(c => c.name === "collidable");
node.walkable = !!json.components.find(c => c.name === "walkable");
node.combine = !!json.components.find(c => c.name === "combine");

const loopAnimationComponent = json.components.find(c => c.name === "loop-animation");

if (loopAnimationComponent && loopAnimationComponent.props) {
const { clip, activeClipIndex } = loopAnimationComponent.props;
const { clip, activeClipIndices } = loopAnimationComponent.props;

if (activeClipIndex !== undefined) {
node.activeClipIndex = loopAnimationComponent.props.activeClipIndex;
} else if (clip !== undefined && node.model && node.model.animations) {
if (clip !== undefined && node.model && node.model.animations) {
// DEPRECATED: Old loop-animation component stored the clip name rather than the clip index
node.activeClipIndex = node.model.animations.findIndex(animation => animation.name === clip);
const clipIndex = node.model.animations.findIndex(animation => animation.name === clip);

if (clipIndex !== -1) {
node.activeClipItems = node.getActiveItems([clipIndex]);
}
} else {
node.activeClipItems = node.getActiveItems(activeClipIndices);
}
}

Expand All @@ -80,6 +86,7 @@ export default class ModelNode extends EditorNodeMixin(Model) {
this._canonicalUrl = "";
this.collidable = true;
this.walkable = true;
this.combine = true;
this.initialScale = 1;
this.boundingBox = new Box3();
this.boundingSphere = new Sphere();
Expand Down Expand Up @@ -315,9 +322,9 @@ export default class ModelNode extends EditorNodeMixin(Model) {
}
};

if (this.activeClipIndex !== -1) {
if (this.activeClipIndices.length > 0) {
components["loop-animation"] = {
activeClipIndex: this.activeClipIndex
activeClipIndices: this.activeClipIndices
};
}

Expand All @@ -329,6 +336,10 @@ export default class ModelNode extends EditorNodeMixin(Model) {
components.walkable = {};
}

if (this.combine) {
components.combine = {};
}

return super.serialize(components);
}

Expand All @@ -348,6 +359,7 @@ export default class ModelNode extends EditorNodeMixin(Model) {
this.attribution = source.attribution;
this.collidable = source.collidable;
this.walkable = source.walkable;
this.combine = source.combine;
return this;
}

Expand All @@ -358,19 +370,22 @@ export default class ModelNode extends EditorNodeMixin(Model) {
receive: this.receiveShadow
});

// TODO: Support exporting more than one active clip.
if (this.activeClip) {
const activeClipIndex = ctx.animations.indexOf(this.activeClip);
const clipIndices = this.activeClipIndices.map(index => {
return ctx.animations.indexOf(this.model.animations[index]);
});

this.model.traverse(child => {
const components = getComponents(child);

if (activeClipIndex === -1) {
throw new Error(
`Error exporting model "${this.name}" with url "${this._canonicalUrl}". Animation could not be found.`
);
} else {
this.addGLTFComponent("loop-animation", {
activeClipIndex: activeClipIndex
});
if (components && components["loop-animation"]) {
delete components["loop-animation"];
}
});

if (clipIndices.length > 0) {
this.addGLTFComponent("loop-animation", {
activeClipIndices: clipIndices
});
}
}
}
50 changes: 44 additions & 6 deletions src/editor/nodes/SceneNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,44 @@ function migrateV3ToV4(json) {
return json;
}

const combineComponents = ["gltf-model", "kit-piece"];

function migrateV4ToV5(json) {
json.version = 5;

for (const entityId in json.entities) {
if (!Object.prototype.hasOwnProperty.call(json.entities, entityId)) continue;

const entity = json.entities[entityId];

if (!entity.components) {
continue;
}

const animationComponent = entity.components.find(c => c.name === "loop-animation");

if (animationComponent) {
// Prior to V5 animation clips were stored in activeClipIndex as an integer
const { activeClipIndex } = animationComponent.props;
delete animationComponent.props.activeClipIndex;
// In V5+ activeClipIndices stores an array of integers. It may be undefined if migrating from a legacy scene where the
// clip property stores the animation clip name. We can't migrate this here so we do it in ModelNode and KitPieceNode.
animationComponent.props.activeClipIndices = activeClipIndex !== undefined ? [activeClipIndex] : [];
}

const hasCombineComponent = entity.components.find(c => combineComponents.indexOf(c.name) !== -1);

if (hasCombineComponent) {
entity.components.push({
name: "combine",
props: {}
});
}
}

return json;
}

export const FogType = {
Disabled: "disabled",
Linear: "linear",
Expand Down Expand Up @@ -166,6 +204,10 @@ export default class SceneNode extends EditorNodeMixin(Scene) {
json = migrateV3ToV4(json);
}

if (json.version === 4) {
json = migrateV4ToV5(json);
}

const { root, metadata, entities } = json;

let scene = null;
Expand Down Expand Up @@ -403,7 +445,7 @@ export default class SceneNode extends EditorNodeMixin(Scene) {

serialize() {
const sceneJson = {
version: 4,
version: 5,
root: this.uuid,
metadata: JSON.parse(JSON.stringify(this.metadata)),
entities: {
Expand Down Expand Up @@ -577,11 +619,7 @@ export default class SceneNode extends EditorNodeMixin(Scene) {

this.traverse(child => {
if (child.isNode && child.type === "Model") {
const activeClip = child.activeClip;

if (activeClip) {
animations.push(child.activeClip);
}
animations.push(...child.clips);
}
});

Expand Down
15 changes: 12 additions & 3 deletions src/editor/nodes/SpawnerNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export default class SpawnerNode extends EditorNodeMixin(Model) {
static async deserialize(editor, json, loadAsync, onError) {
const node = await super.deserialize(editor, json);

const { src } = json.components.find(c => c.name === "spawner").props;
const { src, applyGravity } = json.components.find(c => c.name === "spawner").props;

node.applyGravity = !!applyGravity;

loadAsync(node.load(src, onError));

Expand All @@ -47,6 +49,7 @@ export default class SpawnerNode extends EditorNodeMixin(Model) {
this.boundingSphere = new Sphere();
this.stats = defaultStats;
this.gltfJson = null;
this.applyGravity = false;
}

// Overrides Model's src property and stores the original (non-resolved) url.
Expand Down Expand Up @@ -215,7 +218,8 @@ export default class SpawnerNode extends EditorNodeMixin(Model) {
serialize() {
return super.serialize({
spawner: {
src: this._canonicalUrl
src: this._canonicalUrl,
applyGravity: this.applyGravity
}
});
}
Expand All @@ -232,13 +236,18 @@ export default class SpawnerNode extends EditorNodeMixin(Model) {
this._canonicalUrl = source._canonicalUrl;
}

this.applyGravity = source.applyGravity;

return this;
}

prepareForExport() {
super.prepareForExport();
this.addGLTFComponent("spawner", {
src: this._canonicalUrl
src: this._canonicalUrl,
mediaOptions: {
applyGravity: this.applyGravity
}
});
this.replaceObject();
}
Expand Down
Loading

0 comments on commit e37746b

Please sign in to comment.