@archvisioninc/canvas 3.3.6 → 3.3.8
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/.claude/settings.local.json +8 -0
- package/README_DEV.md +4 -1
- package/package.json +1 -1
- package/src/package/helpers/canvasUpdateHelpers.js +145 -0
- package/src/package/helpers/initHelpers.js +10 -0
- package/src/package/helpers/utilityHelpers.js +17 -0
- package/dist/Canvas.js +0 -67
- package/dist/actions/index.js +0 -1
- package/dist/actions/shortcutActions.js +0 -313
- package/dist/constants/constants.js +0 -80
- package/dist/constants/index.js +0 -1
- package/dist/enums/aspectRatios.js +0 -17
- package/dist/enums/dimensions.js +0 -20
- package/dist/enums/downscaling.js +0 -16
- package/dist/enums/exclusions.js +0 -4
- package/dist/enums/formats.js +0 -1
- package/dist/enums/index.js +0 -8
- package/dist/enums/orthoOptions.js +0 -28
- package/dist/enums/scaleUnits.js +0 -25
- package/dist/enums/shortcuts.js +0 -89
- package/dist/helpers/cameraHelpers.js +0 -86
- package/dist/helpers/canvasAddHelpers.js +0 -161
- package/dist/helpers/canvasCommunicationHelpers.js +0 -52
- package/dist/helpers/canvasRemoveHelpers.js +0 -230
- package/dist/helpers/canvasUpdateHelpers.js +0 -1247
- package/dist/helpers/gizmoHelpers.js +0 -156
- package/dist/helpers/guiHelpers.js +0 -46
- package/dist/helpers/index.js +0 -16
- package/dist/helpers/initHelpers.js +0 -507
- package/dist/helpers/lightHelpers.js +0 -17
- package/dist/helpers/loadHelpers.js +0 -269
- package/dist/helpers/materialHelpers.js +0 -34
- package/dist/helpers/meshHelpers.js +0 -169
- package/dist/helpers/rayHelpers.js +0 -11
- package/dist/helpers/shortcutHelpers.js +0 -35
- package/dist/helpers/utilityHelpers.js +0 -697
- package/dist/helpers/viewportHelpers.js +0 -364
- package/dist/styles.js +0 -25
|
@@ -1,507 +0,0 @@
|
|
|
1
|
-
import * as BABYLON from 'babylonjs';
|
|
2
|
-
import * as MATERIALS from 'babylonjs-materials';
|
|
3
|
-
import * as BABYLONGUI from 'babylonjs-gui';
|
|
4
|
-
import { LISTENERS, LIGHTS, CAMERAS, VIEWPORT } from '../constants';
|
|
5
|
-
import { shortcuts, ratios, downscaling, exclusionMeshes, exclusionMaterials } from '../enums';
|
|
6
|
-
import { newScene, newEngine, newCamera, newLight, newVector, newHighlightManager, handleMouseListeners, handleShortcutListeners, prepareCamera, newGround, newGridMaterial, newColor, setDefaultGridProperties, prepareAxes, getBoundingDistance, newGizmoManager, getUserMeshes, getUserMaterials, newPBRMaterial, createSafeFrame, createDragSelectBox, addInitialGizmoBehaviors, loadFromBlob, loadFromGuidURL, prepareMaterialCamera, loadFromDragDrop, addHighlightExclusion, warningChecks, toRadians, toDegrees, getStatisticsMetadata, newMetaDataEntry, serializeScene, buildMeshPositionsArray, buildMaterialsArray, updatePublish, buildSelectedMaterialArray, buildMaterialVariantsArray, removeAutoRotation, getUserNodes, buildLightsArray } from '../helpers';
|
|
7
|
-
import { modelToOrigin, focusCamera } from '../actions';
|
|
8
|
-
import { reactProps as props } from '../Canvas';
|
|
9
|
-
import _ from 'lodash';
|
|
10
|
-
const node0Name = 'node0';
|
|
11
|
-
const resize = LISTENERS.resize;
|
|
12
|
-
export let engine;
|
|
13
|
-
export let canvas;
|
|
14
|
-
export let scene;
|
|
15
|
-
export let highlightManager;
|
|
16
|
-
export let hoverHighlightManager;
|
|
17
|
-
export let theme;
|
|
18
|
-
export let $selectedTheme;
|
|
19
|
-
export let ground;
|
|
20
|
-
export let mirrorGround;
|
|
21
|
-
export let shadowGenerator;
|
|
22
|
-
export let utilLayer;
|
|
23
|
-
export let gizmoManager;
|
|
24
|
-
export let hdrSphere;
|
|
25
|
-
export let guiTexture;
|
|
26
|
-
export let multiMeshTNode;
|
|
27
|
-
export let singleMeshTNode;
|
|
28
|
-
export let dragDropFileInput;
|
|
29
|
-
export let iblShadowPipeline;
|
|
30
|
-
export let shortcutArray = [];
|
|
31
|
-
export const groundOptions = () => {
|
|
32
|
-
const meshSize = getBoundingDistance() || 10;
|
|
33
|
-
const gridOffset = 10;
|
|
34
|
-
const width = meshSize + gridOffset;
|
|
35
|
-
const height = meshSize + gridOffset;
|
|
36
|
-
const grid = {
|
|
37
|
-
width,
|
|
38
|
-
height
|
|
39
|
-
};
|
|
40
|
-
return grid;
|
|
41
|
-
};
|
|
42
|
-
const resizeEngine = () => engine?.resize();
|
|
43
|
-
export const initSceneObjects = () => {
|
|
44
|
-
initCamera();
|
|
45
|
-
initLights();
|
|
46
|
-
if (!props.previewMode) initHighlightManagers();
|
|
47
|
-
if (!props.previewMode) initGridGround();
|
|
48
|
-
initMirrorGround();
|
|
49
|
-
initGizmos();
|
|
50
|
-
if (!props.previewMode) prepareAxes();
|
|
51
|
-
initEnvironment();
|
|
52
|
-
initGUI();
|
|
53
|
-
checkForRootNode();
|
|
54
|
-
};
|
|
55
|
-
const initHighlightManagers = () => {
|
|
56
|
-
highlightManager = newHighlightManager('selectHighlightManager');
|
|
57
|
-
hoverHighlightManager = newHighlightManager('hoverHighlightManager');
|
|
58
|
-
};
|
|
59
|
-
const tweakSceneForShaderball = () => {
|
|
60
|
-
const xAxis = scene.getMeshById('xAxisMesh');
|
|
61
|
-
const yAxis = scene.getMeshById('yAxisMesh');
|
|
62
|
-
const zAxis = scene.getMeshById('zAxisMesh');
|
|
63
|
-
if (xAxis) xAxis.isVisible = false;
|
|
64
|
-
if (yAxis) yAxis.isVisible = false;
|
|
65
|
-
if (zAxis) zAxis.isVisible = false;
|
|
66
|
-
if (ground) ground.isVisible = false;
|
|
67
|
-
prepareMaterialCamera();
|
|
68
|
-
props.clearNotifications?.();
|
|
69
|
-
};
|
|
70
|
-
const loadDemoMeshes = () => {
|
|
71
|
-
const sphereOptions = {
|
|
72
|
-
diameter: 2,
|
|
73
|
-
segments: 32
|
|
74
|
-
};
|
|
75
|
-
const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', sphereOptions, scene);
|
|
76
|
-
const rect = BABYLON.MeshBuilder.CreateBox('box', {
|
|
77
|
-
width: 4,
|
|
78
|
-
height: 2,
|
|
79
|
-
depth: 4
|
|
80
|
-
}, scene);
|
|
81
|
-
rect.position.x = 2;
|
|
82
|
-
rect.position.y = 1;
|
|
83
|
-
rect.position.z = -2;
|
|
84
|
-
rect.material = newPBRMaterial('pbrRect');
|
|
85
|
-
rect.material.metallic = 0;
|
|
86
|
-
sphere.position.x = -4;
|
|
87
|
-
sphere.position.y = 1;
|
|
88
|
-
sphere.position.z = 2;
|
|
89
|
-
sphere.material = newPBRMaterial('pbrSphere');
|
|
90
|
-
sphere.material.roughness = 0.05;
|
|
91
|
-
};
|
|
92
|
-
const initCamera = () => {
|
|
93
|
-
const cameraMeta = {
|
|
94
|
-
alpha: 0,
|
|
95
|
-
beta: 0,
|
|
96
|
-
radius: 10
|
|
97
|
-
};
|
|
98
|
-
const cameraLocation = {
|
|
99
|
-
x: 0,
|
|
100
|
-
y: 0,
|
|
101
|
-
z: 0
|
|
102
|
-
};
|
|
103
|
-
newCamera('defaultCamera', cameraLocation, CAMERAS.ArcRotateCamera, cameraMeta);
|
|
104
|
-
if (!props.materialMode) {
|
|
105
|
-
prepareCamera();
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
const initGUI = () => {
|
|
109
|
-
const aspectRatio = props.ratio?.value || ratios.broadcast.value;
|
|
110
|
-
guiTexture = new BABYLONGUI.AdvancedDynamicTexture.CreateFullscreenUI('GUI');
|
|
111
|
-
createSafeFrame(aspectRatio);
|
|
112
|
-
createDragSelectBox();
|
|
113
|
-
};
|
|
114
|
-
const initEnvironment = () => {
|
|
115
|
-
const envIntensity = 0.5;
|
|
116
|
-
const envRotation = toRadians(props.envRotation || 0);
|
|
117
|
-
const envBlur = props.envBlur || 0.5;
|
|
118
|
-
const url = props.defaultEnvironments?.find?.(env => _.toLower(env.id) === 'default')?.envURL;
|
|
119
|
-
const hdrTexture = new BABYLON.CubeTexture(url, scene);
|
|
120
|
-
const isPBR = true;
|
|
121
|
-
const scale = 1000;
|
|
122
|
-
const isGlobalTexture = true;
|
|
123
|
-
const createNewSkybox = () => scene.createDefaultSkybox(hdrTexture, isPBR, scale, envBlur, isGlobalTexture);
|
|
124
|
-
const hdrSkyBox = !scene.getMeshById('hdrSkyBox') ? createNewSkybox() : scene.getMeshById('hdrSkyBox');
|
|
125
|
-
const skyBox = scene.getMaterialById('skyBox');
|
|
126
|
-
const backgroundColor = newColor('#00000000');
|
|
127
|
-
if (scene.environmentTexture) {
|
|
128
|
-
scene.environmentTexture.rotationY = envRotation;
|
|
129
|
-
}
|
|
130
|
-
scene.environmentIntensity = envIntensity;
|
|
131
|
-
scene.clearColor = backgroundColor;
|
|
132
|
-
if (skyBox.reflectionTexture) {
|
|
133
|
-
skyBox.reflectionTexture.rotationY = envRotation;
|
|
134
|
-
}
|
|
135
|
-
skyBox.microSurface = 1 - envBlur;
|
|
136
|
-
hdrSkyBox.setEnabled(false);
|
|
137
|
-
scene.metadata = {
|
|
138
|
-
...scene.metadata,
|
|
139
|
-
environmentIntensity: envIntensity,
|
|
140
|
-
environmentRotation: toDegrees(envRotation),
|
|
141
|
-
environmentBlur: skyBox.microSurface,
|
|
142
|
-
viewportEnvironment: hdrSkyBox.isEnabled()
|
|
143
|
-
};
|
|
144
|
-
if (scene.metadata.publish) {
|
|
145
|
-
props.setSerializedData?.(serializeScene());
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
export const initGizmos = () => {
|
|
149
|
-
gizmoManager = newGizmoManager();
|
|
150
|
-
if (multiMeshTNode || singleMeshTNode) {
|
|
151
|
-
singleMeshTNode.dispose();
|
|
152
|
-
multiMeshTNode.dispose();
|
|
153
|
-
}
|
|
154
|
-
singleMeshTNode = new BABYLON.TransformNode('singleMeshTransforms', scene);
|
|
155
|
-
multiMeshTNode = new BABYLON.TransformNode('multiMeshTransforms', scene);
|
|
156
|
-
addInitialGizmoBehaviors();
|
|
157
|
-
};
|
|
158
|
-
const initLights = () => {
|
|
159
|
-
const meshes = getUserMeshes();
|
|
160
|
-
const dirLight = newLight('directional', {
|
|
161
|
-
x: -1,
|
|
162
|
-
y: -2,
|
|
163
|
-
z: -1
|
|
164
|
-
}, LIGHTS.DirectionalLight);
|
|
165
|
-
dirLight.position = newVector(100, 200, 100);
|
|
166
|
-
dirLight.intensity = 0.5;
|
|
167
|
-
dirLight.shadowMinZ = 2;
|
|
168
|
-
dirLight.shadowMaxZ = 300;
|
|
169
|
-
const shadowLightOptions = {
|
|
170
|
-
mapSize: VIEWPORT.shadowMapSize,
|
|
171
|
-
dirLight
|
|
172
|
-
};
|
|
173
|
-
shadowGenerator = newLight('shadowLight', BABYLON.Vector3.Zero(), LIGHTS.ShadowGenerator, shadowLightOptions);
|
|
174
|
-
meshes.forEach(mesh => shadowGenerator.addShadowCaster(mesh, true));
|
|
175
|
-
shadowGenerator.transparencyShadow = true;
|
|
176
|
-
shadowGenerator.useContactHardeningShadow = true;
|
|
177
|
-
shadowGenerator.contactHardeningLightSizeUVRatio = 0.2;
|
|
178
|
-
shadowGenerator.bias = 0.00001;
|
|
179
|
-
shadowGenerator.normalBias = 0.01;
|
|
180
|
-
iblShadowPipeline = new BABYLON.IblShadowsRenderPipeline('archvision_ibl_shadows', scene);
|
|
181
|
-
meshes.forEach(mesh => iblShadowPipeline.addShadowCastingMesh(mesh));
|
|
182
|
-
const materials = getUserMaterials();
|
|
183
|
-
materials.forEach(mat => iblShadowPipeline.addShadowReceivingMaterial(mat));
|
|
184
|
-
exclusionMeshes.forEach(name => {
|
|
185
|
-
const mesh = scene.getMeshByName(name);
|
|
186
|
-
iblShadowPipeline.removeShadowCastingMesh(mesh);
|
|
187
|
-
});
|
|
188
|
-
exclusionMaterials.forEach(name => {
|
|
189
|
-
const mat = scene.getMaterialByName(name);
|
|
190
|
-
iblShadowPipeline.removeShadowReceivingMaterial(mat);
|
|
191
|
-
});
|
|
192
|
-
iblShadowPipeline.toggleShadow(false);
|
|
193
|
-
};
|
|
194
|
-
const initGridGround = () => {
|
|
195
|
-
const gridMaterial = newGridMaterial('gridMat');
|
|
196
|
-
setDefaultGridProperties(gridMaterial);
|
|
197
|
-
ground = newGround('ground', groundOptions());
|
|
198
|
-
ground.material = gridMaterial;
|
|
199
|
-
ground.isPickable = false;
|
|
200
|
-
addHighlightExclusion(ground);
|
|
201
|
-
newMetaDataEntry('viewportGround', ground.isVisible);
|
|
202
|
-
};
|
|
203
|
-
const initMirrorGround = () => {
|
|
204
|
-
const shadowMat = new MATERIALS.ShadowOnlyMaterial('ground', scene);
|
|
205
|
-
shadowMat.specularColor = newColor(0, 0, 0);
|
|
206
|
-
shadowMat.diffuseColor = newColor(theme.colors[$selectedTheme].primary);
|
|
207
|
-
shadowMat.shadowLevel = 0.4;
|
|
208
|
-
shadowMat.alpha = 0.5;
|
|
209
|
-
shadowMat.backFaceCulling = true;
|
|
210
|
-
mirrorGround = newGround('mirrorGround', groundOptions());
|
|
211
|
-
mirrorGround.material = shadowMat;
|
|
212
|
-
mirrorGround.isPickable = false;
|
|
213
|
-
mirrorGround.receiveShadows = props.integration?.shadows;
|
|
214
|
-
addHighlightExclusion(mirrorGround);
|
|
215
|
-
newMetaDataEntry('viewportShadows', mirrorGround.receiveShadows);
|
|
216
|
-
};
|
|
217
|
-
export const initScene = async args => {
|
|
218
|
-
const renderScene = () => scene?.render();
|
|
219
|
-
const {
|
|
220
|
-
canvasRef
|
|
221
|
-
} = args;
|
|
222
|
-
canvas = canvasRef?.current;
|
|
223
|
-
if (!engine && canvas) {
|
|
224
|
-
engine = await newEngine();
|
|
225
|
-
const nullEngine = engine instanceof BABYLON.NullEngine;
|
|
226
|
-
window.removeEventListener(resize, resizeEngine);
|
|
227
|
-
window.addEventListener(resize, resizeEngine);
|
|
228
|
-
if (!nullEngine) {
|
|
229
|
-
createScene();
|
|
230
|
-
engine.runRenderLoop(renderScene);
|
|
231
|
-
}
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
createScene();
|
|
235
|
-
};
|
|
236
|
-
export const createScene = createNewScene => {
|
|
237
|
-
if (!scene || createNewScene) {
|
|
238
|
-
scene = newScene();
|
|
239
|
-
scene.useRightHandedSystem = false;
|
|
240
|
-
}
|
|
241
|
-
if (!theme && !$selectedTheme && props.theme && props.$selectedTheme) {
|
|
242
|
-
theme = props.theme;
|
|
243
|
-
$selectedTheme = props.$selectedTheme;
|
|
244
|
-
}
|
|
245
|
-
utilLayer = new BABYLON.UtilityLayerRenderer(scene, false);
|
|
246
|
-
initSceneObjects();
|
|
247
|
-
initListeners();
|
|
248
|
-
if (props.materialMode) tweakSceneForShaderball();
|
|
249
|
-
if (props.demoScene) loadDemoMeshes();
|
|
250
|
-
if (props.file) {
|
|
251
|
-
loadFromBlob(props.file);
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
if (props.guidURL && !props.reinitialize) loadFromGuidURL(props.guidURL);
|
|
255
|
-
};
|
|
256
|
-
const initMetadataKeyDefaults = () => {
|
|
257
|
-
const {
|
|
258
|
-
position,
|
|
259
|
-
rotation,
|
|
260
|
-
target
|
|
261
|
-
} = scene.activeCamera;
|
|
262
|
-
const [tx, ty, tz] = [position.x, position.y, position.z];
|
|
263
|
-
const [rx, ry, rz] = [rotation.x, rotation.y, rotation.z];
|
|
264
|
-
const [tarX, tarY, tarZ] = [target.x, target.y, target.z];
|
|
265
|
-
const cameraSchema = {
|
|
266
|
-
id: 'Default',
|
|
267
|
-
tx,
|
|
268
|
-
ty,
|
|
269
|
-
tz,
|
|
270
|
-
rx,
|
|
271
|
-
ry,
|
|
272
|
-
rz,
|
|
273
|
-
tarX,
|
|
274
|
-
tarY,
|
|
275
|
-
tarZ
|
|
276
|
-
};
|
|
277
|
-
const downscaleDefault = downscaling.find(size => size.name === '4K').value;
|
|
278
|
-
const defaultEnvironment = props.defaultEnvironments?.find?.(env => _.toLower(env.id) === 'default');
|
|
279
|
-
const defaultGlobalTransforms = {
|
|
280
|
-
tx: 0,
|
|
281
|
-
ty: 0,
|
|
282
|
-
tz: 0,
|
|
283
|
-
rx: 0,
|
|
284
|
-
ry: 0,
|
|
285
|
-
rz: 0,
|
|
286
|
-
sx: 1,
|
|
287
|
-
sy: 1,
|
|
288
|
-
sz: 1
|
|
289
|
-
};
|
|
290
|
-
const publishSchema = {
|
|
291
|
-
title: '',
|
|
292
|
-
category: 'Other',
|
|
293
|
-
tags: [],
|
|
294
|
-
proxy: 'billboard',
|
|
295
|
-
meshSimplification: {
|
|
296
|
-
enabled: false,
|
|
297
|
-
isControl: false,
|
|
298
|
-
decimateAmount: 0.5,
|
|
299
|
-
type: 'custom',
|
|
300
|
-
optimizationType: 'estimated triangles',
|
|
301
|
-
totalTriangles: 0,
|
|
302
|
-
estimatedTriangles: 99,
|
|
303
|
-
userTargetTriangles: 0,
|
|
304
|
-
targetTriangles: 0
|
|
305
|
-
},
|
|
306
|
-
textureDownscaling: {
|
|
307
|
-
enabled: false,
|
|
308
|
-
size: downscaleDefault
|
|
309
|
-
}
|
|
310
|
-
};
|
|
311
|
-
newMetaDataEntry('defaultEnvironment', defaultEnvironment?.envURL);
|
|
312
|
-
newMetaDataEntry('defaultCameraPosition', {});
|
|
313
|
-
newMetaDataEntry('materials', []);
|
|
314
|
-
newMetaDataEntry('publish', publishSchema);
|
|
315
|
-
newMetaDataEntry('selectedMeshes', []);
|
|
316
|
-
newMetaDataEntry('materialVariants', []);
|
|
317
|
-
newMetaDataEntry('hiddenMeshes', []);
|
|
318
|
-
newMetaDataEntry('userMeshPositions', []);
|
|
319
|
-
newMetaDataEntry('userCameraViews', []);
|
|
320
|
-
newMetaDataEntry('userEnvironments', []);
|
|
321
|
-
newMetaDataEntry('selectedAxisCompensation', 'Y-Axis up');
|
|
322
|
-
newMetaDataEntry('boundingBoxEnabled', false);
|
|
323
|
-
newMetaDataEntry('selectedMaterials', []);
|
|
324
|
-
newMetaDataEntry('selectedMaterialVariant', null);
|
|
325
|
-
newMetaDataEntry('selectedUserMeshPosition', {});
|
|
326
|
-
newMetaDataEntry('selectedUserCameraView', cameraSchema);
|
|
327
|
-
newMetaDataEntry('selectedOrthoView', '');
|
|
328
|
-
newMetaDataEntry('selectedRatio', ratios.broadcast);
|
|
329
|
-
newMetaDataEntry('screenshotData', '');
|
|
330
|
-
newMetaDataEntry('safeFrameEnabled', false);
|
|
331
|
-
newMetaDataEntry('selectedUserEnvironment', {
|
|
332
|
-
id: 'Default',
|
|
333
|
-
url: defaultEnvironment?.envURL
|
|
334
|
-
});
|
|
335
|
-
newMetaDataEntry('selectedSourceUnit', null);
|
|
336
|
-
newMetaDataEntry('selectedDisplayUnit', null);
|
|
337
|
-
newMetaDataEntry('meshChangeTracking', []);
|
|
338
|
-
newMetaDataEntry('globalTransforms', defaultGlobalTransforms);
|
|
339
|
-
newMetaDataEntry('viewportEnvironment', false);
|
|
340
|
-
newMetaDataEntry('viewportGround', true);
|
|
341
|
-
newMetaDataEntry('viewportAxes', true);
|
|
342
|
-
newMetaDataEntry('viewportShadows', mirrorGround.receiveShadows);
|
|
343
|
-
newMetaDataEntry('iblShadowPipelineEnabled', false);
|
|
344
|
-
newMetaDataEntry('fileName', null);
|
|
345
|
-
newMetaDataEntry('uvScaleLock', false);
|
|
346
|
-
newMetaDataEntry('lights', []);
|
|
347
|
-
};
|
|
348
|
-
const checkForRootNode = () => {
|
|
349
|
-
let rootNode = scene.getNodeById('__root__');
|
|
350
|
-
let node0 = rootNode?.getChildren()?.find?.((child, index) => child.name === node0Name && index === 0);
|
|
351
|
-
const isTransformNode = item => item?.getClassName() === 'TransformNode';
|
|
352
|
-
const userMeshes = getUserMeshes();
|
|
353
|
-
const userNodes = getUserNodes();
|
|
354
|
-
const topLevelUserNodes = userNodes.filter(node => node.parent === null);
|
|
355
|
-
const otherNode0Nodes = userNodes?.filter(node => node.name === node0Name && node.parent !== rootNode);
|
|
356
|
-
if (!rootNode) {
|
|
357
|
-
rootNode = new BABYLON.Mesh('__root__', scene);
|
|
358
|
-
rootNode.isPickable = false;
|
|
359
|
-
rootNode.isVisible = false;
|
|
360
|
-
rootNode.isBlocker = true;
|
|
361
|
-
rootNode.isPointerBlocker = true;
|
|
362
|
-
rootNode.isHitTestVisible = false;
|
|
363
|
-
}
|
|
364
|
-
if (!node0 || !isTransformNode(node0)) {
|
|
365
|
-
node0 = new BABYLON.TransformNode(node0Name, scene);
|
|
366
|
-
node0.isPickable = false;
|
|
367
|
-
node0.isVisible = false;
|
|
368
|
-
node0.isBlocker = true;
|
|
369
|
-
node0.isPointerBlocker = true;
|
|
370
|
-
node0.isHitTestVisible = false;
|
|
371
|
-
node0.parent = rootNode;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// NOTE: This renames all other node0's to avoid conflict with the main node0 for transformations etc.
|
|
375
|
-
if (!_.isEmpty(otherNode0Nodes)) {
|
|
376
|
-
otherNode0Nodes?.forEach((node, index) => node.name = `node0_(${index})`);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// NOTE: This handles correcting any third-party files that have __root__ and children
|
|
380
|
-
// but not node0, and makes sure everything is a child of the newly created node0.
|
|
381
|
-
rootNode.getChildren().forEach(child => {
|
|
382
|
-
const transformNode = isTransformNode(child);
|
|
383
|
-
const isNode0 = child.name === node0Name && transformNode;
|
|
384
|
-
const parentedToNode0 = child.parent.name === node0Name && transformNode;
|
|
385
|
-
const hasNode0AsChild = child.getChildren().find(node => node.name === node0Name);
|
|
386
|
-
if (!isNode0 && !parentedToNode0 && !hasNode0AsChild) {
|
|
387
|
-
child.setParent(node0);
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
// NOTE: This handles correcting any parentless user meshes from a third-party file and makes
|
|
392
|
-
// sure they are named with the prefix "mesh" and parented to node0.
|
|
393
|
-
userMeshes.forEach(mesh => {
|
|
394
|
-
if (mesh.name === node0Name && !isTransformNode(mesh)) mesh.name = 'mesh0';
|
|
395
|
-
if (mesh.parent === null) mesh.setParent(node0);
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
// NOTE: This handles correcting any parentless user nodes from a third-party file and makes
|
|
399
|
-
// sure they are parented to node0.
|
|
400
|
-
topLevelUserNodes?.forEach(node => node.setParent(node0));
|
|
401
|
-
|
|
402
|
-
// Clean up empty nodes after above normalization
|
|
403
|
-
rootNode.getChildren().forEach(child => {
|
|
404
|
-
const transformNode = isTransformNode(child);
|
|
405
|
-
const noChildren = child.getChildren().length === 0;
|
|
406
|
-
if (transformNode && noChildren) child.dispose();
|
|
407
|
-
});
|
|
408
|
-
};
|
|
409
|
-
export const initSceneFromFile = (sceneFromFile, fileName) => {
|
|
410
|
-
if (sceneFromFile) {
|
|
411
|
-
const preserveEngine = true;
|
|
412
|
-
cleanup(preserveEngine);
|
|
413
|
-
scene = sceneFromFile;
|
|
414
|
-
scene.useRightHandedSystem = false;
|
|
415
|
-
utilLayer = new BABYLON.UtilityLayerRenderer(scene, false);
|
|
416
|
-
window.removeEventListener(resize, resizeEngine);
|
|
417
|
-
window.addEventListener(resize, resizeEngine);
|
|
418
|
-
initListeners();
|
|
419
|
-
initSceneObjects();
|
|
420
|
-
modelToOrigin();
|
|
421
|
-
focusCamera();
|
|
422
|
-
const {
|
|
423
|
-
position,
|
|
424
|
-
rotation
|
|
425
|
-
} = scene.activeCamera;
|
|
426
|
-
const [tx, ty, tz] = [position.x, position.y, position.z];
|
|
427
|
-
const [rx, ry, rz] = [rotation.x, rotation.y, rotation.z];
|
|
428
|
-
const node0 = scene.getNodeByName(node0Name);
|
|
429
|
-
const defaultMeshPositions = buildMeshPositionsArray().map(positionData => {
|
|
430
|
-
return {
|
|
431
|
-
...positionData,
|
|
432
|
-
positionId: 'Default'
|
|
433
|
-
};
|
|
434
|
-
});
|
|
435
|
-
const globalsAfterSceneLoad = {
|
|
436
|
-
tx: node0?.position?.x || 0,
|
|
437
|
-
ty: node0?.position?.y || 0,
|
|
438
|
-
tz: node0?.position?.z || 0,
|
|
439
|
-
rx: node0?.rotation?.x || 0,
|
|
440
|
-
ry: node0?.rotation?.y || 0,
|
|
441
|
-
rz: node0?.rotation?.z || 0,
|
|
442
|
-
sx: node0?.scaling?.x || 1,
|
|
443
|
-
sy: node0?.scaling?.y || 1,
|
|
444
|
-
sz: node0?.scaling?.z || 1
|
|
445
|
-
};
|
|
446
|
-
warningChecks();
|
|
447
|
-
if (props.materialMode) tweakSceneForShaderball();
|
|
448
|
-
initMetadataKeyDefaults();
|
|
449
|
-
getStatisticsMetadata(props);
|
|
450
|
-
newMetaDataEntry('defaultCameraPosition', {
|
|
451
|
-
id: 'default',
|
|
452
|
-
tx,
|
|
453
|
-
ty,
|
|
454
|
-
tz,
|
|
455
|
-
rx,
|
|
456
|
-
ry,
|
|
457
|
-
rz
|
|
458
|
-
});
|
|
459
|
-
newMetaDataEntry('userMeshPositions', defaultMeshPositions);
|
|
460
|
-
newMetaDataEntry('selectedUserMeshPositions', buildMeshPositionsArray());
|
|
461
|
-
newMetaDataEntry('meshChangeTracking', buildMeshPositionsArray());
|
|
462
|
-
newMetaDataEntry('globalTransforms', globalsAfterSceneLoad);
|
|
463
|
-
newMetaDataEntry('materials', buildMaterialsArray());
|
|
464
|
-
newMetaDataEntry('selectedMaterials', buildSelectedMaterialArray());
|
|
465
|
-
newMetaDataEntry('fileName', fileName);
|
|
466
|
-
newMetaDataEntry('materialVariants', buildMaterialVariantsArray());
|
|
467
|
-
newMetaDataEntry('uvScaleLock', scene.metadata.uvScaleLock || false);
|
|
468
|
-
newMetaDataEntry('lights', buildLightsArray());
|
|
469
|
-
updatePublish(fileName ? {
|
|
470
|
-
payload: {
|
|
471
|
-
title: fileName
|
|
472
|
-
}
|
|
473
|
-
} : {});
|
|
474
|
-
props.setSerializedData?.(serializeScene());
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
const initListeners = () => {
|
|
478
|
-
shortcutArray = [];
|
|
479
|
-
if (!props.materialMode) {
|
|
480
|
-
const cameraShortcuts = Object.values(shortcuts.camera);
|
|
481
|
-
const viewportShortcuts = Object.values(shortcuts.viewport);
|
|
482
|
-
const modelShortcuts = Object.values(shortcuts.model);
|
|
483
|
-
const generalListeners = [...cameraShortcuts, ...viewportShortcuts, ...modelShortcuts];
|
|
484
|
-
shortcutArray = [...shortcutArray, ...generalListeners];
|
|
485
|
-
handleMouseListeners();
|
|
486
|
-
}
|
|
487
|
-
if (!props.materialMode && !props.previewMode) loadFromDragDrop();
|
|
488
|
-
if (!props.previewMode) {
|
|
489
|
-
const utilitiesShortcuts = Object.values(shortcuts.utilities);
|
|
490
|
-
const previewListeners = [...utilitiesShortcuts];
|
|
491
|
-
shortcutArray = [...shortcutArray, ...previewListeners];
|
|
492
|
-
}
|
|
493
|
-
handleShortcutListeners();
|
|
494
|
-
};
|
|
495
|
-
export const cleanup = preserveEngine => {
|
|
496
|
-
const remove = true;
|
|
497
|
-
handleShortcutListeners(remove);
|
|
498
|
-
props.setSerializedData?.(null);
|
|
499
|
-
removeAutoRotation();
|
|
500
|
-
window.removeEventListener(resize, resizeEngine);
|
|
501
|
-
if (!preserveEngine) {
|
|
502
|
-
engine?.dispose();
|
|
503
|
-
engine = null;
|
|
504
|
-
}
|
|
505
|
-
scene?.dispose();
|
|
506
|
-
scene = null;
|
|
507
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as BABYLON from 'babylonjs';
|
|
2
|
-
import { LIGHTS } from '../constants';
|
|
3
|
-
import { newVector, scene } from '../helpers';
|
|
4
|
-
export const newLight = (name, location, type, meta = {}) => {
|
|
5
|
-
const defaultName = `light_${getSceneLights().length + 1}`;
|
|
6
|
-
if (type === LIGHTS.SpotLight) {
|
|
7
|
-
const orientation = meta.orientation;
|
|
8
|
-
return new BABYLON.SpotLight(name || `${defaultName}_spot`, newVector(location.x, location.y, location.z), newVector(orientation.x, orientation.y, orientation.z), meta.angle, meta.exponent, scene);
|
|
9
|
-
}
|
|
10
|
-
if (type === LIGHTS.ShadowGenerator) {
|
|
11
|
-
return new BABYLON.ShadowGenerator(meta.mapSize, meta.dirLight || newLight(defaultName, newVector(location.x, location.y, location.z), LIGHTS.DirectionalLight));
|
|
12
|
-
}
|
|
13
|
-
if (LIGHTS[type] && typeof BABYLON[type] === 'function') {
|
|
14
|
-
return new BABYLON[type](name || defaultName, newVector(location.x, location.y, location.z), scene);
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
export const getSceneLights = () => scene.lights;
|