Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix serialization when objects have InstancedMesh parents #12690

Merged
merged 4 commits into from
Jun 28, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/dev/core/src/Cameras/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ export class Camera extends Node {

// Parent
if (this.parent) {
serializationObject.parentId = this.parent.uniqueId;
this.parent._serializeAsParent(serializationObject);
}

if (this.inputs) {
Expand Down Expand Up @@ -1380,6 +1380,11 @@ export class Camera extends Node {
camera._waitingParentId = parsedCamera.parentId;
}

// Parent instance index
if (parsedCamera.parentInstanceIndex !== undefined) {
camera._waitingParentInstanceIndex = parsedCamera.parentInstanceIndex;
}

//If camera has an input manager, let it parse inputs settings
if (camera.inputs) {
camera.inputs.parse(parsedCamera);
Expand Down
6 changes: 5 additions & 1 deletion packages/dev/core/src/Lights/light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ export abstract class Light extends Node implements ISortableLight {

// Parent
if (this.parent) {
serializationObject.parentId = this.parent.uniqueId;
this.parent._serializeAsParent(serializationObject);
}

// Inclusion / exclusions
Expand Down Expand Up @@ -692,6 +692,10 @@ export abstract class Light extends Node implements ISortableLight {
light._waitingParentId = parsedLight.parentId;
}

if (parsedLight.parentInstanceIndex !== undefined) {
light._waitingParentInstanceIndex = parsedLight.parentInstanceIndex;
}

// Falloff
if (parsedLight.falloffType !== undefined) {
light.falloffType = parsedLight.falloffType;
Expand Down
41 changes: 33 additions & 8 deletions packages/dev/core/src/Loading/Plugins/babylonFileLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,21 @@ const loadDetailLevels = (scene: Scene, mesh: AbstractMesh) => {
}
};

const findParent = (parentId: any, scene: Scene) => {
const findParent = (parentId: any, parentInstanceIndex: any, scene: Scene) => {
if (typeof parentId !== "number") {
return scene.getLastEntryById(parentId);
const parentEntry = scene.getLastEntryById(parentId);
if (parentEntry && (parentInstanceIndex !== undefined && parentInstanceIndex !== null)) {
const instance = (parentEntry as Mesh).instances[parseInt(parentInstanceIndex)];
return instance;
}
return parentEntry;
}

const parent = tempIndexContainer[parentId];
if (parent && (parentInstanceIndex !== undefined && parentInstanceIndex !== null)) {
const instance = (parent as Mesh).instances[parseInt(parentInstanceIndex)];
return instance;
}

return parent;
};
Expand Down Expand Up @@ -422,32 +431,36 @@ const loadAssetContainer = (scene: Scene, data: string, rootUrl: string, onError
for (index = 0, cache = scene.cameras.length; index < cache; index++) {
const camera = scene.cameras[index];
if (camera._waitingParentId !== null) {
camera.parent = findParent(camera._waitingParentId, scene);
camera.parent = findParent(camera._waitingParentId, camera._waitingParentInstanceIndex, scene);
camera._waitingParentId = null;
camera._waitingParentInstanceIndex = null;
}
}

for (index = 0, cache = scene.lights.length; index < cache; index++) {
const light = scene.lights[index];
if (light && light._waitingParentId !== null) {
light.parent = findParent(light._waitingParentId, scene);
light.parent = findParent(light._waitingParentId, light._waitingParentInstanceIndex, scene);
light._waitingParentId = null;
light._waitingParentInstanceIndex = null;
}
}

// Connect parents & children and parse actions and lods
for (index = 0, cache = scene.transformNodes.length; index < cache; index++) {
const transformNode = scene.transformNodes[index];
if (transformNode._waitingParentId !== null) {
transformNode.parent = findParent(transformNode._waitingParentId, scene);
transformNode.parent = findParent(transformNode._waitingParentId, transformNode._waitingParentInstanceIndex, scene);
transformNode._waitingParentId = null;
transformNode._waitingParentInstanceIndex = null;
}
}
for (index = 0, cache = scene.meshes.length; index < cache; index++) {
const mesh = scene.meshes[index];
if (mesh._waitingParentId !== null) {
mesh.parent = findParent(mesh._waitingParentId, scene);
mesh.parent = findParent(mesh._waitingParentId, mesh._waitingParentInstanceIndex, scene);
mesh._waitingParentId = null;
mesh._waitingParentInstanceIndex = null;
}
if (mesh._waitingData.lods) {
loadDetailLevels(scene, mesh);
Expand Down Expand Up @@ -776,15 +789,27 @@ SceneLoader.RegisterPlugin({
for (let index = 0, cache = scene.transformNodes.length; index < cache; index++) {
const transformNode = scene.transformNodes[index];
if (transformNode._waitingParentId !== null) {
transformNode.parent = scene.getLastEntryById(transformNode._waitingParentId);
const parent = scene.getLastEntryById(transformNode._waitingParentId);
let parentNode = parent;
if (transformNode._waitingParentInstanceIndex) {
parentNode = (parent as Mesh).instances[parseInt(transformNode._waitingParentInstanceIndex)];
transformNode._waitingParentInstanceIndex = null;
}
transformNode.parent = parentNode;
transformNode._waitingParentId = null;
}
}
let currentMesh: AbstractMesh;
for (let index = 0, cache = scene.meshes.length; index < cache; index++) {
currentMesh = scene.meshes[index];
if (currentMesh._waitingParentId) {
currentMesh.parent = scene.getLastEntryById(currentMesh._waitingParentId);
const parent = scene.getLastEntryById(currentMesh._waitingParentId);
let parentNode = parent;
if (currentMesh._waitingParentInstanceIndex) {
parentNode = (parent as Mesh).instances[parseInt(currentMesh._waitingParentInstanceIndex)];
currentMesh._waitingParentInstanceIndex = null;
}
currentMesh.parent = parentNode;
if (currentMesh.parent?.getClassName() === "TransformNode") {
const loadedTransformNodeIndex = loadedTransformNodes.indexOf(currentMesh.parent as TransformNode);
if (loadedTransformNodeIndex > -1) {
Expand Down
11 changes: 11 additions & 0 deletions packages/dev/core/src/Meshes/instancedMesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,17 @@ export class InstancedMesh extends AbstractMesh {
this._sourceMesh.removeInstance(this);
super.dispose(doNotRecurse, disposeMaterialAndTextures);
}

/**
* @param serializationObject
* @hidden
*/
public _serializeAsParent(serializationObject: any) {
super._serializeAsParent(serializationObject);

serializationObject.parentId = this._sourceMesh.uniqueId;
serializationObject.parentInstanceIndex = this._indexInSourceMeshInstanceArray;
}
}

declare module "./mesh" {
Expand Down
12 changes: 10 additions & 2 deletions packages/dev/core/src/Meshes/mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3572,7 +3572,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {

// Parent
if (this.parent) {
serializationObject.parentId = this.parent.uniqueId;
this.parent._serializeAsParent(serializationObject);
}

// Geometry
Expand Down Expand Up @@ -3657,7 +3657,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
};

if (instance.parent) {
serializationInstance.parentId = instance.parent.uniqueId;
instance.parent._serializeAsParent(serializationInstance);
}

if (instance.rotationQuaternion) {
Expand Down Expand Up @@ -3930,6 +3930,10 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
mesh._waitingParentId = parsedMesh.parentId;
}

if (parsedMesh.parentInstanceIndex !== undefined) {
mesh._waitingParentInstanceIndex = parsedMesh.parentInstanceIndex;
}

// Actions
if (parsedMesh.actions !== undefined) {
mesh._waitingData.actions = parsedMesh.actions;
Expand Down Expand Up @@ -4092,6 +4096,10 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
instance._waitingParentId = parsedInstance.parentId;
}

if (parsedInstance.parentInstanceIndex !== undefined) {
instance._waitingParentInstanceIndex = parsedInstance.parentInstanceIndex;
}

if (parsedInstance.isEnabled !== undefined && parsedInstance.isEnabled !== null) {
instance.setEnabled(parsedInstance.isEnabled);
}
Expand Down
11 changes: 5 additions & 6 deletions packages/dev/core/src/Meshes/transformNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1364,18 +1364,13 @@ export class TransformNode extends Node {

// Parent
if (this.parent) {
serializationObject.parentId = this.parent.uniqueId;
this.parent._serializeAsParent(serializationObject);
}

serializationObject.localMatrix = this.getPivotMatrix().asArray();

serializationObject.isEnabled = this.isEnabled();

// Parent
if (this.parent) {
serializationObject.parentId = this.parent.uniqueId;
}

return serializationObject;
}

Expand Down Expand Up @@ -1403,6 +1398,10 @@ export class TransformNode extends Node {
transformNode._waitingParentId = parsedTransformNode.parentId;
}

if (parsedTransformNode.parentInstanceIndex !== undefined) {
transformNode._waitingParentInstanceIndex = parsedTransformNode.parentInstanceIndex;
}

return transformNode;
}

Expand Down
10 changes: 10 additions & 0 deletions packages/dev/core/src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ export class Node implements IBehaviorAware<Node> {
/** @hidden */
public _waitingParentId: Nullable<string> = null;
/** @hidden */
public _waitingParentInstanceIndex: Nullable<string> = null;
/** @hidden */
public _scene: Scene;
/** @hidden */
public _cache: any = {};
Expand Down Expand Up @@ -237,6 +239,14 @@ export class Node implements IBehaviorAware<Node> {
return this._parentNode;
}

/**
* @param serializationObject
* @hidden
*/
public _serializeAsParent(serializationObject: any): void {
serializationObject.parentId = this.uniqueId;
}

/** @hidden */
public _addToSceneRootNodes() {
if (this._nodeDataStorage._sceneRootNodesIndex === -1) {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/tools/tests/test/visualization/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1426,6 +1426,11 @@
"title": "Material Plugin",
"playgroundId": "#22HT5Z#10",
"referenceImage": "materialPlugin.png"
},
{
"title": "Serialize and Load Instanced Hierarchy",
"playgroundId": "#3ZQ1SL#7",
"referenceImage": "serializeAndLoadInstancedHierarchy.png"
}
]
}