@combeenation/3d-viewer 21.1.0-beta2 → 22.0.0-beta1
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 +1 -0
- package/dist/lib-cjs/index.js +2 -0
- package/dist/lib-cjs/index.js.map +1 -1
- package/dist/lib-cjs/internal/cbn-custom-babylon-loader-plugin.js +32 -0
- package/dist/lib-cjs/internal/cbn-custom-babylon-loader-plugin.js.map +1 -1
- package/dist/lib-cjs/internal/conversion-helper.d.ts +20 -0
- package/dist/lib-cjs/internal/conversion-helper.js +76 -0
- package/dist/lib-cjs/internal/conversion-helper.js.map +1 -0
- package/dist/lib-cjs/internal/export-helper.js +5 -2
- package/dist/lib-cjs/internal/export-helper.js.map +1 -1
- package/dist/lib-cjs/manager/debug-manager.js +3 -3
- package/dist/lib-cjs/manager/debug-manager.js.map +1 -1
- package/dist/lib-cjs/manager/material-manager.js +2 -0
- package/dist/lib-cjs/manager/material-manager.js.map +1 -1
- package/dist/lib-cjs/manager/model-manager.d.ts +0 -6
- package/dist/lib-cjs/manager/model-manager.js +12 -33
- package/dist/lib-cjs/manager/model-manager.js.map +1 -1
- package/dist/lib-cjs/manager/scene-manager.js +1 -1
- package/dist/lib-cjs/manager/scene-manager.js.map +1 -1
- package/dist/lib-cjs/side-effects.d.ts +1 -0
- package/dist/lib-cjs/side-effects.js +6 -0
- package/dist/lib-cjs/side-effects.js.map +1 -0
- package/dist/lib-cjs/viewer.d.ts +7 -1
- package/dist/lib-cjs/viewer.js +4 -1
- package/dist/lib-cjs/viewer.js.map +1 -1
- package/package.json +13 -14
- package/src/index.ts +2 -0
- package/src/internal/cbn-custom-babylon-loader-plugin.ts +42 -0
- package/src/internal/conversion-helper.ts +77 -0
- package/src/internal/export-helper.ts +7 -2
- package/src/manager/debug-manager.ts +3 -3
- package/src/manager/material-manager.ts +3 -0
- package/src/manager/model-manager.ts +11 -31
- package/src/manager/scene-manager.ts +1 -1
- package/src/side-effects.ts +4 -0
- package/src/viewer.ts +9 -1
- package/dist/lib-cjs/internal/math-helper.d.ts +0 -9
- package/dist/lib-cjs/internal/math-helper.js +0 -43
- package/dist/lib-cjs/internal/math-helper.js.map +0 -1
- package/src/internal/math-helper.ts +0 -46
package/dist/lib-cjs/viewer.js
CHANGED
|
@@ -32,6 +32,7 @@ const Index = __importStar(require("./index"));
|
|
|
32
32
|
const index_1 = require("./index");
|
|
33
33
|
const cbn_custom_babylon_loader_plugin_1 = require("./internal/cbn-custom-babylon-loader-plugin");
|
|
34
34
|
const device_helper_1 = require("./internal/device-helper");
|
|
35
|
+
const scene_pure_1 = require("@babylonjs/core/scene.pure");
|
|
35
36
|
const lodash_es_1 = require("lodash-es");
|
|
36
37
|
/**
|
|
37
38
|
* This is the entry point into the application.\
|
|
@@ -67,6 +68,7 @@ class Viewer {
|
|
|
67
68
|
size: 1024,
|
|
68
69
|
},
|
|
69
70
|
useParallelShaderCompile: true,
|
|
71
|
+
useRightHandedSystem: false,
|
|
70
72
|
};
|
|
71
73
|
this._isRenderLoopPaused = false;
|
|
72
74
|
this._isBlurred = false;
|
|
@@ -190,7 +192,8 @@ class Viewer {
|
|
|
190
192
|
if (this._viewerSettings.useParallelShaderCompile === false) {
|
|
191
193
|
engine.getCaps().parallelShaderCompile = undefined;
|
|
192
194
|
}
|
|
193
|
-
this._scene = new
|
|
195
|
+
this._scene = new scene_pure_1.Scene(engine);
|
|
196
|
+
this._scene.useRightHandedSystem = this._viewerSettings.useRightHandedSystem;
|
|
194
197
|
// NOTE: rendering group id "1" is reserved for occlusion helper sphere (see `HtmlAnchorManager`)
|
|
195
198
|
// rendering group id "1" has the same depth buffer as 0 in order to make this work
|
|
196
199
|
// => use rendering group id "2" or higher for keeping meshes in foreground
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/viewer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sEAAyC;AACzC,+CAAiC;AACjC,
|
|
1
|
+
{"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/viewer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@combeenation/3d-viewer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "22.0.0-beta1",
|
|
4
4
|
"description": "Combeenation 3D Viewer",
|
|
5
5
|
"homepage": "https://github.com/Combeenation/3d-viewer#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
},
|
|
50
50
|
"prettier": "@combeenation/prettier-config",
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@babylonjs/core": "
|
|
53
|
-
"@babylonjs/gui": "
|
|
54
|
-
"@babylonjs/loaders": "
|
|
55
|
-
"@babylonjs/serializers": "
|
|
52
|
+
"@babylonjs/core": "9.12.0",
|
|
53
|
+
"@babylonjs/gui": "9.12.0",
|
|
54
|
+
"@babylonjs/loaders": "9.12.0",
|
|
55
|
+
"@babylonjs/serializers": "9.12.0",
|
|
56
56
|
"dxf-writer": "1.18.4",
|
|
57
57
|
"eventemitter3": "4.0.7",
|
|
58
58
|
"html2canvas": "1.4.1",
|
|
@@ -86,19 +86,18 @@
|
|
|
86
86
|
"webpack-merge": "5.8.0"
|
|
87
87
|
},
|
|
88
88
|
"optionalDependencies": {
|
|
89
|
-
"@babylonjs/addons": "
|
|
90
|
-
"@babylonjs/gui-editor": "
|
|
91
|
-
"@babylonjs/inspector": "
|
|
92
|
-
"@babylonjs/materials": "
|
|
93
|
-
"@babylonjs/node-editor": "
|
|
94
|
-
"@babylonjs/node-geometry-editor": "
|
|
89
|
+
"@babylonjs/addons": "9.12.0",
|
|
90
|
+
"@babylonjs/gui-editor": "9.12.0",
|
|
91
|
+
"@babylonjs/inspector": "9.12.0",
|
|
92
|
+
"@babylonjs/materials": "9.12.0",
|
|
93
|
+
"@babylonjs/node-editor": "9.12.0",
|
|
94
|
+
"@babylonjs/node-geometry-editor": "9.12.0"
|
|
95
95
|
},
|
|
96
96
|
"dependenciesComments": {
|
|
97
|
-
"@babylonjs": "Latest version
|
|
97
|
+
"@babylonjs": "Latest version 9.12.0 fixes CSG2 in right handed coordinate system (see https://forum.babylonjs.com/t/problems-with-csg2-and-userighthandedsystem/63626)"
|
|
98
98
|
},
|
|
99
99
|
"optionalDependenciesComments": {
|
|
100
|
-
"@babylonjs": "Defining the inspector package (and it's dependencies) as optional is required to omit these packages in the production build of the CBN react-app (see CB-9269)"
|
|
101
|
-
"@babylonjs/inspector": "Inspector integration from version 8.54.0 doesn't work out of the box, therefore we still go with the legacy one ATM (see CB-11276)"
|
|
100
|
+
"@babylonjs": "Defining the inspector package (and it's dependencies) as optional is required to omit these packages in the production build of the CBN react-app (see CB-9269)"
|
|
102
101
|
},
|
|
103
102
|
"scriptsComments": {
|
|
104
103
|
"test-delayed": "Didn't manage to wait 5 seconds for starting up the asset server as an individual VS Code task, therefore it's solved as npm script"
|
package/src/index.ts
CHANGED
|
@@ -4,13 +4,17 @@ import {
|
|
|
4
4
|
DecalUtils,
|
|
5
5
|
ISceneLoaderPlugin,
|
|
6
6
|
InstancedMesh,
|
|
7
|
+
Mesh,
|
|
8
|
+
Orientation,
|
|
7
9
|
ParsedDecalConfiguration,
|
|
10
|
+
Scene,
|
|
8
11
|
SceneAssetSettings,
|
|
9
12
|
SceneLoader,
|
|
10
13
|
ViewerError,
|
|
11
14
|
ViewerErrorIds,
|
|
12
15
|
} from '../index';
|
|
13
16
|
import { CbnViewerBridge } from './cbn-viewer-bridge';
|
|
17
|
+
import { adjustNormalMapForHandedness, flipHandednessOfNode, getRootNodeOfModel } from './conversion-helper';
|
|
14
18
|
import { setInternalMetadataValue } from './metadata-helper';
|
|
15
19
|
import { deleteAllTags, getTagsAsStrArr, setTagsAsString } from './tags-helper';
|
|
16
20
|
import { isArray, isString } from 'lodash-es';
|
|
@@ -34,6 +38,7 @@ export type CbnBabylonFileData = { decals?: ParsedDecalConfiguration[] };
|
|
|
34
38
|
|
|
35
39
|
type DataWithMeshes = { meshes: unknown[] };
|
|
36
40
|
type DataWithDecalConfigurations = { cbnData: { decals: unknown[] } };
|
|
41
|
+
type DataWithCoordinateSystemMode = { useRightHandedSystem: boolean };
|
|
37
42
|
|
|
38
43
|
type MeshData = {
|
|
39
44
|
name: string;
|
|
@@ -105,6 +110,8 @@ export function registerCustomCbnBabylonLoaderPlugin(): void {
|
|
|
105
110
|
clearColor: dataParsed.clearColor && Color4.FromArray(dataParsed.clearColor),
|
|
106
111
|
};
|
|
107
112
|
|
|
113
|
+
_adaptToHandednessChange(dataParsed, extendedContainer, scene);
|
|
114
|
+
|
|
108
115
|
return extendedContainer;
|
|
109
116
|
},
|
|
110
117
|
};
|
|
@@ -120,6 +127,10 @@ function _isDataWithDecalConfigurations(data: any): data is DataWithDecalConfigu
|
|
|
120
127
|
return isArray(data?.cbnData?.decals);
|
|
121
128
|
}
|
|
122
129
|
|
|
130
|
+
function _isDataWithCoordinateSystemMode(data: any): data is DataWithCoordinateSystemMode {
|
|
131
|
+
return typeof data?.useRightHandedSystem === 'boolean';
|
|
132
|
+
}
|
|
133
|
+
|
|
123
134
|
function _isMeshData(data: any): data is MeshData {
|
|
124
135
|
const hasName = isString(data.name);
|
|
125
136
|
const hasValidMaterialId = !data.materialId || isString(data.materialId);
|
|
@@ -240,3 +251,34 @@ function _createDecals(dataParsed: unknown, container: AssetContainer): void {
|
|
|
240
251
|
}
|
|
241
252
|
});
|
|
242
253
|
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Make adjustments in meshes and materials to support switching handedness from imported model to viewer scene.\
|
|
257
|
+
* Main use case is to use Babylon Assets (left-handed ATM) in a right-handed viewer scene.
|
|
258
|
+
*/
|
|
259
|
+
function _adaptToHandednessChange(dataParsed: unknown, container: AssetContainer, scene: Scene): void {
|
|
260
|
+
if (!_isDataWithCoordinateSystemMode(dataParsed)) return;
|
|
261
|
+
|
|
262
|
+
// nothing to do if the handedness hasn't changed
|
|
263
|
+
if (scene.useRightHandedSystem === dataParsed.useRightHandedSystem) return;
|
|
264
|
+
|
|
265
|
+
container.populateRootNodes();
|
|
266
|
+
const rootNode = getRootNodeOfModel(container);
|
|
267
|
+
if (!rootNode) {
|
|
268
|
+
// we only do a conversion if there is a single root node, otherwise we would need to make more complex adjustments
|
|
269
|
+
console.error('Could not adapt model to handedness, because root node could not be determined');
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
flipHandednessOfNode(rootNode);
|
|
274
|
+
|
|
275
|
+
container.meshes.forEach(mesh => {
|
|
276
|
+
if (mesh instanceof Mesh) {
|
|
277
|
+
mesh.sideOrientation = mesh.sideOrientation === Orientation.CW ? Orientation.CCW : Orientation.CW;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
container.materials.forEach(material => {
|
|
282
|
+
adjustNormalMapForHandedness(material, scene.useRightHandedSystem);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { AssetContainer, Material, Matrix, PBRMaterial, Quaternion, Scene, TransformNode, Vector3 } from '..';
|
|
2
|
+
|
|
3
|
+
const _CONVERT_HANDEDNESS_MATRIX = Matrix.Compose(new Vector3(-1, 1, 1), Quaternion.Identity(), Vector3.Zero());
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns the root node of a models asset container.\
|
|
7
|
+
* This can be useful to reposition an entire (cloned) model.\
|
|
8
|
+
* Function expects only one root `TransformNode` and will return `undefined` otherwise.
|
|
9
|
+
*/
|
|
10
|
+
export function getRootNodeOfModel(assetContainer: AssetContainer): TransformNode | undefined {
|
|
11
|
+
// `assetContainer.rootNodes` can also contain other `Node` types like lights or cameras, which we don't want here
|
|
12
|
+
const rootNodes = assetContainer.rootNodes.filter(node => node instanceof TransformNode) as TransformNode[];
|
|
13
|
+
if (rootNodes.length === 0) {
|
|
14
|
+
console.warn(`No root node found for associated model`);
|
|
15
|
+
return undefined;
|
|
16
|
+
} else if (rootNodes.length > 1) {
|
|
17
|
+
console.warn(`Mutltiple root nodes found for associated model`);
|
|
18
|
+
return undefined;
|
|
19
|
+
} else {
|
|
20
|
+
return rootNodes[0];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Evaluates if the absolute scaling of the node represents a left or right handed coordinate system
|
|
26
|
+
*/
|
|
27
|
+
export function nodeHasLeftHandedScaling(node: TransformNode, scene: Scene): boolean {
|
|
28
|
+
// update world matrix is required to get absolute scaling
|
|
29
|
+
node.computeWorldMatrix(true);
|
|
30
|
+
|
|
31
|
+
let cntNeg = 0;
|
|
32
|
+
if (node.absoluteScaling.x < 0) {
|
|
33
|
+
cntNeg++;
|
|
34
|
+
}
|
|
35
|
+
if (node.absoluteScaling.y < 0) {
|
|
36
|
+
cntNeg++;
|
|
37
|
+
}
|
|
38
|
+
if (node.absoluteScaling.z < 0) {
|
|
39
|
+
cntNeg++;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// flipping scaling values by an odd amount of directions also flips the handedness.
|
|
43
|
+
// that information needs to be combined with the handedness of the viewers scene.
|
|
44
|
+
const hasFlippedHandedness = cntNeg % 2 === 1;
|
|
45
|
+
const isLeftHanded = scene.useRightHandedSystem === hasFlippedHandedness;
|
|
46
|
+
|
|
47
|
+
return isLeftHanded;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Multiplies the nodes world matrix with the conversion matrix (-1 in x scaling) to flip the handedness.
|
|
52
|
+
*/
|
|
53
|
+
export function flipHandednessOfNode(node: TransformNode): void {
|
|
54
|
+
const world = node.getWorldMatrix().clone();
|
|
55
|
+
world.multiplyToRef(_CONVERT_HANDEDNESS_MATRIX, world);
|
|
56
|
+
|
|
57
|
+
const scaling = new Vector3();
|
|
58
|
+
const rotation = new Quaternion();
|
|
59
|
+
const position = new Vector3();
|
|
60
|
+
|
|
61
|
+
world.decompose(scaling, rotation, position);
|
|
62
|
+
|
|
63
|
+
node.scaling = scaling;
|
|
64
|
+
node.rotationQuaternion = rotation;
|
|
65
|
+
node.position = position;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Set invertNormalMap flags according to handedness.\
|
|
70
|
+
* This code is in sync with the logic in the Babylon.js loader.
|
|
71
|
+
*/
|
|
72
|
+
export function adjustNormalMapForHandedness(material: Material, useRightHandedSystem: boolean): void {
|
|
73
|
+
if (material instanceof PBRMaterial) {
|
|
74
|
+
material.invertNormalMapX = !useRightHandedSystem;
|
|
75
|
+
material.invertNormalMapY = useRightHandedSystem;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -63,9 +63,14 @@ export async function exportPreProcess(viewer: Viewer, settings?: ExportPreProce
|
|
|
63
63
|
viewer.scene.rootNodes.forEach(rootNode => _prepareNodeForExport(viewer, rootNode, null, excludeNodes));
|
|
64
64
|
|
|
65
65
|
const nodesForExport = _getNodesMarkedForExport(viewer);
|
|
66
|
-
|
|
67
|
-
// it's important that this is done AFTER instanced meshes have been converted (`_prepareNodeForExport`)
|
|
66
|
+
|
|
68
67
|
nodesForExport.forEach(node => {
|
|
68
|
+
// certain metadata formats can cause problems in the AR scene (see CB-11461)
|
|
69
|
+
// just remove it, as the metadata is not really usable in any export anyway
|
|
70
|
+
delete node.metadata;
|
|
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`)
|
|
69
74
|
if (node instanceof Mesh) viewer.utils.bakeGeometryOfMesh(node);
|
|
70
75
|
});
|
|
71
76
|
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
ViewerEvent,
|
|
17
17
|
} from '../index';
|
|
18
18
|
import { CbnViewerBridge } from '../internal/cbn-viewer-bridge';
|
|
19
|
-
import { nodeHasLeftHandedScaling } from '../internal/
|
|
19
|
+
import { nodeHasLeftHandedScaling } from '../internal/conversion-helper';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Manager for debugging functionalities
|
|
@@ -125,7 +125,7 @@ The inspector can only be used in development builds.`);
|
|
|
125
125
|
const factor = DebugManager._getWorldCoordinatesAxesUnifyFactor();
|
|
126
126
|
this._axesViewer = new AxesViewer(utilityLayerScene, size * factor);
|
|
127
127
|
|
|
128
|
-
let isLeftHanded =
|
|
128
|
+
let isLeftHanded = !this.viewer.scene.useRightHandedSystem;
|
|
129
129
|
if (node) {
|
|
130
130
|
// required for correct rotation when calling right after creating the node (see CB-11240)
|
|
131
131
|
// force=true might not be needed, but it's safer
|
|
@@ -152,7 +152,7 @@ The inspector can only be used in development builds.`);
|
|
|
152
152
|
}
|
|
153
153
|
this._axesViewer.update(node.absolutePosition, xAxis, yAxis, zAxis);
|
|
154
154
|
|
|
155
|
-
isLeftHanded = nodeHasLeftHandedScaling(node);
|
|
155
|
+
isLeftHanded = nodeHasLeftHandedScaling(node, this.viewer.scene);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
DebugManager._prepareAxisVisual('X', this._axesViewer.xAxis);
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from '../index';
|
|
12
12
|
import { CbnViewerBridge } from '../internal/cbn-viewer-bridge';
|
|
13
13
|
import * as CloningHelper from '../internal/cloning-helper';
|
|
14
|
+
import { adjustNormalMapForHandedness } from '../internal/conversion-helper';
|
|
14
15
|
import {
|
|
15
16
|
clearInternalMetadataValue,
|
|
16
17
|
getInternalMetadataValue,
|
|
@@ -241,6 +242,8 @@ export class MaterialManager {
|
|
|
241
242
|
return null;
|
|
242
243
|
}
|
|
243
244
|
|
|
245
|
+
adjustNormalMapForHandedness(material, this.viewer.scene.useRightHandedSystem);
|
|
246
|
+
|
|
244
247
|
await this.viewer.parameterManager.applyParameterValuesToMaterial(material);
|
|
245
248
|
|
|
246
249
|
const texturesLoadProm = async (): Promise<void> => {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from '../index';
|
|
11
11
|
import { BaseAsset, loadAsset, prepareAssetForScene } from '../internal/asset-helper';
|
|
12
12
|
import { cloneModelAssetContainer } from '../internal/cloning-helper';
|
|
13
|
-
import { flipHandednessOfNode, nodeHasLeftHandedScaling } from '../internal/
|
|
13
|
+
import { flipHandednessOfNode, getRootNodeOfModel, nodeHasLeftHandedScaling } from '../internal/conversion-helper';
|
|
14
14
|
import { isArray } from 'lodash-es';
|
|
15
15
|
|
|
16
16
|
export type ParsedDecalConfiguration = DecalConfiguration & { materialId?: string; tags?: string };
|
|
@@ -314,7 +314,7 @@ export class ModelManager {
|
|
|
314
314
|
};
|
|
315
315
|
this._modelAssets[newModelName] = clonedModel;
|
|
316
316
|
|
|
317
|
-
const rootNode =
|
|
317
|
+
const rootNode = getRootNodeOfModel(clonedModel.assetContainer);
|
|
318
318
|
if (rootNode && rootNodeName) {
|
|
319
319
|
rootNode.name = rootNodeName;
|
|
320
320
|
}
|
|
@@ -323,17 +323,16 @@ export class ModelManager {
|
|
|
323
323
|
await this._showModel(clonedModel);
|
|
324
324
|
|
|
325
325
|
if (parentNode && rootNode) {
|
|
326
|
-
const parentNodeIsLeftHanded = nodeHasLeftHandedScaling(parentNode);
|
|
326
|
+
const parentNodeIsLeftHanded = nodeHasLeftHandedScaling(parentNode, this.viewer.scene);
|
|
327
|
+
const requiresHandednessFlip = parentNodeIsLeftHanded === this.viewer.scene.useRightHandedSystem;
|
|
327
328
|
|
|
328
|
-
//
|
|
329
|
-
//
|
|
330
|
-
//
|
|
329
|
+
// The handedness of a freshly loaded (and cloned) model equals the viewers handedness.
|
|
330
|
+
// However, the parent nodes handedness can differ, especially if it's deeply nested in the node hierarchy.
|
|
331
|
+
// In this case we have to flip the root node of the cloned model.
|
|
331
332
|
//
|
|
332
|
-
//
|
|
333
|
-
//
|
|
334
|
-
|
|
335
|
-
// transformation values in a hardcoded way.
|
|
336
|
-
if (!parentNodeIsLeftHanded) {
|
|
333
|
+
// NOTE: this should not be the case anymore when using the viewer in right-handed mode, as there are no
|
|
334
|
+
// negative scalings in the models root node anymore.
|
|
335
|
+
if (requiresHandednessFlip) {
|
|
337
336
|
flipHandednessOfNode(rootNode);
|
|
338
337
|
}
|
|
339
338
|
|
|
@@ -405,7 +404,7 @@ export class ModelManager {
|
|
|
405
404
|
await this._prepareModelForScene(model);
|
|
406
405
|
}
|
|
407
406
|
|
|
408
|
-
const rootNode =
|
|
407
|
+
const rootNode = getRootNodeOfModel(model.assetContainer);
|
|
409
408
|
|
|
410
409
|
return { assetContainer: model.assetContainer, rootNode };
|
|
411
410
|
}
|
|
@@ -514,23 +513,4 @@ export class ModelManager {
|
|
|
514
513
|
model.assetContainer.removeFromScene();
|
|
515
514
|
model.state = 'loaded';
|
|
516
515
|
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Returns the root node of a models asset container.\
|
|
520
|
-
* This can be useful to reposition an entire (cloned) model.\
|
|
521
|
-
* Function expects only one root `TransformNode` and will return `undefined` otherwise.
|
|
522
|
-
*/
|
|
523
|
-
protected _getRootNodeOfModel(assetContainer: AssetContainer): TransformNode | undefined {
|
|
524
|
-
// `assetContainer.rootNodes` can also contain other `Node` types like lights or cameras, which we don't want here
|
|
525
|
-
const rootNodes = assetContainer.rootNodes.filter(node => node instanceof TransformNode) as TransformNode[];
|
|
526
|
-
if (rootNodes.length === 0) {
|
|
527
|
-
console.warn(`No root node found for associated model`);
|
|
528
|
-
return undefined;
|
|
529
|
-
} else if (rootNodes.length > 1) {
|
|
530
|
-
console.warn(`Mutltiple root nodes found for associated model`);
|
|
531
|
-
return undefined;
|
|
532
|
-
} else {
|
|
533
|
-
return rootNodes[0];
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
516
|
}
|
|
@@ -353,7 +353,7 @@ export class SceneManager {
|
|
|
353
353
|
// built
|
|
354
354
|
// also the flat dimension of the plane is independent of the scaling, it will always remain a plane
|
|
355
355
|
groundMesh.scaling = new Vector3(factor, factor, factor);
|
|
356
|
-
groundMesh.
|
|
356
|
+
groundMesh.setAbsolutePosition(new Vector3(position.x, 0, position.z));
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
/**
|
package/src/viewer.ts
CHANGED
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
NodeParameterSubject,
|
|
17
17
|
NullEngine,
|
|
18
18
|
ParameterManager,
|
|
19
|
-
Scene,
|
|
20
19
|
SceneManager,
|
|
21
20
|
TagParameterSubject,
|
|
22
21
|
TextureManager,
|
|
@@ -25,6 +24,7 @@ import {
|
|
|
25
24
|
} from './index';
|
|
26
25
|
import { registerCustomCbnBabylonLoaderPlugin } from './internal/cbn-custom-babylon-loader-plugin';
|
|
27
26
|
import { getIsScaledDownDevice } from './internal/device-helper';
|
|
27
|
+
import { Scene } from '@babylonjs/core/scene.pure';
|
|
28
28
|
import { cloneDeep, merge } from 'lodash-es';
|
|
29
29
|
|
|
30
30
|
/**
|
|
@@ -70,6 +70,11 @@ export type ViewerSettings = {
|
|
|
70
70
|
* It's activated by default due to compatibility reasons but can be overwritten with this flag.
|
|
71
71
|
*/
|
|
72
72
|
useParallelShaderCompile: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Run the viewers scene in right handed mode.\
|
|
75
|
+
* The main advantage is that GLB based models can be used without a negative scaling in their root nodes.
|
|
76
|
+
*/
|
|
77
|
+
useRightHandedSystem: boolean;
|
|
73
78
|
};
|
|
74
79
|
|
|
75
80
|
/**
|
|
@@ -117,6 +122,7 @@ export class Viewer {
|
|
|
117
122
|
size: 1024,
|
|
118
123
|
},
|
|
119
124
|
useParallelShaderCompile: true,
|
|
125
|
+
useRightHandedSystem: false,
|
|
120
126
|
};
|
|
121
127
|
|
|
122
128
|
protected _isRenderLoopPaused = false;
|
|
@@ -272,6 +278,8 @@ export class Viewer {
|
|
|
272
278
|
}
|
|
273
279
|
|
|
274
280
|
this._scene = new Scene(engine);
|
|
281
|
+
this._scene.useRightHandedSystem = this._viewerSettings.useRightHandedSystem;
|
|
282
|
+
|
|
275
283
|
// NOTE: rendering group id "1" is reserved for occlusion helper sphere (see `HtmlAnchorManager`)
|
|
276
284
|
// rendering group id "1" has the same depth buffer as 0 in order to make this work
|
|
277
285
|
// => use rendering group id "2" or higher for keeping meshes in foreground
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { TransformNode } from '..';
|
|
2
|
-
/**
|
|
3
|
-
* Evaluates if the absolute scaling of the node represents a left or right handed coordinate system
|
|
4
|
-
*/
|
|
5
|
-
export declare function nodeHasLeftHandedScaling(node: TransformNode): boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Multiplies the nodes world matrix with the conversion matrix (-1 in x scaling) to flip the handedness.
|
|
8
|
-
*/
|
|
9
|
-
export declare function flipHandednessOfNode(node: TransformNode): void;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.flipHandednessOfNode = exports.nodeHasLeftHandedScaling = void 0;
|
|
4
|
-
const __1 = require("..");
|
|
5
|
-
const _CONVERT_HANDEDNESS_MATRIX = __1.Matrix.Compose(new __1.Vector3(-1, 1, 1), __1.Quaternion.Identity(), __1.Vector3.Zero());
|
|
6
|
-
/**
|
|
7
|
-
* Evaluates if the absolute scaling of the node represents a left or right handed coordinate system
|
|
8
|
-
*/
|
|
9
|
-
function nodeHasLeftHandedScaling(node) {
|
|
10
|
-
// update world matrix is required to get absolute scaling
|
|
11
|
-
node.computeWorldMatrix(true);
|
|
12
|
-
let cntNeg = 0;
|
|
13
|
-
if (node.absoluteScaling.x < 0) {
|
|
14
|
-
cntNeg++;
|
|
15
|
-
}
|
|
16
|
-
if (node.absoluteScaling.y < 0) {
|
|
17
|
-
cntNeg++;
|
|
18
|
-
}
|
|
19
|
-
if (node.absoluteScaling.z < 0) {
|
|
20
|
-
cntNeg++;
|
|
21
|
-
}
|
|
22
|
-
// flipping scaling values by an odd amount of directions also flips the coordinate system mode.
|
|
23
|
-
// given that Babylon.js is left handed by default, we can say that even is left handed and odd is right handed
|
|
24
|
-
const isLeftHanded = cntNeg % 2 === 0;
|
|
25
|
-
return isLeftHanded;
|
|
26
|
-
}
|
|
27
|
-
exports.nodeHasLeftHandedScaling = nodeHasLeftHandedScaling;
|
|
28
|
-
/**
|
|
29
|
-
* Multiplies the nodes world matrix with the conversion matrix (-1 in x scaling) to flip the handedness.
|
|
30
|
-
*/
|
|
31
|
-
function flipHandednessOfNode(node) {
|
|
32
|
-
const world = node.getWorldMatrix().clone();
|
|
33
|
-
world.multiplyToRef(_CONVERT_HANDEDNESS_MATRIX, world);
|
|
34
|
-
const scaling = new __1.Vector3();
|
|
35
|
-
const rotation = new __1.Quaternion();
|
|
36
|
-
const position = new __1.Vector3();
|
|
37
|
-
world.decompose(scaling, rotation, position);
|
|
38
|
-
node.scaling = scaling;
|
|
39
|
-
node.rotationQuaternion = rotation;
|
|
40
|
-
node.position = position;
|
|
41
|
-
}
|
|
42
|
-
exports.flipHandednessOfNode = flipHandednessOfNode;
|
|
43
|
-
//# sourceMappingURL=math-helper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"math-helper.js","sourceRoot":"","sources":["../../../src/internal/math-helper.ts"],"names":[],"mappings":";;;AAAA,0BAAgE;AAEhE,MAAM,0BAA0B,GAAG,UAAM,CAAC,OAAO,CAAC,IAAI,WAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,cAAU,CAAC,QAAQ,EAAE,EAAE,WAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAEhH;;GAEG;AACH,SAAgB,wBAAwB,CAAC,IAAmB;IAC1D,0DAA0D;IAC1D,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAE9B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,EAAE;QAC9B,MAAM,EAAE,CAAC;KACV;IACD,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,EAAE;QAC9B,MAAM,EAAE,CAAC;KACV;IACD,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,EAAE;QAC9B,MAAM,EAAE,CAAC;KACV;IAED,gGAAgG;IAChG,+GAA+G;IAC/G,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC;IAEtC,OAAO,YAAY,CAAC;AACtB,CAAC;AApBD,4DAoBC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,IAAmB;IACtD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,CAAC;IAC5C,KAAK,CAAC,aAAa,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;IAEvD,MAAM,OAAO,GAAG,IAAI,WAAO,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,cAAU,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,WAAO,EAAE,CAAC;IAE/B,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAE7C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC;IACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;AAC3B,CAAC;AAbD,oDAaC"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { Matrix, Quaternion, TransformNode, Vector3 } from '..';
|
|
2
|
-
|
|
3
|
-
const _CONVERT_HANDEDNESS_MATRIX = Matrix.Compose(new Vector3(-1, 1, 1), Quaternion.Identity(), Vector3.Zero());
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Evaluates if the absolute scaling of the node represents a left or right handed coordinate system
|
|
7
|
-
*/
|
|
8
|
-
export function nodeHasLeftHandedScaling(node: TransformNode): boolean {
|
|
9
|
-
// update world matrix is required to get absolute scaling
|
|
10
|
-
node.computeWorldMatrix(true);
|
|
11
|
-
|
|
12
|
-
let cntNeg = 0;
|
|
13
|
-
if (node.absoluteScaling.x < 0) {
|
|
14
|
-
cntNeg++;
|
|
15
|
-
}
|
|
16
|
-
if (node.absoluteScaling.y < 0) {
|
|
17
|
-
cntNeg++;
|
|
18
|
-
}
|
|
19
|
-
if (node.absoluteScaling.z < 0) {
|
|
20
|
-
cntNeg++;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// flipping scaling values by an odd amount of directions also flips the coordinate system mode.
|
|
24
|
-
// given that Babylon.js is left handed by default, we can say that even is left handed and odd is right handed
|
|
25
|
-
const isLeftHanded = cntNeg % 2 === 0;
|
|
26
|
-
|
|
27
|
-
return isLeftHanded;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Multiplies the nodes world matrix with the conversion matrix (-1 in x scaling) to flip the handedness.
|
|
32
|
-
*/
|
|
33
|
-
export function flipHandednessOfNode(node: TransformNode): void {
|
|
34
|
-
const world = node.getWorldMatrix().clone();
|
|
35
|
-
world.multiplyToRef(_CONVERT_HANDEDNESS_MATRIX, world);
|
|
36
|
-
|
|
37
|
-
const scaling = new Vector3();
|
|
38
|
-
const rotation = new Quaternion();
|
|
39
|
-
const position = new Vector3();
|
|
40
|
-
|
|
41
|
-
world.decompose(scaling, rotation, position);
|
|
42
|
-
|
|
43
|
-
node.scaling = scaling;
|
|
44
|
-
node.rotationQuaternion = rotation;
|
|
45
|
-
node.position = position;
|
|
46
|
-
}
|