@combeenation/3d-viewer 12.0.0-alpha1 → 12.0.0-alpha2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib-cjs/api/manager/gltfExportManager.d.ts +1 -1
- package/dist/lib-cjs/api/manager/gltfExportManager.js +17 -13
- package/dist/lib-cjs/api/manager/gltfExportManager.js.map +1 -1
- package/dist/lib-cjs/api/util/geometryHelper.d.ts +1 -1
- package/dist/lib-cjs/api/util/geometryHelper.js +11 -7
- package/dist/lib-cjs/api/util/geometryHelper.js.map +1 -1
- package/dist/lib-cjs/buildinfo.json +1 -1
- package/dist/lib-cjs/commonjs.tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/api/manager/gltfExportManager.ts +21 -17
- package/src/api/util/geometryHelper.ts +17 -7
package/package.json
CHANGED
|
@@ -65,20 +65,23 @@ export class GltfExportManager {
|
|
|
65
65
|
.forEach(material => this._createRefractionMaterialReplacement(material as PBRMaterial));
|
|
66
66
|
|
|
67
67
|
// handle nodes
|
|
68
|
-
this.viewer.scene.rootNodes.forEach(rootNode =>
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
this.viewer.scene.rootNodes.forEach(rootNode => this._prepareNodeForExport(rootNode, null, excluded));
|
|
69
|
+
|
|
70
|
+
// bake transformation of all meshes, so that no negative scalings are left
|
|
71
|
+
// it's important that this is done AFTER instanced meshes have been converted (_prepareNodeForExport)
|
|
72
|
+
this.viewer.scene.meshes
|
|
73
|
+
.filter(mesh => !!mesh.metadata?.[GltfExportManager._METADATA_PROPS.exportNode])
|
|
74
|
+
.forEach(mesh => bakeGeometryOfMesh(mesh as Mesh));
|
|
71
75
|
|
|
72
76
|
// reset transformation of all "TransformNodes", which couldn't be handled by the geometry baking algorithm
|
|
73
77
|
// it's important that this is done AFTER all geometries have been baked
|
|
74
|
-
this.viewer.scene
|
|
75
|
-
.getNodes()
|
|
78
|
+
this.viewer.scene.transformNodes
|
|
76
79
|
.filter(node => !!node.metadata?.[GltfExportManager._METADATA_PROPS.exportNode])
|
|
77
80
|
.forEach(node => resetTransformation(node as TransformNode));
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
protected async _exportPostProcess(): Promise<void> {
|
|
81
|
-
// dispose all nodes and
|
|
84
|
+
// dispose all nodes and materials that have only been created for the export
|
|
82
85
|
this.viewer.scene.rootNodes
|
|
83
86
|
.filter(rootNode => rootNode.metadata?.[GltfExportManager._METADATA_PROPS.deleteAfterExport])
|
|
84
87
|
.forEach(rootNode => rootNode.dispose());
|
|
@@ -95,13 +98,13 @@ export class GltfExportManager {
|
|
|
95
98
|
},
|
|
96
99
|
// keep root node(s)
|
|
97
100
|
// this seems to be important due to the geometry baking and transformation resetting stuff
|
|
98
|
-
// => root node
|
|
101
|
+
// => root node would have no transformation anymore, which seems to be problematic for the import
|
|
99
102
|
removeNoopRootNodes: false,
|
|
100
103
|
};
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
protected _prepareNodeForExport(
|
|
104
|
-
node:
|
|
107
|
+
node: BjsNode,
|
|
105
108
|
clonedParent: Nullable<TransformNode>,
|
|
106
109
|
excluded?: ExcludedGeometryList
|
|
107
110
|
) {
|
|
@@ -109,17 +112,18 @@ export class GltfExportManager {
|
|
|
109
112
|
return;
|
|
110
113
|
}
|
|
111
114
|
|
|
115
|
+
// from here on we only have TransformNodes
|
|
116
|
+
const transformNode = node as TransformNode;
|
|
117
|
+
|
|
112
118
|
// clone original node and create unique name (via uniqueId)
|
|
113
|
-
const newNodeName = `${
|
|
119
|
+
const newNodeName = `${transformNode.name}_${transformNode.uniqueId}`;
|
|
114
120
|
const clonedNode =
|
|
115
|
-
|
|
116
|
-
? createMeshFromInstancedMesh(
|
|
117
|
-
:
|
|
121
|
+
transformNode instanceof InstancedMesh
|
|
122
|
+
? createMeshFromInstancedMesh(transformNode, newNodeName, clonedParent)
|
|
123
|
+
: transformNode.clone(newNodeName, clonedParent, true)!;
|
|
118
124
|
|
|
119
|
-
//
|
|
120
|
-
// also exchange material
|
|
125
|
+
// exchange material
|
|
121
126
|
if (clonedNode instanceof Mesh) {
|
|
122
|
-
bakeGeometryOfMesh(clonedNode);
|
|
123
127
|
const exchangeWithMaterial =
|
|
124
128
|
clonedNode.material?.metadata?.[GltfExportManager._METADATA_PROPS.exchangeMaterialWith];
|
|
125
129
|
if (exchangeWithMaterial) {
|
|
@@ -133,8 +137,8 @@ export class GltfExportManager {
|
|
|
133
137
|
[GltfExportManager._METADATA_PROPS.deleteAfterExport]: true,
|
|
134
138
|
});
|
|
135
139
|
|
|
136
|
-
//
|
|
137
|
-
const childs =
|
|
140
|
+
// handle children
|
|
141
|
+
const childs = transformNode.getChildTransformNodes(true);
|
|
138
142
|
childs.forEach(child => this._prepareNodeForExport(child, clonedNode, excluded));
|
|
139
143
|
}
|
|
140
144
|
|
|
@@ -8,14 +8,24 @@ import type { MorphTarget } from '@babylonjs/core/Morph';
|
|
|
8
8
|
import { MorphTargetManager } from '@babylonjs/core/Morph/morphTargetManager';
|
|
9
9
|
import type { FloatArray } from '@babylonjs/core/types';
|
|
10
10
|
|
|
11
|
-
const createMeshFromInstancedMesh = function (
|
|
11
|
+
const createMeshFromInstancedMesh = function (
|
|
12
|
+
instancedMesh: InstancedMesh,
|
|
13
|
+
newName: string,
|
|
14
|
+
clonedParent: Nullable<TransformNode>
|
|
15
|
+
) {
|
|
12
16
|
// first create a clone of the source mesh
|
|
13
|
-
const newMesh = instancedMesh.sourceMesh.clone(newName,
|
|
14
|
-
// apply the transformation data
|
|
15
|
-
|
|
16
|
-
newMesh.
|
|
17
|
-
newMesh.
|
|
18
|
-
newMesh.scaling = instancedMesh.scaling;
|
|
17
|
+
const newMesh = instancedMesh.sourceMesh.clone(newName, clonedParent, true);
|
|
18
|
+
// apply the transformation data, it's important to create clones of the transformations to not touch the original
|
|
19
|
+
// transformation when applying changes (eg: geometry baking)
|
|
20
|
+
newMesh.position = instancedMesh.position.clone();
|
|
21
|
+
newMesh.rotation = instancedMesh.rotation.clone();
|
|
22
|
+
newMesh.scaling = instancedMesh.scaling.clone();
|
|
23
|
+
|
|
24
|
+
// rotation quaternion is optional
|
|
25
|
+
if (instancedMesh.rotationQuaternion) {
|
|
26
|
+
newMesh.rotationQuaternion = instancedMesh.rotationQuaternion.clone();
|
|
27
|
+
}
|
|
28
|
+
|
|
19
29
|
// also sync the enabled state from the original instanced mesh
|
|
20
30
|
newMesh.setEnabled(instancedMesh.isEnabled(false));
|
|
21
31
|
|