architwin 1.12.5 → 1.13.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.
Files changed (39) hide show
  1. package/CORE_FEATURES.md +35 -0
  2. package/lib/architwin.d.ts +96 -5
  3. package/lib/architwin.js +1 -1
  4. package/lib/atwinui/components/toolbar/collapse.d.ts +18 -0
  5. package/lib/atwinui/components/toolbar/collapse.js +62 -0
  6. package/lib/atwinui/components/toolbar/i18n.js +52 -2
  7. package/lib/atwinui/components/toolbar/index.js +11 -1
  8. package/lib/atwinui/components/toolbar/menuBar.d.ts +1 -0
  9. package/lib/atwinui/components/toolbar/menuBar.js +11 -0
  10. package/lib/atwinui/components/toolbar/pipeFormPane.d.ts +31 -0
  11. package/lib/atwinui/components/toolbar/pipeFormPane.js +545 -0
  12. package/lib/atwinui/components/toolbar/pipeListPane.d.ts +19 -0
  13. package/lib/atwinui/components/toolbar/pipeListPane.js +388 -0
  14. package/lib/atwinui/components/toolbar/spaceUserListPane.d.ts +3 -0
  15. package/lib/atwinui/components/toolbar/spaceUserListPane.js +95 -0
  16. package/lib/atwinui/components/toolbar/tagIotForm.d.ts +20 -0
  17. package/lib/atwinui/components/toolbar/tagIotForm.js +391 -0
  18. package/lib/atwinui/components/toolbar/tagIotFormPane.d.ts +62 -0
  19. package/lib/atwinui/components/toolbar/tagIotFormPane.js +606 -0
  20. package/lib/atwinui/components/toolbar/usersPane.d.ts +14 -0
  21. package/lib/atwinui/components/toolbar/usersPane.js +273 -0
  22. package/lib/atwinui/components/toolbar/viewingRemoteSpace.d.ts +7 -0
  23. package/lib/atwinui/components/toolbar/viewingRemoteSpace.js +77 -0
  24. package/lib/atwinui/events.d.ts +4 -1
  25. package/lib/atwinui/events.js +76 -13
  26. package/lib/atwinui/helpers.d.ts +15 -0
  27. package/lib/atwinui/helpers.js +49 -0
  28. package/lib/atwinui/index.js +2 -0
  29. package/lib/loaders/curosrMarkerLoader.d.ts +25 -0
  30. package/lib/loaders/curosrMarkerLoader.js +86 -0
  31. package/lib/loaders/index.d.ts +2 -1
  32. package/lib/loaders/index.js +2 -1
  33. package/lib/loaders/pathLoader.d.ts +99 -0
  34. package/lib/loaders/pathLoader.js +451 -0
  35. package/lib/types.d.ts +79 -1
  36. package/lib/types.js +34 -0
  37. package/package.json +1 -1
  38. package/static/atwinui.css +263 -0
  39. package/static/utility.css +81 -1
@@ -0,0 +1,86 @@
1
+ import { _mpConfig } from "../architwin";
2
+ // Default asset path (overridden if bundlePath is present in config)
3
+ let _staticAssetPath = '../';
4
+ class CursorMarkerLoader {
5
+ constructor(mpConfig) {
6
+ // === Inputs ===
7
+ this.inputs = {
8
+ pointerIntersection: null,
9
+ markerTexture: null,
10
+ visible: true,
11
+ offset: 0.05,
12
+ scale: 1 // Marker scale multiplier
13
+ };
14
+ // === Initialization ===
15
+ this.onInit = () => {
16
+ console.log('🛠️ CursorMarkerLoader on init', this.inputs.pointerIntersection);
17
+ const THREE = this.context.three;
18
+ if (!this.inputs.pointerIntersection)
19
+ return;
20
+ // Extract position and surface normal from intersection data
21
+ const { position: coord, normal: _normal } = this.inputs.pointerIntersection;
22
+ // Normalize the surface normal
23
+ const normal = new THREE.Vector3(_normal.x, _normal.y, _normal.z).normalize();
24
+ // === Generate rotation quaternion to align marker with surface ===
25
+ // Build a tangent-bitangent-normal (TBN) basis from surface normal
26
+ const up = new THREE.Vector3(0, 0, 1);
27
+ const tangent = new THREE.Vector3().crossVectors(new THREE.Vector3(1, 0, 0), normal).normalize();
28
+ const bitangent = new THREE.Vector3().crossVectors(normal, tangent).normalize();
29
+ const matrix = new THREE.Matrix4().makeBasis(tangent, bitangent, normal);
30
+ // Create quaternion from basis matrix and align Z-up to normal
31
+ const quaternion = new THREE.Quaternion().setFromRotationMatrix(matrix);
32
+ quaternion.setFromUnitVectors(up, normal);
33
+ // Convert to Euler angles for use with Three.js transforms
34
+ const euler = new THREE.Euler().setFromQuaternion(quaternion);
35
+ // Apply offset to position to move slightly off the surface
36
+ const adjustedPosition = new THREE.Vector3(coord.x + normal.x * this.inputs.offset, coord.y + normal.y * this.inputs.offset, coord.z + normal.z * this.inputs.offset);
37
+ // Marker texture fallback
38
+ const markerUrl = this.inputs.markerTexture || `${_staticAssetPath}static/objective.png`;
39
+ // === Load texture and build the marker plane ===
40
+ const loader = new THREE.TextureLoader();
41
+ loader.load(markerUrl, (texture) => {
42
+ this.texture = texture;
43
+ // Define geometry and material for the flat marker plane
44
+ this.geometry = new THREE.PlaneGeometry(0.1, 0.1);
45
+ this.material = new THREE.MeshBasicMaterial({
46
+ map: texture,
47
+ transparent: false,
48
+ opacity: 1,
49
+ side: THREE.DoubleSide,
50
+ });
51
+ // Create the mesh
52
+ this.mesh = new THREE.Mesh(this.geometry, this.material);
53
+ this.mesh.position.copy(adjustedPosition);
54
+ this.mesh.rotation.set(euler.x, euler.y, euler.z);
55
+ this.mesh.name = 'cursorMarker';
56
+ this.mesh.visible = this.inputs.visible;
57
+ // Register output so it can be used as a collider/interactable object
58
+ this.outputs.objectRoot = this.mesh;
59
+ this.outputs.collider = this.mesh;
60
+ console.log('🛠️ CursorMarkerLoader on loader.load', texture);
61
+ });
62
+ };
63
+ // === Triggered when inputs change ===
64
+ this.onInputsUpdated = () => {
65
+ console.log('🛠️ CursorMarkerLoader inputupdated');
66
+ this.onInit();
67
+ };
68
+ // === Cleanup for memory management ===
69
+ this.onDestroy = () => {
70
+ var _a, _b, _c;
71
+ console.log('🛠️ CursorMarkerLoader destroy');
72
+ (_a = this.geometry) === null || _a === void 0 ? void 0 : _a.dispose();
73
+ (_b = this.material) === null || _b === void 0 ? void 0 : _b.dispose();
74
+ (_c = this.texture) === null || _c === void 0 ? void 0 : _c.dispose();
75
+ };
76
+ console.log('🛠️ CursorMarkerLoader constructor called');
77
+ this.outputs = {};
78
+ // Override static asset path if deployed via CDN
79
+ if ('bundlePath' in mpConfig) {
80
+ _staticAssetPath = 'https://cdn.jsdelivr.net/npm/architwin@latest/';
81
+ }
82
+ }
83
+ }
84
+ // === Factory and Component Type ===
85
+ export const cursorMarkerType = 'mp.cursorMarker';
86
+ export const cursorMarkerFactory = () => new CursorMarkerLoader(_mpConfig);
@@ -9,4 +9,5 @@ import { sweepPuckType, puckBackgroundFactory } from "./sweepPuckLoader";
9
9
  import { viewpointType, viewpointFactory } from "./viewpointLoader";
10
10
  import { tubeLineType, tubeLineFactory, verticeType, verticeFactory, bufferGeometryType, bufferGeometry } from "./polydrawerLoader";
11
11
  import { fbxType, fbxFactory } from "./fbxLoader";
12
- export { planeType, planeFactory, planeTypeImage, planeTypeVideo, planeTypePdf, setHudState, planeImageFactory, planeVideoFactory, planePdfFactory, gltfType, gltfFactory, boxType, boxFactory, textType, textFactory, css3DType, css3DFactory, hudType, hudFactory, sweepPuckType, puckBackgroundFactory, viewpointType, viewpointFactory, tubeLineType, tubeLineFactory, verticeType, verticeFactory, bufferGeometryType, bufferGeometry, fbxType, fbxFactory };
12
+ import { pathPointType, pathPointFactory, pathLineType, pathLineFactory } from "./pathLoader";
13
+ export { planeType, planeFactory, planeTypeImage, planeTypeVideo, planeTypePdf, setHudState, planeImageFactory, planeVideoFactory, planePdfFactory, gltfType, gltfFactory, boxType, boxFactory, textType, textFactory, css3DType, css3DFactory, hudType, hudFactory, sweepPuckType, puckBackgroundFactory, viewpointType, viewpointFactory, tubeLineType, tubeLineFactory, verticeType, verticeFactory, bufferGeometryType, bufferGeometry, fbxType, fbxFactory, pathPointType, pathPointFactory, pathLineType, pathLineFactory };
@@ -9,6 +9,7 @@ import { sweepPuckType, puckBackgroundFactory } from "./sweepPuckLoader";
9
9
  import { viewpointType, viewpointFactory } from "./viewpointLoader";
10
10
  import { tubeLineType, tubeLineFactory, verticeType, verticeFactory, bufferGeometryType, bufferGeometry } from "./polydrawerLoader";
11
11
  import { fbxType, fbxFactory } from "./fbxLoader";
12
+ import { pathPointType, pathPointFactory, pathLineType, pathLineFactory } from "./pathLoader";
12
13
  export {
13
14
  // planeType,planeFactory,
14
- planeType, planeFactory, planeTypeImage, planeTypeVideo, planeTypePdf, setHudState, planeImageFactory, planeVideoFactory, planePdfFactory, gltfType, gltfFactory, boxType, boxFactory, textType, textFactory, css3DType, css3DFactory, hudType, hudFactory, sweepPuckType, puckBackgroundFactory, viewpointType, viewpointFactory, tubeLineType, tubeLineFactory, verticeType, verticeFactory, bufferGeometryType, bufferGeometry, fbxType, fbxFactory };
15
+ planeType, planeFactory, planeTypeImage, planeTypeVideo, planeTypePdf, setHudState, planeImageFactory, planeVideoFactory, planePdfFactory, gltfType, gltfFactory, boxType, boxFactory, textType, textFactory, css3DType, css3DFactory, hudType, hudFactory, sweepPuckType, puckBackgroundFactory, viewpointType, viewpointFactory, tubeLineType, tubeLineFactory, verticeType, verticeFactory, bufferGeometryType, bufferGeometry, fbxType, fbxFactory, pathPointType, pathPointFactory, pathLineType, pathLineFactory };
@@ -0,0 +1,99 @@
1
+ import { MpSdk } from "../../bundle/sdk";
2
+ import { Pane } from 'tweakpane';
3
+ export declare class PathLine {
4
+ mpSdk: MpSdk;
5
+ mesh: THREE.Mesh;
6
+ material: THREE.Material;
7
+ geometry: THREE.BufferGeometry;
8
+ texture: THREE.CanvasTexture;
9
+ tubeGeometry: THREE.TubeGeometry;
10
+ time: number;
11
+ closed: boolean;
12
+ panel: Pane;
13
+ billboard: string;
14
+ hovered: boolean;
15
+ length: number;
16
+ groupedMesh: THREE.Group;
17
+ constructor(mpSdk: MpSdk);
18
+ inputs: {
19
+ name: string;
20
+ label: string;
21
+ description: string;
22
+ node: any;
23
+ tubes: any;
24
+ path: any;
25
+ enabled: boolean;
26
+ active: boolean;
27
+ editMode: boolean;
28
+ direction: number;
29
+ curveType: string;
30
+ opacity: number;
31
+ tubularSegments: number;
32
+ radialSegments: number;
33
+ fillColor: string;
34
+ textColor: string;
35
+ text: string;
36
+ font: string;
37
+ radius: number;
38
+ scrollSpeed: number;
39
+ collider: boolean;
40
+ visible: boolean;
41
+ pathOptions: any;
42
+ };
43
+ outputs: Record<string, unknown> & MpSdk.Scene.PredefinedOutputs;
44
+ context: MpSdk.Scene.IComponentContext;
45
+ emits: {
46
+ active: boolean;
47
+ destroyed: boolean;
48
+ };
49
+ events: {
50
+ 'INTERACTION.CLICK': boolean;
51
+ 'INTERACTION.HOVER': boolean;
52
+ };
53
+ onInit: () => void;
54
+ onInputsUpdated: (prevInputs: any) => void;
55
+ renderPathLine: () => void;
56
+ setBillboard: (value: any) => void;
57
+ onEvent(eventType: any, data: any): void;
58
+ onTick(tickDelta: any): void;
59
+ renderGUI: () => void;
60
+ onDestroy(): void;
61
+ }
62
+ export declare const pathLineType = "pathLine";
63
+ export declare const pathLineFactory: (mpSdk: MpSdk) => () => PathLine;
64
+ export declare class PathPoint {
65
+ mpSdk: MpSdk;
66
+ mesh: THREE.Mesh;
67
+ material: THREE.Material;
68
+ geometry: THREE.BufferGeometry;
69
+ texture: THREE.CanvasTexture;
70
+ pointerSub: MpSdk.ISubscription;
71
+ pointerIntersection: MpSdk.Pointer.Intersection;
72
+ constructor(mpSdk: MpSdk);
73
+ inputs: {
74
+ index: any;
75
+ radius: number;
76
+ position: any;
77
+ fillColor: string;
78
+ hoverColor: string;
79
+ ringVisibility: boolean;
80
+ };
81
+ outputs: Record<string, unknown> & MpSdk.Scene.PredefinedOutputs;
82
+ context: MpSdk.Scene.IComponentContext;
83
+ emits: {
84
+ active: boolean;
85
+ changed: boolean;
86
+ };
87
+ events: {
88
+ 'INTERACTION.DRAG': boolean;
89
+ 'INTERACTION.DRAG_BEGIN': boolean;
90
+ 'INTERACTION.DRAG_END': boolean;
91
+ 'INTERACTION.HOVER': boolean;
92
+ };
93
+ onInputsUpdated: (prevInputs: any) => void;
94
+ onEvent(eventType: any, data: any): void;
95
+ onInit: () => void;
96
+ renderVertice: (hovered?: boolean) => void;
97
+ }
98
+ export declare const pathPointType = "pathPoint";
99
+ export declare const pathPointFactory: (mpSdk: any) => () => PathPoint;
@@ -0,0 +1,451 @@
1
+ import { Pane } from 'tweakpane';
2
+ import { dispatchSpaceEvent } from "../architwin";
3
+ import { SPACE_EVENTS } from "../types";
4
+ export class PathLine {
5
+ constructor(mpSdk) {
6
+ this.time = 0;
7
+ this.closed = false;
8
+ this.billboard = undefined;
9
+ this.hovered = false;
10
+ this.length = 0;
11
+ this.inputs = {
12
+ name: '',
13
+ label: 'Path Line',
14
+ description: '',
15
+ node: null,
16
+ tubes: null,
17
+ path: null,
18
+ enabled: true,
19
+ active: false,
20
+ editMode: false,
21
+ direction: -1,
22
+ curveType: 'catmullrom',
23
+ opacity: 0.3,
24
+ tubularSegments: 100,
25
+ radialSegments: 20,
26
+ fillColor: 'none',
27
+ textColor: 'rgb(255,255,255)',
28
+ text: '➡︎',
29
+ font: '48px sans-serif',
30
+ radius: 0.05,
31
+ scrollSpeed: 1.35,
32
+ collider: true,
33
+ visible: true,
34
+ pathOptions: null
35
+ };
36
+ //@ts-expect-error
37
+ this.outputs = {
38
+ length: 0,
39
+ gui: {},
40
+ };
41
+ this.emits = {
42
+ active: true,
43
+ destroyed: true,
44
+ };
45
+ this.events = {
46
+ 'INTERACTION.CLICK': true,
47
+ 'INTERACTION.HOVER': false,
48
+ };
49
+ this.onInit = () => {
50
+ const THREE = this.context.three;
51
+ this.groupedMesh = new THREE.Group();
52
+ if (this.inputs.active) {
53
+ //this.renderGUI();
54
+ }
55
+ if (this.inputs.path.length > 1) {
56
+ this.renderPathLine();
57
+ }
58
+ };
59
+ this.onInputsUpdated = (prevInputs) => {
60
+ if (this.inputs !== prevInputs) {
61
+ const THREE = this.context.three;
62
+ this.groupedMesh = new THREE.Group();
63
+ if (!this.inputs.active && this.panel) {
64
+ this.panel.dispose();
65
+ //@ts-expect-error
66
+ this.panel = false;
67
+ }
68
+ else {
69
+ if (!this.panel || this.inputs.label !== prevInputs.label) {
70
+ //console.log('Rendering GUI...');
71
+ // this.renderGUI();
72
+ }
73
+ }
74
+ if (this.inputs.pathOptions) {
75
+ const excludedKeys = ['id', 'pathOptions'];
76
+ for (let key in this.inputs) {
77
+ if (!excludedKeys.includes(key)) {
78
+ if (this.inputs.pathOptions[key]) {
79
+ this.inputs[key] = this.inputs.pathOptions[key];
80
+ }
81
+ }
82
+ }
83
+ }
84
+ if (this.inputs.path.length > 1) {
85
+ this.renderPathLine();
86
+ console.log("paths ", this.inputs.path);
87
+ }
88
+ }
89
+ };
90
+ this.renderPathLine = () => {
91
+ const THREE = this.context.three;
92
+ // Find Length
93
+ let sections = this.inputs.path.length - 1;
94
+ this.length = 0;
95
+ for (let i = 0; i < sections; i++) {
96
+ const start = new THREE.Vector3(this.inputs.path[i].x, this.inputs.path[i].y, this.inputs.path[i].z);
97
+ const end = new THREE.Vector3(this.inputs.path[i + 1].x, this.inputs.path[i + 1].y, this.inputs.path[i + 1].z);
98
+ this.length += start.distanceTo(end);
99
+ }
100
+ const ctx = document.createElement('canvas').getContext('2d');
101
+ if (!ctx) {
102
+ return;
103
+ }
104
+ ctx.canvas.width = 64;
105
+ ctx.canvas.height = 64;
106
+ if (this.inputs.fillColor == 'none') {
107
+ ctx.clearRect(0, 0, 64, 64);
108
+ }
109
+ else {
110
+ // background
111
+ let fillColorRGBA = this.inputs.fillColor.replace(/rgb/i, 'rgba');
112
+ fillColorRGBA = fillColorRGBA.replace(/\)/i, ',' + (this.hovered ? 0.9 : this.inputs.opacity) + ')');
113
+ ctx.fillStyle = fillColorRGBA;
114
+ ctx.fillRect(0, 0, 64, 64);
115
+ }
116
+ // render out text measurement in the rendered line
117
+ ctx.translate(32, 32);
118
+ ctx.fillStyle = this.inputs.textColor;
119
+ ctx.textAlign = 'center';
120
+ ctx.textBaseline = 'middle';
121
+ ctx.font = this.inputs.font;
122
+ ctx.fillText(this.inputs.text, 0, 0);
123
+ this.texture = new THREE.CanvasTexture(ctx.canvas);
124
+ this.texture.wrapS = THREE.RepeatWrapping;
125
+ this.texture.wrapT = THREE.RepeatWrapping;
126
+ this.texture.repeat.set(this.length, 3);
127
+ this.material = new THREE.MeshBasicMaterial({
128
+ map: this.texture,
129
+ side: THREE.DoubleSide,
130
+ depthWrite: false,
131
+ depthTest: true,
132
+ transparent: true,
133
+ //@ts-expect-error
134
+ flatShading: true,
135
+ emissive: 0x072534,
136
+ });
137
+ if (this.inputs.path !== null) {
138
+ this.tubeGeometry && this.tubeGeometry.dispose();
139
+ this.tubeGeometry = new THREE.TubeGeometry(new THREE.CatmullRomCurve3(this.inputs.path, false,
140
+ //@ts-expect-error
141
+ this.inputs.curveType, this.inputs.curveType == 'catmullrom' ? 0.25 : 0), this.inputs.tubularSegments, // tubularSegments
142
+ this.inputs.radius, this.inputs.radialSegments, // radialSegments
143
+ this.closed // closed
144
+ );
145
+ this.mesh = new THREE.Mesh(this.tubeGeometry, this.material);
146
+ }
147
+ this.mesh.name = this.inputs.name;
148
+ this.outputs.length = this.length;
149
+ this.groupedMesh.add(this.mesh);
150
+ this.mesh.visible = this.inputs.visible;
151
+ if (this.inputs.enabled) {
152
+ this.outputs.objectRoot = this.mesh;
153
+ this.outputs.collider = this.inputs.collider ? this.mesh : null;
154
+ }
155
+ else {
156
+ this.outputs.objectRoot = null;
157
+ this.outputs.collider = null;
158
+ }
159
+ if (this.panel) {
160
+ this.panel.refresh();
161
+ }
162
+ dispatchSpaceEvent(SPACE_EVENTS.PATH_UPDATED, {
163
+ path: this.inputs.path,
164
+ textColor: this.inputs.textColor
165
+ });
166
+ };
167
+ this.setBillboard = (value) => {
168
+ this.billboard = value;
169
+ };
170
+ //This is just a temp gui I need for debugging and experimentation purposes. Will be commented out once I am done
171
+ this.renderGUI = () => {
172
+ if (this.panel) {
173
+ this.panel.dispose();
174
+ }
175
+ this.panel = new Pane({
176
+ //width: 260,
177
+ title: 'Scrolling Tube Creator',
178
+ container: document.getElementById('objgui'),
179
+ });
180
+ const tab = this.panel.addTab({
181
+ pages: [{ title: 'Edit' }, { title: 'All Drawings' }],
182
+ });
183
+ const folder1 = tab.pages[0].addFolder({ title: 'Inputs' });
184
+ folder1.addBinding(this.inputs, 'name');
185
+ folder1.addBinding(this.inputs, 'label');
186
+ folder1.addBinding(this.inputs, 'description', {
187
+ readonly: false,
188
+ multiline: true,
189
+ rows: 5,
190
+ });
191
+ folder1.addBinding(this.inputs, 'text', {
192
+ options: { ' ': ' ', '➡︎': '➡︎', '✳': '✳', '☠': '☠' },
193
+ });
194
+ folder1.addBinding(this.inputs, 'textColor');
195
+ folder1.addBinding(this.inputs, 'fillColor');
196
+ folder1.addBinding(this.inputs, 'direction', {
197
+ options: { 'Left to Right': -1, 'Right to Left': 1 },
198
+ });
199
+ folder1.addBinding(this.outputs, 'length', {
200
+ readonly: true,
201
+ });
202
+ // If the node was passed as an input, we can run node.destroy();
203
+ if (this.inputs.node) {
204
+ const remove = folder1.addButton({ title: 'Remove', label: 'Remove' });
205
+ remove.on('click', () => {
206
+ //@ts-expect-error
207
+ this.notify('destroyed');
208
+ this.panel.dispose();
209
+ //@ts-expect-error
210
+ this.panel = false;
211
+ this.inputs.active = false;
212
+ this.inputs.node.stop();
213
+ });
214
+ }
215
+ const folder2 = tab.pages[0].addFolder({
216
+ title: 'Advanced',
217
+ expanded: true,
218
+ });
219
+ folder2.addBinding(this.inputs, 'enabled');
220
+ folder2.addBinding(this.inputs, 'opacity', { min: 0, max: 1, step: 0.05 });
221
+ folder2.addBinding(this.inputs, 'radius', {
222
+ min: 0.01,
223
+ max: 1,
224
+ step: 0.01,
225
+ });
226
+ folder2.addBinding(this.inputs, 'scrollSpeed', {
227
+ min: 0,
228
+ max: 5,
229
+ step: 0.05,
230
+ });
231
+ folder2.addBinding(this.inputs, 'tubularSegments', {
232
+ min: 1,
233
+ max: 100,
234
+ step: 1,
235
+ });
236
+ folder2.addBinding(this.inputs, 'radialSegments', {
237
+ min: 1,
238
+ max: 20,
239
+ step: 1,
240
+ });
241
+ folder2.addBinding(this.inputs, 'collider');
242
+ if (this.inputs.tubes !== null) {
243
+ const nodeIterator = this.inputs.tubes.nodeIterator();
244
+ let nodes = nodeIterator.next();
245
+ while (!nodes.done) {
246
+ const componentIterator = nodes.value.componentIterator();
247
+ let component = componentIterator.next();
248
+ nodes = nodeIterator.next();
249
+ const button = tab.pages[1].addButton({
250
+ title: component.value.inputs.label,
251
+ label: '=',
252
+ });
253
+ button.on('click', (data) => {
254
+ // This needs to be reviewed
255
+ if (!component.value.inputs.active) {
256
+ //@ts-expect-error
257
+ this.notify('active', { component: component.value });
258
+ }
259
+ });
260
+ }
261
+ }
262
+ };
263
+ this.mpSdk = mpSdk;
264
+ }
265
+ onEvent(eventType, data) {
266
+ if (eventType === 'INTERACTION.CLICK') {
267
+ //@ts-expect-error
268
+ this.notify('active', { component: this });
269
+ // Show a Tag Billboard with the info of this tube
270
+ if (!this.billboard) {
271
+ // Allow access to these variables within then callbacks.
272
+ var mpSdk = this.mpSdk;
273
+ mpSdk.Tag.toggleNavControls(false);
274
+ mpSdk.Tag.add({
275
+ label: this.inputs.label,
276
+ description: this.inputs.description +
277
+ ' - ' +
278
+ Math.round(this.length * 1000) / 1000 +
279
+ 'm',
280
+ anchorPosition: {
281
+ x: data.point.x,
282
+ y: data.point.y,
283
+ z: data.point.z,
284
+ },
285
+ stemVector: {
286
+ x: 0,
287
+ y: 0,
288
+ z: 0,
289
+ },
290
+ }).then((tags) => {
291
+ this.setBillboard(tags[0]);
292
+ mpSdk.Tag.allowAction(tags[0], {
293
+ opening: true,
294
+ navigating: true,
295
+ });
296
+ mpSdk.Tag.editOpacity(tags[0], 0);
297
+ mpSdk.Tag.open(tags[0]).then(() => {
298
+ let tagDestroyer = mpSdk.Tag.openTags.subscribe((newState) => {
299
+ if (newState.selected.size == 0) {
300
+ let thisTag = newState.selected;
301
+ //@ts-expect-error
302
+ if (thisTag != tags[0]) {
303
+ mpSdk.Tag.remove(tags[0]);
304
+ tagDestroyer.cancel();
305
+ this.setBillboard(false);
306
+ mpSdk.Tag.toggleNavControls(true);
307
+ }
308
+ }
309
+ });
310
+ });
311
+ });
312
+ }
313
+ }
314
+ }
315
+ onTick(tickDelta) {
316
+ if (this.inputs.scrollSpeed > 0) {
317
+ this.time += tickDelta;
318
+ if (this.texture) {
319
+ this.texture.offset.x =
320
+ (this.inputs.direction *
321
+ ((this.inputs.scrollSpeed * this.time) / 1000)) %
322
+ 1;
323
+ }
324
+ }
325
+ }
326
+ onDestroy() {
327
+ this.texture.dispose();
328
+ if (this.panel) {
329
+ this.panel.dispose();
330
+ //@ts-expect-error
331
+ this.panel = false;
332
+ }
333
+ if (this.billboard) {
334
+ this.mpSdk.Tag.remove(this.billboard);
335
+ console.log('Nav Controls On');
336
+ this.mpSdk.Tag.toggleNavControls(true);
337
+ }
338
+ }
339
+ }
340
+ export const pathLineType = 'pathLine';
341
+ export const pathLineFactory = function (mpSdk) {
342
+ return function () {
343
+ return new PathLine(mpSdk);
344
+ };
345
+ };
346
+ export class PathPoint {
347
+ constructor(mpSdk) {
348
+ this.inputs = {
349
+ index: null,
350
+ radius: 0.05,
351
+ position: null,
352
+ fillColor: 'rgb(11,57,72)',
353
+ hoverColor: 'rgb(255,0,0)',
354
+ ringVisibility: false
355
+ };
356
+ this.emits = {
357
+ active: true,
358
+ changed: true,
359
+ };
360
+ this.events = {
361
+ 'INTERACTION.DRAG': true,
362
+ 'INTERACTION.DRAG_BEGIN': true,
363
+ 'INTERACTION.DRAG_END': true,
364
+ 'INTERACTION.HOVER': true,
365
+ };
366
+ this.onInputsUpdated = (prevInputs) => {
367
+ this.renderVertice(false);
368
+ };
369
+ this.onInit = () => {
370
+ this.renderVertice();
371
+ };
372
+ this.renderVertice = (hovered = false) => {
373
+ const THREE = this.context.three;
374
+ const group = new THREE.Group();
375
+ //This is just a visual marker so that the user can see the points they have already marked
376
+ this.geometry = new THREE.SphereGeometry(this.inputs.radius, 16, 16);
377
+ this.material = new THREE.MeshBasicMaterial({
378
+ color: (hovered ? this.inputs.hoverColor : this.inputs.fillColor),
379
+ transparent: true,
380
+ opacity: 0.6,
381
+ });
382
+ this.mesh = new THREE.Mesh(this.geometry, this.material);
383
+ this.mesh.position.set(this.inputs.position.x, this.inputs.position.y, this.inputs.position.z);
384
+ this.outputs.objectRoot = this.mesh;
385
+ this.outputs.collider = this.mesh;
386
+ };
387
+ this.mpSdk = mpSdk;
388
+ }
389
+ onEvent(eventType, data) {
390
+ var _a;
391
+ if (eventType === 'INTERACTION.DRAG') {
392
+ //this.pointerIntersection.object === 'intersectedobject.model'
393
+ //this.pointerIntersection.object
394
+ console.log("group this.pointerIntersection ", this.pointerIntersection);
395
+ if (this.pointerIntersection.object === 'intersectedobject.model') {
396
+ let e = Object.assign({}, this.pointerIntersection.position);
397
+ this.mesh.position.set(e.x, e.y, e.z);
398
+ //this.mesh.children[0].position.set(e.x, e.y, e.z)
399
+ //@ts-expect-error
400
+ this.notify('changed', {
401
+ index: this.inputs.index,
402
+ position: this.mesh.position,
403
+ collider: null,
404
+ });
405
+ }
406
+ }
407
+ if (eventType === 'INTERACTION.DRAG_BEGIN') {
408
+ this.mpSdk.Pointer.setVisible(false);
409
+ //@ts-expect-error
410
+ this.mesh.material.opacity = 0.5;
411
+ //this.mesh.children[0].material.opacity = 0.5
412
+ // will make it smaller later. Setting this to 0.5 to make it easier to see in the space
413
+ this.mesh.scale.set(0.5, 0.5, 0.5);
414
+ if (this.pointerSub == null) {
415
+ this.pointerSub = this.mpSdk.Pointer.intersection.subscribe((data) => {
416
+ this.pointerIntersection = data;
417
+ });
418
+ }
419
+ //@ts-expect-error
420
+ this.notify('changed', {
421
+ index: this.inputs.index,
422
+ position: this.mesh.position,
423
+ collider: false,
424
+ });
425
+ }
426
+ if (eventType === 'INTERACTION.DRAG_END') {
427
+ //@ts-expect-error
428
+ this.mesh.material.opacity = 1;
429
+ this.mesh.scale.set(1, 1, 1);
430
+ this.mpSdk.Pointer.setVisible(true);
431
+ (_a = this.pointerSub) === null || _a === void 0 ? void 0 : _a.cancel();
432
+ //renderPolygonFromPath()
433
+ //@ts-expect-error
434
+ this.notify('changed', {
435
+ index: this.inputs.index,
436
+ position: this.mesh.position,
437
+ collider: false,
438
+ });
439
+ dispatchSpaceEvent(SPACE_EVENTS.VERTEX_DRAG_END, {
440
+ index: this.inputs.index,
441
+ position: this.mesh.position
442
+ });
443
+ }
444
+ }
445
+ }
446
+ export const pathPointType = 'pathPoint';
447
+ export const pathPointFactory = function (mpSdk) {
448
+ return function () {
449
+ return new PathPoint(mpSdk);
450
+ };
451
+ };