@archvisioninc/canvas 3.3.8 → 3.3.9

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.
@@ -0,0 +1,156 @@
1
+ import * as BABYLON from 'babylonjs';
2
+ import { MESH_PARAMS } from '../constants';
3
+ import { gizmoManager, multiMeshTNode, singleMeshTNode, scene, selectedMeshes, getParamOfSelectedMeshes, getUserMeshes, newVector, getBoundingMeshData, newStandardMaterial, addHighlightExclusion, restoreParents, newMetaDataEntry, serializeScene, buildMeshPositionsArray, toRadians } from '../helpers';
4
+ import { reactProps as props } from '../Canvas';
5
+ import _ from 'lodash';
6
+ let parentList = [];
7
+ let previousSingleNode = {};
8
+ export const newGizmoManager = () => {
9
+ const thickness = 1;
10
+ return new BABYLON.GizmoManager(scene, thickness);
11
+ };
12
+ export const cleanupGizmoAndTNodes = () => {
13
+ const singleAtRest = singleMeshTNode.position.equals(newVector(0, 0, 0));
14
+ const multiAtRest = multiMeshTNode.position.equals(newVector(0, 0, 0));
15
+ const resetNodes = type => {
16
+ const single = type === 'single';
17
+ const node = single ? singleMeshTNode : multiMeshTNode;
18
+ gizmoManager.attachToNode(null);
19
+ if (!_.isEmpty(parentList)) {
20
+ previousSingleNode = {};
21
+ if (single) previousSingleNode = singleMeshTNode.getChildren()[0];
22
+ restoreParents(parentList);
23
+ }
24
+ node.position = new BABYLON.Vector3(0, 0, 0);
25
+ parentList = [];
26
+ };
27
+ if (!singleAtRest) resetNodes('single');
28
+ if (!multiAtRest) resetNodes('multi');
29
+ };
30
+ export const attachToSelectMeshesNode = () => {
31
+ const singleSelection = selectedMeshes.length === 1;
32
+ const multiSelection = selectedMeshes.length > 1;
33
+ cleanupGizmoAndTNodes();
34
+ if (singleSelection) handleSingleMeshGizmo(selectedMeshes[0]);
35
+ if (multiSelection) handleMultiMeshGizmo();
36
+ };
37
+ export const handleSingleMeshGizmo = mesh => {
38
+ if (mesh) {
39
+ const meshCenter = getParamOfSelectedMeshes(MESH_PARAMS.center);
40
+ const isChildOfNode = previousSingleNode?.name === mesh.name;
41
+ const parent = mesh.parent;
42
+ const currentMeshTracking = scene.metadata.meshChangeTracking.find(trackedMesh => trackedMesh.meshId === mesh.id);
43
+ const radiansX = toRadians(currentMeshTracking?.rx);
44
+ const radiansY = toRadians(currentMeshTracking?.ry);
45
+ const radiansZ = toRadians(currentMeshTracking?.rz);
46
+ const newRotation = newVector(radiansX, radiansY, radiansZ);
47
+ parentList.push({
48
+ mesh,
49
+ parent
50
+ });
51
+ if (isChildOfNode) restoreParents(parentList);
52
+ singleMeshTNode.position = meshCenter;
53
+ singleMeshTNode.rotation = newRotation;
54
+ singleMeshTNode.scaling = newVector(1, 1, 1);
55
+ mesh.setParent(singleMeshTNode);
56
+ gizmoManager.attachToNode(singleMeshTNode);
57
+ }
58
+ };
59
+ export const handleMultiMeshGizmo = () => {
60
+ const meshCenter = getParamOfSelectedMeshes(MESH_PARAMS.center);
61
+ const meshScaling = getParamOfSelectedMeshes(MESH_PARAMS.scaling);
62
+ const meshRotation = getParamOfSelectedMeshes(MESH_PARAMS.rotation);
63
+ const nodeChildren = multiMeshTNode.getChildren();
64
+ getUserMeshes().forEach(mesh => {
65
+ const isChildOfNode = _.includes(nodeChildren, mesh);
66
+ const parent = mesh.parent;
67
+ parentList.push({
68
+ mesh,
69
+ parent
70
+ });
71
+ if (isChildOfNode) restoreParents(parentList);
72
+ });
73
+ multiMeshTNode.rotation = meshRotation;
74
+ multiMeshTNode.position = meshCenter;
75
+ multiMeshTNode.scaling = meshScaling;
76
+ selectedMeshes.forEach(mesh => mesh.setParent(multiMeshTNode));
77
+ gizmoManager.attachToNode(multiMeshTNode);
78
+ };
79
+ export const addInitialGizmoBehaviors = () => {
80
+ addBoundingBoxGizmoBehaviors();
81
+ addScalingGizmoBehaviors();
82
+ addPositionGizmoBehaviors();
83
+ addRotationGizmoBehaviors();
84
+ };
85
+ export const createBoundingMesh = () => {
86
+ const oldBoundingMesh = scene.getMeshById('boundingMesh');
87
+ oldBoundingMesh?.dispose();
88
+ const meshesToUse = !_.isEmpty(selectedMeshes) ? selectedMeshes : getUserMeshes();
89
+ const boundingRect = getBoundingMeshData(meshesToUse);
90
+ let boundingRectMaterial = scene.materials.find(mat => mat.name === 'boundingMaterial');
91
+ if (!boundingRectMaterial) boundingRectMaterial = newStandardMaterial('boundingMaterial');
92
+ const {
93
+ maximum,
94
+ minimum
95
+ } = boundingRect;
96
+ const height = maximum.y - minimum.y;
97
+ const width = maximum.x - minimum.x;
98
+ const depth = maximum.z - minimum.z;
99
+ const rectOptions = {
100
+ width,
101
+ height,
102
+ depth
103
+ };
104
+ let nodeLocation = getParamOfSelectedMeshes(MESH_PARAMS.center);
105
+ if (!_.isEmpty(selectedMeshes)) {
106
+ nodeLocation = selectedMeshes.length > 1 ? multiMeshTNode.position.clone() : singleMeshTNode.position.clone();
107
+ }
108
+ const boundingMesh = BABYLON.MeshBuilder.CreateBox('boundingMesh', rectOptions, scene);
109
+ boundingRectMaterial.alpha = 0;
110
+ boundingMesh.material = boundingRectMaterial;
111
+ boundingMesh.position = nodeLocation || newVector(1, 1, 1);
112
+ boundingMesh.isPickable = false;
113
+ boundingMesh.visibility = 0;
114
+ addHighlightExclusion(boundingMesh);
115
+ return boundingMesh;
116
+ };
117
+ export const addBoundingBoxGizmoBehaviors = () => {
118
+ gizmoManager.boundingBoxGizmoEnabled = true;
119
+ gizmoManager.onAttachedToNodeObservable.add(() => {
120
+ const boundingBoxEnabled = gizmoManager.boundingBoxGizmoEnabled;
121
+ const newBox = createBoundingMesh();
122
+ if (boundingBoxEnabled) gizmoManager.attachToMesh(newBox);
123
+ });
124
+ gizmoManager.boundingBoxGizmoEnabled = false;
125
+ };
126
+ const addScalingGizmoBehaviors = () => {
127
+ gizmoManager.scaleGizmoEnabled = true;
128
+ const scaleGizmo = gizmoManager.gizmos.scaleGizmo;
129
+ scaleGizmo.onDragEndObservable.add(() => {
130
+ attachToSelectMeshesNode();
131
+ createBoundingMesh();
132
+ newMetaDataEntry('meshChangeTracking', buildMeshPositionsArray());
133
+ props.setSerializedData?.(serializeScene());
134
+ });
135
+ gizmoManager.scaleGizmoEnabled = false;
136
+ };
137
+ const addPositionGizmoBehaviors = () => {
138
+ gizmoManager.positionGizmoEnabled = true;
139
+ const positionGizmo = gizmoManager.gizmos.positionGizmo;
140
+ positionGizmo.onDragEndObservable.add(() => {
141
+ createBoundingMesh();
142
+ newMetaDataEntry('meshChangeTracking', buildMeshPositionsArray());
143
+ props.setSerializedData?.(serializeScene());
144
+ });
145
+ gizmoManager.positionGizmoEnabled = false;
146
+ };
147
+ const addRotationGizmoBehaviors = () => {
148
+ gizmoManager.rotationGizmoEnabled = true;
149
+ const rotationGizmo = gizmoManager.gizmos.rotationGizmo;
150
+ rotationGizmo.onDragEndObservable.add(() => {
151
+ createBoundingMesh();
152
+ newMetaDataEntry('meshChangeTracking', buildMeshPositionsArray());
153
+ props.setSerializedData?.(serializeScene());
154
+ });
155
+ gizmoManager.rotationGizmoEnabled = false;
156
+ };
@@ -0,0 +1,46 @@
1
+ import * as BABYLONGUI from 'babylonjs-gui';
2
+ import { theme, $selectedTheme, guiTexture, canvas } from '../helpers';
3
+ import { GUI } from '../constants';
4
+ export const createSafeFrame = ratio => {
5
+ const buffer = 0.95;
6
+ const name = GUI.outerSafeFrame;
7
+ const safeFrame = new BABYLONGUI.Rectangle(name);
8
+ safeFrame.cornerRadius = 8;
9
+ safeFrame.thickness = 3;
10
+ safeFrame.alpha = 0.75;
11
+ safeFrame.color = theme.colors[$selectedTheme].accent;
12
+ safeFrame.background = 'transparent';
13
+ safeFrame.onBeforeDrawObservable.add(() => {
14
+ const isWidthGreater = canvas.clientWidth > canvas.clientHeight;
15
+ const canvasWidth = canvas.clientWidth;
16
+ const canvasHeight = canvas.clientHeight;
17
+ const canvasRatio = canvasWidth / canvasHeight;
18
+ let frameWidth = canvas.clientWidth / canvasRatio;
19
+ let frameHeight = canvas.clientHeight / canvasRatio;
20
+ let frameRatio = frameWidth / frameHeight;
21
+ const compensationMultiplier = ratio / frameRatio;
22
+ frameHeight /= compensationMultiplier;
23
+ frameRatio = frameWidth / frameHeight;
24
+ if (!isWidthGreater) {
25
+ frameWidth = canvas.clientWidth;
26
+ frameHeight = canvas.clientWidth / ratio;
27
+ }
28
+ safeFrame.widthInPixels = frameWidth * buffer;
29
+ safeFrame.heightInPixels = frameHeight * buffer;
30
+ });
31
+ guiTexture.addControl(safeFrame);
32
+ guiTexture.getControlByName(name).isVisible = false;
33
+ };
34
+ export const createDragSelectBox = () => {
35
+ const name = GUI.dragSelectBox;
36
+ const dragBox = new BABYLONGUI.Rectangle(name);
37
+ dragBox.cornerRadius = 5;
38
+ dragBox.thickness = 2;
39
+ dragBox.alpha = 0.75;
40
+ dragBox.color = theme.colors[$selectedTheme].accent;
41
+ dragBox.background = `${theme.colors[$selectedTheme].accent}25`;
42
+ dragBox.horizontalAlignment = BABYLONGUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
43
+ dragBox.verticalAlignment = BABYLONGUI.Control.VERTICAL_ALIGNMENT_TOP;
44
+ guiTexture.addControl(dragBox);
45
+ guiTexture.getControlByName(name).isVisible = false;
46
+ };
@@ -0,0 +1,16 @@
1
+ export * from './utilityHelpers';
2
+ export * from './initHelpers';
3
+ export * from './cameraHelpers';
4
+ export * from './shortcutHelpers';
5
+ export * from './viewportHelpers';
6
+ export * from './lightHelpers';
7
+ export * from './meshHelpers';
8
+ export * from './materialHelpers';
9
+ export * from './guiHelpers';
10
+ export * from './rayHelpers';
11
+ export * from './gizmoHelpers';
12
+ export * from './loadHelpers';
13
+ export * from './canvasUpdateHelpers';
14
+ export * from './canvasAddHelpers';
15
+ export * from './canvasRemoveHelpers';
16
+ export * from './canvasCommunicationHelpers';