@combeenation/3d-viewer 12.0.0-alpha1 → 12.0.0-alpha3
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 +2 -2
- package/dist/lib-cjs/api/manager/gltfExportManager.js +21 -17
- 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 +29 -23
- package/src/api/util/geometryHelper.ts +17 -7
package/package.json
CHANGED
|
@@ -59,26 +59,31 @@ export class GltfExportManager {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
protected async _exportPreProcess(excluded?: ExcludedGeometryList): Promise<void> {
|
|
62
|
+
this.viewer.pauseRendering();
|
|
63
|
+
|
|
62
64
|
// handle materials
|
|
63
65
|
this.viewer.scene.materials
|
|
64
66
|
.filter(material => this._shouldReplaceMaterial(material))
|
|
65
67
|
.forEach(material => this._createRefractionMaterialReplacement(material as PBRMaterial));
|
|
66
68
|
|
|
67
69
|
// handle nodes
|
|
68
|
-
this.viewer.scene.rootNodes.forEach(rootNode =>
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
this.viewer.scene.rootNodes.forEach(rootNode => this._prepareNodeForExport(rootNode, null, excluded));
|
|
71
|
+
|
|
72
|
+
// bake transformation of all meshes, so that no negative scalings are left
|
|
73
|
+
// it's important that this is done AFTER instanced meshes have been converted (_prepareNodeForExport)
|
|
74
|
+
this.viewer.scene.meshes
|
|
75
|
+
.filter(mesh => !!mesh.metadata?.[GltfExportManager._METADATA_PROPS.exportNode])
|
|
76
|
+
.forEach(mesh => bakeGeometryOfMesh(mesh as Mesh));
|
|
71
77
|
|
|
72
78
|
// reset transformation of all "TransformNodes", which couldn't be handled by the geometry baking algorithm
|
|
73
79
|
// it's important that this is done AFTER all geometries have been baked
|
|
74
|
-
this.viewer.scene
|
|
75
|
-
.getNodes()
|
|
80
|
+
[...this.viewer.scene.transformNodes, ...this.viewer.scene.meshes]
|
|
76
81
|
.filter(node => !!node.metadata?.[GltfExportManager._METADATA_PROPS.exportNode])
|
|
77
82
|
.forEach(node => resetTransformation(node as TransformNode));
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
protected async _exportPostProcess(): Promise<void> {
|
|
81
|
-
// dispose all nodes and
|
|
86
|
+
// dispose all nodes and materials that have only been created for the export
|
|
82
87
|
this.viewer.scene.rootNodes
|
|
83
88
|
.filter(rootNode => rootNode.metadata?.[GltfExportManager._METADATA_PROPS.deleteAfterExport])
|
|
84
89
|
.forEach(rootNode => rootNode.dispose());
|
|
@@ -86,6 +91,8 @@ export class GltfExportManager {
|
|
|
86
91
|
this.viewer.scene.materials
|
|
87
92
|
.filter(mat => !!mat.metadata?.[GltfExportManager._METADATA_PROPS.deleteAfterExport])
|
|
88
93
|
.forEach(material => material.dispose(false, false));
|
|
94
|
+
|
|
95
|
+
this.viewer.resumeRendering();
|
|
89
96
|
}
|
|
90
97
|
|
|
91
98
|
protected _gltfExportOptions(): IExportOptions {
|
|
@@ -95,13 +102,13 @@ export class GltfExportManager {
|
|
|
95
102
|
},
|
|
96
103
|
// keep root node(s)
|
|
97
104
|
// this seems to be important due to the geometry baking and transformation resetting stuff
|
|
98
|
-
// => root node
|
|
105
|
+
// => root node would have no transformation anymore, which seems to be problematic for the import
|
|
99
106
|
removeNoopRootNodes: false,
|
|
100
107
|
};
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
protected _prepareNodeForExport(
|
|
104
|
-
node:
|
|
111
|
+
node: BjsNode,
|
|
105
112
|
clonedParent: Nullable<TransformNode>,
|
|
106
113
|
excluded?: ExcludedGeometryList
|
|
107
114
|
) {
|
|
@@ -109,17 +116,18 @@ export class GltfExportManager {
|
|
|
109
116
|
return;
|
|
110
117
|
}
|
|
111
118
|
|
|
119
|
+
// from here on we only have TransformNodes
|
|
120
|
+
const transformNode = node as TransformNode;
|
|
121
|
+
|
|
112
122
|
// clone original node and create unique name (via uniqueId)
|
|
113
|
-
const newNodeName = `${
|
|
123
|
+
const newNodeName = `${transformNode.name}_${transformNode.uniqueId}`;
|
|
114
124
|
const clonedNode =
|
|
115
|
-
|
|
116
|
-
? createMeshFromInstancedMesh(
|
|
117
|
-
:
|
|
125
|
+
transformNode instanceof InstancedMesh
|
|
126
|
+
? createMeshFromInstancedMesh(transformNode, newNodeName, clonedParent)
|
|
127
|
+
: transformNode.clone(newNodeName, clonedParent, true)!;
|
|
118
128
|
|
|
119
|
-
//
|
|
120
|
-
// also exchange material
|
|
129
|
+
// exchange material
|
|
121
130
|
if (clonedNode instanceof Mesh) {
|
|
122
|
-
bakeGeometryOfMesh(clonedNode);
|
|
123
131
|
const exchangeWithMaterial =
|
|
124
132
|
clonedNode.material?.metadata?.[GltfExportManager._METADATA_PROPS.exchangeMaterialWith];
|
|
125
133
|
if (exchangeWithMaterial) {
|
|
@@ -133,8 +141,8 @@ export class GltfExportManager {
|
|
|
133
141
|
[GltfExportManager._METADATA_PROPS.deleteAfterExport]: true,
|
|
134
142
|
});
|
|
135
143
|
|
|
136
|
-
//
|
|
137
|
-
const childs =
|
|
144
|
+
// handle children
|
|
145
|
+
const childs = transformNode.getChildTransformNodes(true);
|
|
138
146
|
childs.forEach(child => this._prepareNodeForExport(child, clonedNode, excluded));
|
|
139
147
|
}
|
|
140
148
|
|
|
@@ -172,12 +180,12 @@ export class GltfExportManager {
|
|
|
172
180
|
/**
|
|
173
181
|
* Create an export-friendly replacement material for a material using refraction.
|
|
174
182
|
*/
|
|
175
|
-
protected _createRefractionMaterialReplacement(material: PBRMaterial)
|
|
183
|
+
protected _createRefractionMaterialReplacement(material: PBRMaterial) {
|
|
176
184
|
const newName = `${material.name}_clone`;
|
|
177
|
-
|
|
178
|
-
const clonedMaterial = material.clone(newName);
|
|
185
|
+
|
|
186
|
+
const clonedMaterial = material.clone(newName);
|
|
179
187
|
clonedMaterial.refractionTexture = null;
|
|
180
|
-
clonedMaterial.metallicReflectanceTexture = null;
|
|
188
|
+
clonedMaterial.metallicReflectanceTexture = null;
|
|
181
189
|
clonedMaterial.alpha = 0.7;
|
|
182
190
|
clonedMaterial.albedoColor = new Color3(0.3, 0.3, 0.3);
|
|
183
191
|
clonedMaterial.transparencyMode = PBRMaterial.PBRMATERIAL_ALPHABLEND;
|
|
@@ -186,7 +194,5 @@ export class GltfExportManager {
|
|
|
186
194
|
|
|
187
195
|
injectMetadata(material, { [GltfExportManager._METADATA_PROPS.exchangeMaterialWith]: newName });
|
|
188
196
|
injectMetadata(clonedMaterial, { [GltfExportManager._METADATA_PROPS.deleteAfterExport]: true });
|
|
189
|
-
|
|
190
|
-
return clonedMaterial;
|
|
191
197
|
}
|
|
192
198
|
}
|
|
@@ -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
|
|