@combeenation/3d-viewer 12.4.1 → 13.0.0
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/buildinfo.json +1 -1
- package/dist/lib-cjs/commonjs.tsconfig.tsbuildinfo +1 -1
- package/dist/lib-cjs/index.d.ts +63 -63
- package/dist/lib-cjs/index.js +81 -114
- package/dist/lib-cjs/index.js.map +1 -1
- package/dist/lib-cjs/internal/cbnCustomBabylonLoaderPlugin.d.ts +10 -0
- package/dist/lib-cjs/internal/cbnCustomBabylonLoaderPlugin.js +124 -0
- package/dist/lib-cjs/internal/cbnCustomBabylonLoaderPlugin.js.map +1 -0
- package/dist/lib-cjs/internal/cloningHelper.d.ts +19 -0
- package/dist/lib-cjs/internal/cloningHelper.js +165 -0
- package/dist/lib-cjs/internal/cloningHelper.js.map +1 -0
- package/dist/lib-cjs/internal/deviceHelper.d.ts +9 -0
- package/dist/lib-cjs/{api/util → internal}/deviceHelper.js +6 -10
- package/dist/lib-cjs/internal/deviceHelper.js.map +1 -0
- package/dist/lib-cjs/internal/geometryHelper.d.ts +21 -0
- package/dist/lib-cjs/{api/util → internal}/geometryHelper.js +57 -24
- package/dist/lib-cjs/internal/geometryHelper.js.map +1 -0
- package/dist/lib-cjs/internal/metadataHelper.d.ts +26 -0
- package/dist/lib-cjs/internal/metadataHelper.js +51 -0
- package/dist/lib-cjs/internal/metadataHelper.js.map +1 -0
- package/dist/lib-cjs/internal/paintableHelper.d.ts +40 -0
- package/dist/lib-cjs/internal/paintableHelper.js +287 -0
- package/dist/lib-cjs/internal/paintableHelper.js.map +1 -0
- package/dist/lib-cjs/internal/tagsHelper.d.ts +12 -0
- package/dist/lib-cjs/internal/tagsHelper.js +38 -0
- package/dist/lib-cjs/internal/tagsHelper.js.map +1 -0
- package/dist/lib-cjs/manager/cameraManager.d.ts +51 -0
- package/dist/lib-cjs/manager/cameraManager.js +154 -0
- package/dist/lib-cjs/manager/cameraManager.js.map +1 -0
- package/dist/lib-cjs/manager/debugManager.d.ts +60 -0
- package/dist/lib-cjs/manager/debugManager.js +218 -0
- package/dist/lib-cjs/manager/debugManager.js.map +1 -0
- package/dist/lib-cjs/manager/eventManager.d.ts +52 -0
- package/dist/lib-cjs/manager/eventManager.js +72 -0
- package/dist/lib-cjs/manager/eventManager.js.map +1 -0
- package/dist/lib-cjs/{api/manager → manager}/gltfExportManager.d.ts +29 -34
- package/dist/lib-cjs/{api/manager → manager}/gltfExportManager.js +99 -120
- package/dist/lib-cjs/manager/gltfExportManager.js.map +1 -0
- package/dist/lib-cjs/manager/materialManager.d.ts +35 -0
- package/dist/lib-cjs/manager/materialManager.js +126 -0
- package/dist/lib-cjs/manager/materialManager.js.map +1 -0
- package/dist/lib-cjs/manager/modelManager.d.ts +145 -0
- package/dist/lib-cjs/manager/modelManager.js +381 -0
- package/dist/lib-cjs/manager/modelManager.js.map +1 -0
- package/dist/lib-cjs/manager/parameterManager.d.ts +210 -0
- package/dist/lib-cjs/manager/parameterManager.js +515 -0
- package/dist/lib-cjs/manager/parameterManager.js.map +1 -0
- package/dist/lib-cjs/manager/sceneManager.d.ts +45 -0
- package/dist/lib-cjs/manager/sceneManager.js +65 -0
- package/dist/lib-cjs/manager/sceneManager.js.map +1 -0
- package/dist/lib-cjs/manager/screenshotManager.d.ts +36 -0
- package/dist/lib-cjs/manager/screenshotManager.js +40 -0
- package/dist/lib-cjs/manager/screenshotManager.js.map +1 -0
- package/dist/lib-cjs/manager/textureManager.d.ts +12 -0
- package/dist/lib-cjs/manager/textureManager.js +44 -0
- package/dist/lib-cjs/manager/textureManager.js.map +1 -0
- package/dist/lib-cjs/viewer.d.ts +117 -0
- package/dist/lib-cjs/viewer.js +222 -0
- package/dist/lib-cjs/viewer.js.map +1 -0
- package/dist/lib-cjs/{api/classes/viewerError.d.ts → viewerError.d.ts} +6 -1
- package/dist/lib-cjs/{api/classes/viewerError.js → viewerError.js} +6 -1
- package/dist/lib-cjs/viewerError.js.map +1 -0
- package/package.json +10 -11
- package/src/dev.ts +14 -37
- package/src/{types.d.ts → globalTypes.d.ts} +8 -18
- package/src/index.ts +79 -113
- package/src/internal/cbnCustomBabylonLoaderPlugin.ts +149 -0
- package/src/internal/cloningHelper.ts +225 -0
- package/src/internal/deviceHelper.ts +25 -0
- package/src/{api/util → internal}/geometryHelper.ts +63 -24
- package/src/internal/metadataHelper.ts +63 -0
- package/src/internal/paintableHelper.ts +310 -0
- package/src/internal/tagsHelper.ts +41 -0
- package/src/manager/cameraManager.ts +236 -0
- package/src/manager/debugManager.ts +245 -0
- package/src/manager/eventManager.ts +72 -0
- package/src/{api/manager → manager}/gltfExportManager.ts +132 -125
- package/src/manager/materialManager.ts +135 -0
- package/src/manager/modelManager.ts +456 -0
- package/src/manager/parameterManager.ts +652 -0
- package/src/manager/sceneManager.ts +101 -0
- package/src/manager/screenshotManager.ts +59 -0
- package/src/manager/textureManager.ts +32 -0
- package/src/viewer.ts +296 -0
- package/src/{api/classes/viewerError.ts → viewerError.ts} +6 -1
- package/dist/lib-cjs/api/classes/animationInterface.d.ts +0 -8
- package/dist/lib-cjs/api/classes/animationInterface.js +0 -3
- package/dist/lib-cjs/api/classes/animationInterface.js.map +0 -1
- package/dist/lib-cjs/api/classes/dottedPath.d.ts +0 -79
- package/dist/lib-cjs/api/classes/dottedPath.js +0 -167
- package/dist/lib-cjs/api/classes/dottedPath.js.map +0 -1
- package/dist/lib-cjs/api/classes/element.d.ts +0 -153
- package/dist/lib-cjs/api/classes/element.js +0 -703
- package/dist/lib-cjs/api/classes/element.js.map +0 -1
- package/dist/lib-cjs/api/classes/event.d.ts +0 -401
- package/dist/lib-cjs/api/classes/event.js +0 -425
- package/dist/lib-cjs/api/classes/event.js.map +0 -1
- package/dist/lib-cjs/api/classes/eventBroadcaster.d.ts +0 -26
- package/dist/lib-cjs/api/classes/eventBroadcaster.js +0 -50
- package/dist/lib-cjs/api/classes/eventBroadcaster.js.map +0 -1
- package/dist/lib-cjs/api/classes/fuzzyMap.d.ts +0 -7
- package/dist/lib-cjs/api/classes/fuzzyMap.js +0 -22
- package/dist/lib-cjs/api/classes/fuzzyMap.js.map +0 -1
- package/dist/lib-cjs/api/classes/parameter.d.ts +0 -410
- package/dist/lib-cjs/api/classes/parameter.js +0 -643
- package/dist/lib-cjs/api/classes/parameter.js.map +0 -1
- package/dist/lib-cjs/api/classes/parameterObservable.d.ts +0 -36
- package/dist/lib-cjs/api/classes/parameterObservable.js +0 -73
- package/dist/lib-cjs/api/classes/parameterObservable.js.map +0 -1
- package/dist/lib-cjs/api/classes/parameterizable.d.ts +0 -15
- package/dist/lib-cjs/api/classes/parameterizable.js +0 -103
- package/dist/lib-cjs/api/classes/parameterizable.js.map +0 -1
- package/dist/lib-cjs/api/classes/placementAnimation.d.ts +0 -45
- package/dist/lib-cjs/api/classes/placementAnimation.js +0 -177
- package/dist/lib-cjs/api/classes/placementAnimation.js.map +0 -1
- package/dist/lib-cjs/api/classes/variant.d.ts +0 -261
- package/dist/lib-cjs/api/classes/variant.js +0 -873
- package/dist/lib-cjs/api/classes/variant.js.map +0 -1
- package/dist/lib-cjs/api/classes/variantInstance.d.ts +0 -53
- package/dist/lib-cjs/api/classes/variantInstance.js +0 -126
- package/dist/lib-cjs/api/classes/variantInstance.js.map +0 -1
- package/dist/lib-cjs/api/classes/variantParameterizable.d.ts +0 -17
- package/dist/lib-cjs/api/classes/variantParameterizable.js +0 -87
- package/dist/lib-cjs/api/classes/variantParameterizable.js.map +0 -1
- package/dist/lib-cjs/api/classes/viewer.d.ts +0 -215
- package/dist/lib-cjs/api/classes/viewer.js +0 -709
- package/dist/lib-cjs/api/classes/viewer.js.map +0 -1
- package/dist/lib-cjs/api/classes/viewerError.js.map +0 -1
- package/dist/lib-cjs/api/classes/viewerLight.d.ts +0 -66
- package/dist/lib-cjs/api/classes/viewerLight.js +0 -345
- package/dist/lib-cjs/api/classes/viewerLight.js.map +0 -1
- package/dist/lib-cjs/api/internal/lensRendering.d.ts +0 -8
- package/dist/lib-cjs/api/internal/lensRendering.js +0 -12
- package/dist/lib-cjs/api/internal/lensRendering.js.map +0 -1
- package/dist/lib-cjs/api/internal/sceneSetup.d.ts +0 -13
- package/dist/lib-cjs/api/internal/sceneSetup.js +0 -228
- package/dist/lib-cjs/api/internal/sceneSetup.js.map +0 -1
- package/dist/lib-cjs/api/manager/animationManager.d.ts +0 -30
- package/dist/lib-cjs/api/manager/animationManager.js +0 -127
- package/dist/lib-cjs/api/manager/animationManager.js.map +0 -1
- package/dist/lib-cjs/api/manager/gltfExportManager.js.map +0 -1
- package/dist/lib-cjs/api/manager/sceneManager.d.ts +0 -33
- package/dist/lib-cjs/api/manager/sceneManager.js +0 -129
- package/dist/lib-cjs/api/manager/sceneManager.js.map +0 -1
- package/dist/lib-cjs/api/manager/tagManager.d.ts +0 -118
- package/dist/lib-cjs/api/manager/tagManager.js +0 -531
- package/dist/lib-cjs/api/manager/tagManager.js.map +0 -1
- package/dist/lib-cjs/api/manager/textureLoadManager.d.ts +0 -22
- package/dist/lib-cjs/api/manager/textureLoadManager.js +0 -108
- package/dist/lib-cjs/api/manager/textureLoadManager.js.map +0 -1
- package/dist/lib-cjs/api/manager/variantInstanceManager.d.ts +0 -106
- package/dist/lib-cjs/api/manager/variantInstanceManager.js +0 -291
- package/dist/lib-cjs/api/manager/variantInstanceManager.js.map +0 -1
- package/dist/lib-cjs/api/store/specStorage.d.ts +0 -32
- package/dist/lib-cjs/api/store/specStorage.js +0 -66
- package/dist/lib-cjs/api/store/specStorage.js.map +0 -1
- package/dist/lib-cjs/api/util/babylonHelper.d.ts +0 -238
- package/dist/lib-cjs/api/util/babylonHelper.js +0 -826
- package/dist/lib-cjs/api/util/babylonHelper.js.map +0 -1
- package/dist/lib-cjs/api/util/debugHelper.d.ts +0 -9
- package/dist/lib-cjs/api/util/debugHelper.js +0 -94
- package/dist/lib-cjs/api/util/debugHelper.js.map +0 -1
- package/dist/lib-cjs/api/util/deviceHelper.d.ts +0 -9
- package/dist/lib-cjs/api/util/deviceHelper.js.map +0 -1
- package/dist/lib-cjs/api/util/geometryHelper.d.ts +0 -17
- package/dist/lib-cjs/api/util/geometryHelper.js.map +0 -1
- package/dist/lib-cjs/api/util/globalTypes.d.ts +0 -490
- package/dist/lib-cjs/api/util/globalTypes.js +0 -2
- package/dist/lib-cjs/api/util/globalTypes.js.map +0 -1
- package/dist/lib-cjs/api/util/resourceHelper.d.ts +0 -58
- package/dist/lib-cjs/api/util/resourceHelper.js +0 -215
- package/dist/lib-cjs/api/util/resourceHelper.js.map +0 -1
- package/dist/lib-cjs/api/util/sceneLoaderHelper.d.ts +0 -58
- package/dist/lib-cjs/api/util/sceneLoaderHelper.js +0 -229
- package/dist/lib-cjs/api/util/sceneLoaderHelper.js.map +0 -1
- package/dist/lib-cjs/api/util/stringHelper.d.ts +0 -13
- package/dist/lib-cjs/api/util/stringHelper.js +0 -33
- package/dist/lib-cjs/api/util/stringHelper.js.map +0 -1
- package/dist/lib-cjs/api/util/structureHelper.d.ts +0 -9
- package/dist/lib-cjs/api/util/structureHelper.js +0 -58
- package/dist/lib-cjs/api/util/structureHelper.js.map +0 -1
- package/src/api/classes/animationInterface.ts +0 -10
- package/src/api/classes/dottedPath.ts +0 -181
- package/src/api/classes/element.ts +0 -766
- package/src/api/classes/event.ts +0 -457
- package/src/api/classes/eventBroadcaster.ts +0 -52
- package/src/api/classes/fuzzyMap.ts +0 -21
- package/src/api/classes/parameter.ts +0 -686
- package/src/api/classes/parameterObservable.ts +0 -73
- package/src/api/classes/parameterizable.ts +0 -87
- package/src/api/classes/placementAnimation.ts +0 -162
- package/src/api/classes/variant.ts +0 -965
- package/src/api/classes/variantInstance.ts +0 -123
- package/src/api/classes/variantParameterizable.ts +0 -83
- package/src/api/classes/viewer.ts +0 -751
- package/src/api/classes/viewerLight.ts +0 -335
- package/src/api/internal/debugViewer.ts +0 -90
- package/src/api/internal/lensRendering.ts +0 -9
- package/src/api/internal/sceneSetup.ts +0 -208
- package/src/api/manager/animationManager.ts +0 -143
- package/src/api/manager/sceneManager.ts +0 -134
- package/src/api/manager/tagManager.ts +0 -572
- package/src/api/manager/textureLoadManager.ts +0 -107
- package/src/api/manager/variantInstanceManager.ts +0 -306
- package/src/api/store/specStorage.ts +0 -68
- package/src/api/util/babylonHelper.ts +0 -915
- package/src/api/util/debugHelper.ts +0 -121
- package/src/api/util/deviceHelper.ts +0 -31
- package/src/api/util/globalTypes.ts +0 -566
- package/src/api/util/resourceHelper.ts +0 -201
- package/src/api/util/sceneLoaderHelper.ts +0 -247
- package/src/api/util/stringHelper.ts +0 -30
- package/src/api/util/structureHelper.ts +0 -62
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractMesh,
|
|
3
|
+
AssetContainer,
|
|
4
|
+
InstancedMesh,
|
|
5
|
+
Mesh,
|
|
6
|
+
MorphTargetManager,
|
|
7
|
+
NodeNamingStrategy,
|
|
8
|
+
Scene,
|
|
9
|
+
TagNamingStrategy,
|
|
10
|
+
TransformNode,
|
|
11
|
+
} from '../index';
|
|
12
|
+
import {
|
|
13
|
+
clearInternalMetadataValue,
|
|
14
|
+
cloneInternalMetadata,
|
|
15
|
+
cloneMetadata,
|
|
16
|
+
getInternalMetadataValue,
|
|
17
|
+
setInternalMetadataValue,
|
|
18
|
+
} from './metadataHelper';
|
|
19
|
+
import { cloneTags, getTags, setTags } from './tagsHelper';
|
|
20
|
+
|
|
21
|
+
const _defaultNodeNamingStrategy: NodeNamingStrategy = (node: TransformNode, newModelName: string): string => {
|
|
22
|
+
return `${node.name}.${newModelName}`;
|
|
23
|
+
};
|
|
24
|
+
const _defaultTagNamingStrategy: TagNamingStrategy = (tag: string, newModelName: string): string => {
|
|
25
|
+
// don't rename tags by default
|
|
26
|
+
return tag;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Clones the node hierarchy of the asset container with some special treatment that differs from Babylon.js default
|
|
31
|
+
* cloning behaviour, such as:
|
|
32
|
+
* - create new instances of morph target manager
|
|
33
|
+
* - deep cloning internal metadata
|
|
34
|
+
* - deep cloning metadata and tags for instanced meshes
|
|
35
|
+
* - reassigns source meshes in cloned asset container
|
|
36
|
+
* Furthermore there is the possibility to adjust naming of nodes and tags in the cloned asset container
|
|
37
|
+
*/
|
|
38
|
+
export function cloneModelAssetContainer(
|
|
39
|
+
sourceAssetContainer: AssetContainer,
|
|
40
|
+
newModelName: string,
|
|
41
|
+
renaming: {
|
|
42
|
+
nodeNamingStrategy?: NodeNamingStrategy;
|
|
43
|
+
tagNamingStrategy?: TagNamingStrategy;
|
|
44
|
+
},
|
|
45
|
+
scene: Scene
|
|
46
|
+
): AssetContainer {
|
|
47
|
+
const targetAssetContainer = new AssetContainer(scene);
|
|
48
|
+
|
|
49
|
+
sourceAssetContainer.rootNodes.forEach(node => {
|
|
50
|
+
if (node instanceof TransformNode) {
|
|
51
|
+
// this is the actual node tree cloning procedure
|
|
52
|
+
_cloneNode(node, newModelName, null, targetAssetContainer, {
|
|
53
|
+
nodeNamingStrategy: renaming?.nodeNamingStrategy,
|
|
54
|
+
tagNamingStrategy: renaming?.tagNamingStrategy,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
targetAssetContainer.populateRootNodes();
|
|
60
|
+
targetAssetContainer.rootNodes.forEach(node => {
|
|
61
|
+
if (node instanceof TransformNode) {
|
|
62
|
+
// reassigning instanced meshes can only be done after the model has been fully cloned, as we can't be sure if
|
|
63
|
+
// the source or instanced mesh is handled prior
|
|
64
|
+
_reAssignSourceMesh(node, sourceAssetContainer.meshes, targetAssetContainer.meshes);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// morph target manager is not cloned per default, therefore morph targets would affect original and cloned model at
|
|
69
|
+
// the same time, which we don't want
|
|
70
|
+
sourceAssetContainer.morphTargetManagers.forEach(sourceMTM => {
|
|
71
|
+
cloneMorphTargetManager(sourceMTM, targetAssetContainer);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
_clearCloningMetadata(sourceAssetContainer);
|
|
75
|
+
_clearCloningMetadata(targetAssetContainer);
|
|
76
|
+
|
|
77
|
+
// hide immediately, so that show model code can do it's thing (scene preparation) before finally showing the model
|
|
78
|
+
targetAssetContainer.removeAllFromScene();
|
|
79
|
+
|
|
80
|
+
return targetAssetContainer;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Helper function for cloning a morph target manager and updating all the mesh assignments.
|
|
85
|
+
* Meshes need to be already available in the target asset container.
|
|
86
|
+
*/
|
|
87
|
+
export function cloneMorphTargetManager(
|
|
88
|
+
sourceMTM: MorphTargetManager,
|
|
89
|
+
targetAssetContainer: AssetContainer
|
|
90
|
+
): MorphTargetManager {
|
|
91
|
+
const clonedMTM = sourceMTM.clone();
|
|
92
|
+
|
|
93
|
+
clonedMTM._parentContainer = targetAssetContainer;
|
|
94
|
+
targetAssetContainer.morphTargetManagers.push(clonedMTM);
|
|
95
|
+
|
|
96
|
+
targetAssetContainer.meshes.forEach(mesh => {
|
|
97
|
+
if (mesh.morphTargetManager?.uniqueId === sourceMTM.uniqueId) {
|
|
98
|
+
mesh.morphTargetManager = clonedMTM;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return clonedMTM;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The actual geometry cloning function.
|
|
107
|
+
* Calls "clone" function of dedicated Node type and recourses into children to clone the whole node tree.
|
|
108
|
+
* Adds temporary metadata for special treatment of certain node types (e.g. InstancedMesh).
|
|
109
|
+
*/
|
|
110
|
+
function _cloneNode(
|
|
111
|
+
node: TransformNode,
|
|
112
|
+
newModelName: string,
|
|
113
|
+
newParent: TransformNode | null,
|
|
114
|
+
assetContainer: AssetContainer,
|
|
115
|
+
renaming: {
|
|
116
|
+
nodeNamingStrategy?: NodeNamingStrategy;
|
|
117
|
+
tagNamingStrategy?: TagNamingStrategy;
|
|
118
|
+
}
|
|
119
|
+
): void {
|
|
120
|
+
const nodeNamingStrategy = renaming.nodeNamingStrategy ?? _defaultNodeNamingStrategy;
|
|
121
|
+
const tagNamingStrategy = renaming.tagNamingStrategy ?? _defaultTagNamingStrategy;
|
|
122
|
+
|
|
123
|
+
const cloneName = nodeNamingStrategy(node, newModelName);
|
|
124
|
+
const clone = node.clone(cloneName, newParent, true);
|
|
125
|
+
if (!clone) {
|
|
126
|
+
throw new Error(`Cloning node "${node.name}" failed`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
clone.id = cloneName;
|
|
130
|
+
// create a deep clone for internal metadata, as the default clone function uses the same assignment of the sources
|
|
131
|
+
// internal metadata
|
|
132
|
+
cloneInternalMetadata(node, clone);
|
|
133
|
+
// ATM the assignment from clone to source is needed for reassigning instanced meshes after cloning
|
|
134
|
+
// may be usefull for other node types in the future as well
|
|
135
|
+
setInternalMetadataValue(clone, 'cloneSource', node.uniqueId);
|
|
136
|
+
setInternalMetadataValue(node, 'cloneTarget', clone.uniqueId);
|
|
137
|
+
|
|
138
|
+
if (node instanceof InstancedMesh) {
|
|
139
|
+
_cloneInstancedMeshData(node, clone as InstancedMesh);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const sourceTags = getTags(node);
|
|
143
|
+
const mappedTags = sourceTags.map(tag => tagNamingStrategy(tag, newModelName));
|
|
144
|
+
setTags(clone, mappedTags);
|
|
145
|
+
|
|
146
|
+
clone._parentContainer = assetContainer;
|
|
147
|
+
// TODO WTT: create global helper function for distinguishing between transform nodes and meshes
|
|
148
|
+
if (clone instanceof AbstractMesh) {
|
|
149
|
+
assetContainer.meshes.push(clone);
|
|
150
|
+
} else {
|
|
151
|
+
assetContainer.transformNodes.push(clone);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const children = node.getChildTransformNodes(true);
|
|
155
|
+
children.forEach(child => _cloneNode(child, newModelName, clone, assetContainer, renaming));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Cloned instanced meshes are having the same source mesh as their cloning source.
|
|
160
|
+
* However we want the cloned source mesh to be the actual source.
|
|
161
|
+
* Exchanging and reassigning is done within this function.
|
|
162
|
+
* Operates on the given `node` and all its children recursively.
|
|
163
|
+
*/
|
|
164
|
+
function _reAssignSourceMesh(node: TransformNode, sourceMeshes: AbstractMesh[], clonedMeshes: AbstractMesh[]): void {
|
|
165
|
+
if (node instanceof InstancedMesh) {
|
|
166
|
+
// find the cloned instance and source mesh
|
|
167
|
+
const clonedInstance = node;
|
|
168
|
+
const originalInstance = _findByUniqueId(
|
|
169
|
+
sourceMeshes,
|
|
170
|
+
getInternalMetadataValue(clonedInstance, 'cloneSource') as number
|
|
171
|
+
);
|
|
172
|
+
if (originalInstance instanceof InstancedMesh) {
|
|
173
|
+
const originalSource = originalInstance.sourceMesh;
|
|
174
|
+
const clonedSource = _findByUniqueId(
|
|
175
|
+
clonedMeshes,
|
|
176
|
+
getInternalMetadataValue(originalSource, 'cloneTarget') as number
|
|
177
|
+
);
|
|
178
|
+
if (clonedSource instanceof Mesh) {
|
|
179
|
+
// it's not possible to just exchange the source mesh => readonly property
|
|
180
|
+
// we have to create a new clone with the correct source mesh
|
|
181
|
+
const exchangedInstance = clonedInstance.clone(clonedInstance.name, clonedInstance.parent, true, clonedSource);
|
|
182
|
+
clonedInstance._parentContainer!.meshes.push(exchangedInstance);
|
|
183
|
+
|
|
184
|
+
_cloneInstancedMeshData(clonedInstance, exchangedInstance);
|
|
185
|
+
|
|
186
|
+
// re-reference the childs of the cloned instance as well
|
|
187
|
+
const childs = clonedInstance.getChildTransformNodes(true);
|
|
188
|
+
childs.forEach(child => (child.parent = exchangedInstance));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// old instance mesh is not needed anymore and can be disposed
|
|
193
|
+
clonedInstance.dispose();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// recurse into childs
|
|
197
|
+
const children = node.getChildTransformNodes(true);
|
|
198
|
+
children.forEach(child => _reAssignSourceMesh(child, sourceMeshes, clonedMeshes));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Removes metadata entries "cloneSource" and "cloneTarget" from all meshes and transform nodes inside the asset
|
|
203
|
+
* container
|
|
204
|
+
*/
|
|
205
|
+
function _clearCloningMetadata(assetContainer: AssetContainer): void {
|
|
206
|
+
[...assetContainer.meshes, ...assetContainer.transformNodes].forEach(node => {
|
|
207
|
+
clearInternalMetadataValue(node, 'cloneSource');
|
|
208
|
+
clearInternalMetadataValue(node, 'cloneTarget');
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* "InstancedMesh.clone" function doesn't clone tags and metadata, also the enabled state doesn't seem to be cloned
|
|
214
|
+
* correctly.
|
|
215
|
+
* This function adjusts the behaviour to fulfill our expectations.
|
|
216
|
+
*/
|
|
217
|
+
function _cloneInstancedMeshData(sourceInstancedMesh: InstancedMesh, targetInstancedMesh: InstancedMesh): void {
|
|
218
|
+
targetInstancedMesh.setEnabled(sourceInstancedMesh.isEnabled(false));
|
|
219
|
+
cloneMetadata(sourceInstancedMesh, targetInstancedMesh);
|
|
220
|
+
cloneTags(sourceInstancedMesh, targetInstancedMesh);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function _findByUniqueId(nodes: TransformNode[], uniqueId: number): TransformNode | undefined {
|
|
224
|
+
return nodes.find(node => node.uniqueId === uniqueId);
|
|
225
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { LimitTextureSizeConfig } from '../index';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Checks if the current device is an iPhone
|
|
5
|
+
*/
|
|
6
|
+
export function getIsIPhone(): boolean {
|
|
7
|
+
const isIPhone = /iPhone/.test(navigator.userAgent);
|
|
8
|
+
|
|
9
|
+
return isIPhone;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Checks if the current device is "scaled down", as defined in the Spec
|
|
14
|
+
*/
|
|
15
|
+
export function getIsScaledDownDevice(limitTextureSize: LimitTextureSizeConfig | false): boolean {
|
|
16
|
+
if (!limitTextureSize) {
|
|
17
|
+
// no down scaling defined
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// check device
|
|
22
|
+
const deviceFits = limitTextureSize.devices === 'all' || (limitTextureSize.devices === 'iPhone' && getIsIPhone());
|
|
23
|
+
|
|
24
|
+
return deviceFits;
|
|
25
|
+
}
|
|
@@ -1,23 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import {
|
|
2
|
+
ExcludedGeometry,
|
|
3
|
+
ExcludedGeometryList,
|
|
4
|
+
FloatArray,
|
|
5
|
+
Geometry,
|
|
6
|
+
InstancedMesh,
|
|
7
|
+
Mesh,
|
|
8
|
+
MorphTarget,
|
|
9
|
+
MorphTargetManager,
|
|
10
|
+
ParameterSubject,
|
|
11
|
+
TransformNode,
|
|
12
|
+
Vector3,
|
|
13
|
+
VertexBuffer,
|
|
14
|
+
} from '../index';
|
|
15
|
+
import { cloneInternalMetadata } from './metadataHelper';
|
|
16
|
+
import { hasTag } from './tagsHelper';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Find out if a node is part of a list of excluded geometry
|
|
20
|
+
* @param node BJS node
|
|
21
|
+
* @param list list of excluded geometry
|
|
22
|
+
* @returns boolean based on whether node (or one of its parents) was found in list
|
|
23
|
+
*/
|
|
24
|
+
export function isNodeExcluded(nodeToCheck: TransformNode, list: ExcludedGeometryList): boolean {
|
|
25
|
+
// CAUTION: node has to be the same instance
|
|
26
|
+
const checkNode = (excludedNode: TransformNode): boolean => excludedNode === nodeToCheck;
|
|
27
|
+
const checkTagManagerSubject = (excludedSubject: ParameterSubject): boolean => {
|
|
28
|
+
const nameMatches = !!excludedSubject.nodeName && excludedSubject.nodeName === nodeToCheck.name;
|
|
29
|
+
const tagMatches = !!excludedSubject.tagName && hasTag(nodeToCheck, excludedSubject.tagName);
|
|
30
|
+
return nameMatches || tagMatches;
|
|
31
|
+
};
|
|
32
|
+
const check = (geometryToExclude: ExcludedGeometry): boolean => {
|
|
33
|
+
if (geometryToExclude instanceof TransformNode) {
|
|
34
|
+
return checkNode(geometryToExclude);
|
|
35
|
+
}
|
|
36
|
+
if ((geometryToExclude as ParameterSubject).tagName || (geometryToExclude as ParameterSubject).nodeName) {
|
|
37
|
+
return checkTagManagerSubject(geometryToExclude as ParameterSubject);
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
let isExcluded = list.some(geometryToExclude => check(geometryToExclude));
|
|
43
|
+
// consider parent as well
|
|
44
|
+
if (!isExcluded && nodeToCheck.parent instanceof TransformNode) {
|
|
45
|
+
isExcluded = isNodeExcluded(nodeToCheck.parent, list);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return isExcluded;
|
|
49
|
+
}
|
|
10
50
|
|
|
11
51
|
/**
|
|
12
52
|
* Creates a "standard" mesh from an instanced mesh, by cloning the source mesh and applying transformation data
|
|
13
53
|
*/
|
|
14
|
-
|
|
54
|
+
export function createMeshFromInstancedMesh(
|
|
15
55
|
instancedMesh: InstancedMesh,
|
|
16
56
|
newName: string,
|
|
17
|
-
clonedParent:
|
|
18
|
-
) {
|
|
57
|
+
clonedParent: TransformNode
|
|
58
|
+
): Mesh {
|
|
19
59
|
// first create a clone of the source mesh
|
|
20
60
|
const newMesh = instancedMesh.sourceMesh.clone(newName, clonedParent, true);
|
|
61
|
+
cloneInternalMetadata(instancedMesh.sourceMesh, newMesh);
|
|
21
62
|
// apply the transformation data, it's important to create clones of the transformations to not touch the original
|
|
22
63
|
// transformation when applying changes (eg: geometry baking)
|
|
23
64
|
newMesh.position = instancedMesh.position.clone();
|
|
@@ -33,13 +74,13 @@ const createMeshFromInstancedMesh = function (
|
|
|
33
74
|
newMesh.setEnabled(instancedMesh.isEnabled(false));
|
|
34
75
|
|
|
35
76
|
return newMesh;
|
|
36
|
-
}
|
|
77
|
+
}
|
|
37
78
|
|
|
38
79
|
/**
|
|
39
80
|
* Removes transformation data from the mesh and stores it in the geometry, which is called "baking".
|
|
40
81
|
* Also considers the geometry change from morph targets.
|
|
41
82
|
*/
|
|
42
|
-
|
|
83
|
+
export function bakeGeometryOfMesh(mesh: Mesh): void {
|
|
43
84
|
if (!mesh.geometry) {
|
|
44
85
|
// no geometry available, nothing to do
|
|
45
86
|
return;
|
|
@@ -79,27 +120,27 @@ const bakeGeometryOfMesh = function (mesh: Mesh) {
|
|
|
79
120
|
|
|
80
121
|
// bake the transformation data in the mesh geometry, fortunately there is already a help function from Babylon.js
|
|
81
122
|
mesh.bakeCurrentTransformIntoVertices();
|
|
82
|
-
}
|
|
123
|
+
}
|
|
83
124
|
|
|
84
125
|
/**
|
|
85
126
|
* Resets transformation to initial state
|
|
86
127
|
*/
|
|
87
|
-
|
|
128
|
+
export function resetTransformation(node: TransformNode): void {
|
|
88
129
|
node.position = new Vector3(0, 0, 0);
|
|
89
130
|
node.rotation = new Vector3(0, 0, 0);
|
|
90
131
|
node.rotationQuaternion = null;
|
|
91
132
|
node.scaling = new Vector3(1, 1, 1);
|
|
92
|
-
}
|
|
133
|
+
}
|
|
93
134
|
|
|
94
135
|
/**
|
|
95
136
|
* @param kind morph targets can affect various vertices kinds, whereas "position" is the most common one
|
|
96
137
|
* still other kinds (like normals or tangents) can be affected as well and can be provided on this input
|
|
97
138
|
*/
|
|
98
|
-
|
|
139
|
+
function _bakeMorphTargetManagerIntoVertices(
|
|
99
140
|
kind: string,
|
|
100
141
|
morphTargetManager: MorphTargetManager,
|
|
101
142
|
geometry: Geometry
|
|
102
|
-
) {
|
|
143
|
+
): void {
|
|
103
144
|
const origVerticesData = geometry.getVerticesData(kind);
|
|
104
145
|
if (!origVerticesData) {
|
|
105
146
|
// no vertices data for this kind availabe on the mesh geometry
|
|
@@ -122,9 +163,9 @@ const _bakeMorphTargetManagerIntoVertices = function (
|
|
|
122
163
|
|
|
123
164
|
// apply the updated vertices data
|
|
124
165
|
geometry.setVerticesData(kind, verticesData);
|
|
125
|
-
}
|
|
166
|
+
}
|
|
126
167
|
|
|
127
|
-
|
|
168
|
+
function _getVerticesDataFromMorphTarget(kind: string, morphTarget: MorphTarget): FloatArray | null {
|
|
128
169
|
switch (kind) {
|
|
129
170
|
case VertexBuffer.PositionKind:
|
|
130
171
|
return morphTarget.getPositions();
|
|
@@ -137,6 +178,4 @@ const _getVerticesDataFromMorphTarget = function (kind: string, morphTarget: Mor
|
|
|
137
178
|
}
|
|
138
179
|
|
|
139
180
|
return null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export { createMeshFromInstancedMesh, bakeGeometryOfMesh, resetTransformation };
|
|
181
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { BaseTexture, Material, Node } from '../index';
|
|
2
|
+
import { cloneDeep } from 'lodash-es';
|
|
3
|
+
|
|
4
|
+
type MetadataValue = string | number | boolean | undefined;
|
|
5
|
+
type MetadataTarget = Node | Material | BaseTexture;
|
|
6
|
+
type MetadataKeys =
|
|
7
|
+
// CBN babylon loader
|
|
8
|
+
| 'deferredMaterial'
|
|
9
|
+
// material manager
|
|
10
|
+
| 'materialToBeSet'
|
|
11
|
+
// GLTF export
|
|
12
|
+
| 'exportNode'
|
|
13
|
+
| 'deleteAfterExport'
|
|
14
|
+
| 'exchangeMaterialWith'
|
|
15
|
+
// cloning
|
|
16
|
+
| 'cloneSource'
|
|
17
|
+
| 'cloneTarget';
|
|
18
|
+
|
|
19
|
+
// TODO WTT: use generics or some kind of logic that is able to type the metadata according to their key
|
|
20
|
+
/**
|
|
21
|
+
* Sets certain metadata on the objects INTERNAL metadata storage.
|
|
22
|
+
* "object._internalMetadata.cbn" is reserved for CBN specific metadata information.
|
|
23
|
+
* The objects public metadata ("object.metadata") is not affected and should therefore not interfere with metadata
|
|
24
|
+
* that is used in consumer projects.
|
|
25
|
+
*/
|
|
26
|
+
export function setInternalMetadataValue(object: MetadataTarget, key: MetadataKeys, value: MetadataValue): void {
|
|
27
|
+
if (!object._internalMetadata) {
|
|
28
|
+
object._internalMetadata = {};
|
|
29
|
+
}
|
|
30
|
+
if (!object._internalMetadata.cbn) {
|
|
31
|
+
object._internalMetadata.cbn = {};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
object._internalMetadata.cbn[key] = value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function clearInternalMetadataValue(object: MetadataTarget, key: MetadataKeys): void {
|
|
38
|
+
delete object._internalMetadata?.cbn?.[key];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function getInternalMetadataValue(object: MetadataTarget, key: MetadataKeys): MetadataValue {
|
|
42
|
+
return object._internalMetadata?.cbn?.[key];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Creates a deep clone from the source objects internal metadata and assigns it to the target objects metadata.
|
|
47
|
+
* This is required as Babylon.js only creates shallow clones of the internal metadata, which would be problematic for
|
|
48
|
+
* our needs.
|
|
49
|
+
*/
|
|
50
|
+
export function cloneInternalMetadata(sourceObject: MetadataTarget, targetObject: MetadataTarget): void {
|
|
51
|
+
targetObject._internalMetadata = cloneDeep(sourceObject._internalMetadata);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Clones the metadata from one object to another.
|
|
56
|
+
* CAUTION: this is now the public available "object.metadata" object.
|
|
57
|
+
* We need this function internally when cloning instanced meshes.
|
|
58
|
+
*/
|
|
59
|
+
export function cloneMetadata(sourceObject: MetadataTarget, targetObject: MetadataTarget): void {
|
|
60
|
+
const clonedMetadata = cloneDeep(sourceObject.metadata);
|
|
61
|
+
|
|
62
|
+
targetObject.metadata = clonedMetadata;
|
|
63
|
+
}
|