@smarterplan/ngx-smarterplan-core 1.4.15 → 1.4.17

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 (107) hide show
  1. package/README.md +24 -24
  2. package/esm2022/lib/components/csv-export/csv-export.component.mjs +3 -3
  3. package/esm2022/lib/components/loader/loader.component.mjs +3 -3
  4. package/esm2022/lib/components/menu-bar/avatar/avatar.component.mjs +1 -1
  5. package/esm2022/lib/components/menu-bar/menu-bar.component.mjs +3 -3
  6. package/esm2022/lib/components/menu-bar/navigation-bar/navigation-bar.component.mjs +3 -3
  7. package/esm2022/lib/components/modal-switch-visit/modal-switch-visit.component.mjs +3 -3
  8. package/esm2022/lib/components/search-bar/search-bar.component.mjs +3 -3
  9. package/esm2022/lib/components/support-modal/support-modal.component.mjs +3 -3
  10. package/esm2022/lib/config.mjs +1 -1
  11. package/esm2022/lib/helpers.service.mjs +46 -1
  12. package/esm2022/lib/matterport-extensions/nest-thermostat/CanvasImage.mjs +1 -1
  13. package/esm2022/lib/matterport-extensions/nest-thermostat/CanvasRenderer.mjs +1 -1
  14. package/esm2022/lib/matterport-extensions/nest-thermostat/NestThermostat.mjs +1 -1
  15. package/esm2022/lib/matterport-extensions/nest-thermostat/PlaneRenderer.mjs +1 -1
  16. package/esm2022/lib/matterport-extensions/scene-component/SceneComponent.mjs +1 -1
  17. package/esm2022/lib/matterport-extensions/security-camera/SecurityCamera.mjs +22 -22
  18. package/esm2022/lib/matterport-extensions/tv-player/TvPlayer.mjs +1 -1
  19. package/esm2022/lib/matterport-extensions/view-frustum-mesh/ViewFrustumMesh.mjs +22 -22
  20. package/esm2022/lib/mattertagData.mjs +1 -1
  21. package/esm2022/lib/ngx-smarterplan-core.module.mjs +1 -1
  22. package/esm2022/lib/ngx-smarterplan-core.service.mjs +1 -1
  23. package/esm2022/lib/pipes/duration-to-string.pipe.mjs +1 -1
  24. package/esm2022/lib/pipes/format-date-number-to-digits.pipe.mjs +1 -1
  25. package/esm2022/lib/pipes/hashtag-from-id.pipe.mjs +1 -1
  26. package/esm2022/lib/pipes/safe-url.pipe.mjs +1 -1
  27. package/esm2022/lib/pipes/time-date-to-local-string.pipe.mjs +1 -1
  28. package/esm2022/lib/pipes/username-from-id.pipe.mjs +1 -1
  29. package/esm2022/lib/services/amplify-cache.service.mjs +1 -1
  30. package/esm2022/lib/services/base-tab.service.mjs +1 -1
  31. package/esm2022/lib/services/baseVisibility.service.mjs +1 -1
  32. package/esm2022/lib/services/content.service.mjs +1 -1
  33. package/esm2022/lib/services/filter.service.mjs +11 -1
  34. package/esm2022/lib/services/intervention.service.mjs +1 -1
  35. package/esm2022/lib/services/locale.service.mjs +1 -1
  36. package/esm2022/lib/services/matterport-import.service.mjs +1 -1
  37. package/esm2022/lib/services/matterport-measurement.service.mjs +1 -1
  38. package/esm2022/lib/services/matterport-navigation.service.mjs +1 -1
  39. package/esm2022/lib/services/matterport-object3d.service.mjs +1 -1
  40. package/esm2022/lib/services/matterport-pointer.service.mjs +6 -6
  41. package/esm2022/lib/services/matterport-tag-copy.service.mjs +1 -1
  42. package/esm2022/lib/services/matterport-tag.service.mjs +1 -1
  43. package/esm2022/lib/services/matterport.service.mjs +29 -18
  44. package/esm2022/lib/services/models/affectation.service.mjs +1 -1
  45. package/esm2022/lib/services/models/base-object.service.mjs +31 -4
  46. package/esm2022/lib/services/models/capture.service.mjs +1 -1
  47. package/esm2022/lib/services/models/comment.service.mjs +1 -1
  48. package/esm2022/lib/services/models/domain.service.mjs +1 -1
  49. package/esm2022/lib/services/models/equipment.service.mjs +14 -13
  50. package/esm2022/lib/services/models/event.service.mjs +1 -1
  51. package/esm2022/lib/services/models/feature.service.mjs +8 -7
  52. package/esm2022/lib/services/models/hashtag.service.mjs +1 -1
  53. package/esm2022/lib/services/models/layer.service.mjs +1 -1
  54. package/esm2022/lib/services/models/measurement.service.mjs +1 -1
  55. package/esm2022/lib/services/models/mission.service.mjs +1 -1
  56. package/esm2022/lib/services/models/navigation.service.mjs +1 -1
  57. package/esm2022/lib/services/models/node.service.mjs +1 -1
  58. package/esm2022/lib/services/models/object3D.service.mjs +1 -1
  59. package/esm2022/lib/services/models/operation.service.mjs +1 -1
  60. package/esm2022/lib/services/models/organisation.service.mjs +1 -1
  61. package/esm2022/lib/services/models/plan.service.mjs +1 -1
  62. package/esm2022/lib/services/models/poi.service.mjs +27 -27
  63. package/esm2022/lib/services/models/profile.service.mjs +1 -1
  64. package/esm2022/lib/services/models/property.service.mjs +1 -1
  65. package/esm2022/lib/services/models/space.service.mjs +48 -6
  66. package/esm2022/lib/services/models/template.service.mjs +1 -1
  67. package/esm2022/lib/services/models/ticket.service.mjs +27 -8
  68. package/esm2022/lib/services/models/visit.service.mjs +17 -5
  69. package/esm2022/lib/services/models/zone.service.mjs +1 -1
  70. package/esm2022/lib/services/navigator.service.mjs +14 -1
  71. package/esm2022/lib/services/s3.service.mjs +18 -1
  72. package/esm2022/lib/services/search.service.mjs +1 -1
  73. package/esm2022/lib/services/support.service.mjs +1 -1
  74. package/esm2022/lib/services/tag.service.mjs +16 -16
  75. package/esm2022/lib/services/threejs-import.service.mjs +151 -0
  76. package/esm2022/lib/services/threejs.service.mjs +1587 -0
  77. package/esm2022/lib/services/user.service.mjs +1 -1
  78. package/esm2022/lib/services/utils/matterport-transform.util.mjs +1 -1
  79. package/esm2022/lib/services/validators.service.mjs +1 -1
  80. package/esm2022/lib/services/viewer.service.mjs +402 -5
  81. package/esm2022/lib/services/zone-drawer.service.mjs +1 -1
  82. package/esm2022/lib/services/zoneChange.service.mjs +10 -1
  83. package/esm2022/lib/tokens/matterport-sdk-key.token.mjs +1 -1
  84. package/esm2022/lib/types.service.mjs +2 -1
  85. package/esm2022/lib/validators/email.directive.mjs +1 -1
  86. package/esm2022/lib/validators/no-empty.directive.mjs +1 -1
  87. package/esm2022/lib/validators/number.directive.mjs +1 -1
  88. package/esm2022/lib/validators/text.directive.mjs +1 -1
  89. package/esm2022/public-api.mjs +3 -1
  90. package/fesm2022/smarterplan-ngx-smarterplan-core.mjs +8046 -5724
  91. package/fesm2022/smarterplan-ngx-smarterplan-core.mjs.map +1 -1
  92. package/lib/helpers.service.d.ts +43 -0
  93. package/lib/services/models/base-object.service.d.ts +11 -1
  94. package/lib/services/models/equipment.service.d.ts +2 -1
  95. package/lib/services/models/feature.service.d.ts +2 -1
  96. package/lib/services/models/space.service.d.ts +22 -1
  97. package/lib/services/models/ticket.service.d.ts +4 -1
  98. package/lib/services/models/visit.service.d.ts +9 -1
  99. package/lib/services/s3.service.d.ts +8 -0
  100. package/lib/services/threejs-import.service.d.ts +31 -0
  101. package/lib/services/threejs.service.d.ts +521 -0
  102. package/lib/services/viewer.service.d.ts +152 -1
  103. package/lib/services/zoneChange.service.d.ts +9 -0
  104. package/lib/types.service.d.ts +15 -1
  105. package/package.json +1 -1
  106. package/public-api.d.ts +2 -0
  107. package/src/assets/vs-app.json +67 -67
@@ -1,13 +1,17 @@
1
1
  import { Subject } from 'rxjs';
2
2
  import { MatterportService } from './matterport.service';
3
+ import { ThreeJsService } from './threejs.service';
3
4
  import { BaseTagService } from './tag.service';
4
5
  import { DbObjectType, POI, PoiType, Comment, Equipment, Ticket, Feature, SpModule } from '../types.service';
5
6
  import { PoiService } from './models/poi.service';
7
+ import { Config } from '../config';
6
8
  import * as i0 from "@angular/core";
7
9
  export declare class ViewerService {
8
10
  private readonly sdkKey;
11
+ private readonly config;
9
12
  private poiService;
10
13
  private matterportService;
14
+ private threeJsService;
11
15
  private viewerMode;
12
16
  currentModel3D: string;
13
17
  private tourUrl;
@@ -23,6 +27,14 @@ export declare class ViewerService {
23
27
  dataIsLoaded: Subject<boolean>;
24
28
  isLoaded: boolean;
25
29
  showingViewer: boolean;
30
+ /**
31
+ * The space being viewed, whichever viewer is showing it.
32
+ *
33
+ * MatterportService carries its own copy, set while its SDK connects - which never happens in
34
+ * Three.js mode. Anything that reads only that one silently does nothing for a 3D model, and the
35
+ * lists that feed tags are exactly that.
36
+ */
37
+ currentSpaceID: string | null;
26
38
  sweepToMove: string | null;
27
39
  rotationToMove: {
28
40
  x: number;
@@ -50,7 +62,7 @@ export declare class ViewerService {
50
62
  };
51
63
  };
52
64
  private isObjectLoaded;
53
- constructor(sdkKey: string, poiService: PoiService, matterportService: MatterportService);
65
+ constructor(sdkKey: string, config: Config, poiService: PoiService, matterportService: MatterportService, threeJsService: ThreeJsService);
54
66
  checkMode(indexMode: string): boolean;
55
67
  setMode(indexMode: string): void;
56
68
  setTourUrl(options: {
@@ -82,7 +94,70 @@ export declare class ViewerService {
82
94
  */
83
95
  addObjectTagsToViewer(objects: DbObjectType[]): Promise<void>;
84
96
  actionAddObjectFromPOI(object: DbObjectType, poi: POI): Promise<any>;
97
+ /**
98
+ * Draws a POI as a tag in the Three.js scene.
99
+ *
100
+ * Both viewers are fed by the same subscriptions on the same POI records, so a tag created in
101
+ * either one shows up in the other without any syncing of its own - this is just the Three.js end
102
+ * of the pipeline that already drives Matterport.
103
+ */
104
+ private addThreeJsTagFromPOI;
105
+ /**
106
+ * The image to draw a tag with, mirroring what Matterport shows for the same POI.
107
+ *
108
+ * Matterport registers one texture per type (`icon-ticket`, `icon-equipment`...) from the same
109
+ * config entries used here, and overrides it with the POI's own icon when it has one. Reading the
110
+ * same two sources is what keeps a tag looking like itself across the two viewers.
111
+ */
112
+ private resolveTagIconUrl;
113
+ /** The configured icon for a POI type, or null when that type has none. */
114
+ private defaultTagIconUrl;
115
+ /** Moves the Three.js camera to frame a tag, mirroring Matterport's goToTag. */
116
+ goToThreeJsTag(elementId: string): void;
117
+ /** Shows only tags of the given POI types; null clears the filter. */
118
+ setVisibleThreeJsTagTypes(types: PoiType[] | null): void;
119
+ /**
120
+ * Alignment walkthrough: pick a tag, then click where it really sits, three times over.
121
+ *
122
+ * Uses tags that already exist, so nothing is created and nothing is written until the caller
123
+ * saves the result. See threeJsAlignmentProgress$ for what the UI should be asking for.
124
+ */
125
+ startThreeJsTagAlignment(): void;
126
+ cancelThreeJsTagAlignment(): void;
127
+ get threeJsAlignmentProgress$(): Subject<{
128
+ pairs: number;
129
+ awaiting: "tag" | "point";
130
+ tagId?: string;
131
+ }>;
132
+ /**
133
+ * Solves the alignment and applies it to the scene, returning it as the JSON to store in the
134
+ * capture's metadata. Null means the three tags were collinear and nothing was applied.
135
+ */
136
+ solveThreeJsTagAlignment(existingMetadata?: string): {
137
+ alignment: any;
138
+ metadata: string;
139
+ } | null;
140
+ /** Shows or hides a single Three.js tag. */
141
+ setThreeJsTagVisibility(elementId: string, visible: boolean): void;
85
142
  action_delete_element(element: DbObjectType): Promise<void>;
143
+ /** Emits when a Three.js model load actually stopped short, rather than merely being asked to. */
144
+ get threeJsModelLoadCancelled$(): Subject<void>;
145
+ /** Stops the Three.js model download in progress. */
146
+ cancelThreeJsModelLoad(): void;
147
+ /** Emits a tag's label while the pointer is over it in the Three.js scene. */
148
+ get threeJsTagHovered$(): Subject<{
149
+ label: string;
150
+ event: MouseEvent;
151
+ }>;
152
+ /** Emits the element id of a tag clicked in the Three.js scene. */
153
+ get threeJsTagClicked$(): Subject<import("./threejs.service").ThreeJsTagClick>;
154
+ /**
155
+ * Applies the visit's stored tag alignment, mapping captured tag coordinates onto this model.
156
+ *
157
+ * Safe to call before the model or any tag exists: it is a transform on the group both end up
158
+ * under, so it applies to whatever arrives later.
159
+ */
160
+ setThreeJsTagAlignmentFromMetadata(metadata: string): void;
86
161
  /**
87
162
  * Enable tag placement menu to add a new element depending on its type (TICKET, DATA, EQUIPMENT etc)
88
163
  */
@@ -104,6 +179,30 @@ export declare class ViewerService {
104
179
  action_toolbox_mesure(): void;
105
180
  action_toolbox_cancel_mesure(): void;
106
181
  action_update_poi(poi: POI, isValid: boolean, element: DbObjectType): Promise<POI>;
182
+ /**
183
+ * Writes the spot picked in the Three.js scene into the POI, mirroring the Matterport branch.
184
+ *
185
+ * The coordinate goes in the same field and the same space Matterport writes, which is what makes
186
+ * a tag created here show up in the right place there - and the other way round.
187
+ */
188
+ private commitThreeJsTagPlacement;
189
+ /**
190
+ * Creates the POI for an element just placed in the Three.js scene.
191
+ *
192
+ * The Matterport path reaches the same result through its tag dictionary - the tag exists first
193
+ * and carries the coordinates. Three.js has no such object, so the placement captured at click
194
+ * time is the only record of where the user pointed, and it has to become a POI here or it is
195
+ * lost when the form closes.
196
+ *
197
+ * Returns null when there is no pending placement, which is the normal case in Matterport mode.
198
+ */
199
+ createPoiForThreeJsPlacement(element: DbObjectType, poiType: PoiType): Promise<POI | null>;
200
+ /** Emits when a tag is dropped on the model in the Three.js scene. */
201
+ get threeJsTagPlaced$(): Subject<import("./threejs.service").ThreeJsTagPlacement>;
202
+ /** Emits when the calibration walkthrough is abandoned, including via Escape. */
203
+ get threeJsAlignmentCancelled$(): Subject<void>;
204
+ /** Leaves Three.js tag placement mode without placing anything. */
205
+ cancelThreeJsTagPlacement(): void;
107
206
  editOnlyTagStyleForPoi(poi: POI, object: DbObjectType): void;
108
207
  addIconAndSetForPoi(poi: POI, iconPath: string): void;
109
208
  changeToRegistredIconForPoi(poi: POI, iconName: string): void;
@@ -114,6 +213,58 @@ export declare class ViewerService {
114
213
  * @param element
115
214
  */
116
215
  action_move_poi_visually(poi: POI, element: Ticket | Feature | Equipment | Comment): Promise<void>;
216
+ initThreeJs(canvas: HTMLCanvasElement): void;
217
+ /**
218
+ * Loads a 3D model into the Three.js scene (GLTF).
219
+ * Only works when the viewer is in 'threejs' mode.
220
+ */
221
+ loadGLTFModel(url: string, cameraPosition?: {
222
+ x: number;
223
+ y: number;
224
+ z: number;
225
+ }, rotation?: {
226
+ x: number;
227
+ y: number;
228
+ z: number;
229
+ }): void;
230
+ /**
231
+ * Loads a GLB stored in S3, given its key (e.g. `visits/<id>/model.glb`).
232
+ *
233
+ * Resolves the key to a signed URL first, then loads it like any other. The signed URL only
234
+ * covers authentication - the bucket still needs a CORS rule allowing GET from the app's origin,
235
+ * or the browser blocks the download before it starts.
236
+ *
237
+ * `placementMetadata` is the capture's stored placement; when absent or unusable the viewer falls
238
+ * back to framing the model automatically.
239
+ */
240
+ loadGLTFModelFromS3(key: string, placementMetadata?: string): Promise<void>;
241
+ /**
242
+ * Loads a 3D model into the Three.js scene (OBJ).
243
+ */
244
+ loadObjModel(mtlUrl: string, objUrl: string, cameraPosition?: {
245
+ x: number;
246
+ y: number;
247
+ z: number;
248
+ }, rotation?: {
249
+ x: number;
250
+ y: number;
251
+ z: number;
252
+ }): void;
253
+ get threeJsObjectHovered$(): Subject<{
254
+ id: string;
255
+ event: MouseEvent;
256
+ }>;
257
+ get threeJsObjectClicked$(): Subject<string>;
258
+ /** Emits true while a heavy .obj file is being parsed (in a worker, when available), false once done. */
259
+ get threeJsModelLoading$(): Subject<boolean>;
260
+ /** Download progress for GLB models as a 0-1 fraction, or null when the size isn't known upfront. */
261
+ get threeJsModelLoadProgress$(): Subject<number>;
262
+ /**
263
+ * Registers the Web Worker used to parse heavy .obj files off the main thread.
264
+ * Must be created by the app (see obj-parser.worker.ts), since this library can't bundle worker files.
265
+ */
266
+ setObjParserWorker(worker: Worker): void;
267
+ addThreeJsObjects(objs: any[]): void;
117
268
  initMatterportSdk(spaceID: string, model3D: string, tagService: BaseTagService, module?: SpModule): Promise<void>;
118
269
  removeForbiddenSweeps(forbiddenSweeps: string[]): void;
119
270
  setObject3DLoadedInPosition(objectLoaded: boolean): void;
@@ -8,6 +8,15 @@ import * as i0 from "@angular/core";
8
8
  export declare class ZoneChangeService {
9
9
  zoneChange: Subject<Zone | null>;
10
10
  zonesForUserChange: Subject<Zone[] | null>;
11
+ /**
12
+ * Emits the space opened by a viewer that has no zone navigation (Three.js), or null when it
13
+ * closes.
14
+ *
15
+ * Zones are defined by the sweeps they contain, so they only mean something in a Matterport tour.
16
+ * A 3D model has no sweeps: it shows the whole space at once, and the services that load data
17
+ * listen here instead of to `zoneChange` to know which space they are looking at.
18
+ */
19
+ spaceWithoutZones: Subject<string | null>;
11
20
  private currentZone;
12
21
  private currentZones;
13
22
  floorHasChanged: EventEmitter<Zone>;
@@ -127,7 +127,8 @@ export declare enum EmailStatus {
127
127
  export declare enum CaptureViewer {
128
128
  CUPIX = "CUPIX",
129
129
  MATTERPORT = "MATTERPORT",
130
- SMARTERPLAN_V1 = "SMARTERPLAN_V1"
130
+ SMARTERPLAN_V1 = "SMARTERPLAN_V1",
131
+ THREEJS = "THREEJS"
131
132
  }
132
133
  export declare enum InventoryStatus {
133
134
  SUCCESS = "SUCCESS",
@@ -569,6 +570,14 @@ export type Space = {
569
570
  status?: SpaceStatus | null;
570
571
  guestLink?: string | null;
571
572
  signedImageUrl?: string | null;
573
+ /**
574
+ * The capture a visitor opens by default, of any viewer type.
575
+ *
576
+ * Kept on the space rather than as a flag on each capture: there is one field, so there can only
577
+ * be one answer, whichever screen set it. A flag per capture would let two of them claim the
578
+ * default and put the choice back where it started - undefined.
579
+ */
580
+ defaultCaptureID?: string | null;
572
581
  zones?: {
573
582
  __typename?: 'ModelZoneConnection';
574
583
  items?: Array<Zone | null> | null;
@@ -595,6 +604,11 @@ export type Visit = {
595
604
  node: Node;
596
605
  name?: string | null;
597
606
  nmbImagesImported: number;
607
+ /**
608
+ * Free-form metadata from the capture. Named after its source to keep it distinct from `name`,
609
+ * which comes from node.metadata. Three.js visits store their initial placement here.
610
+ */
611
+ captureMetadata?: string | null;
598
612
  };
599
613
  export type Hashtag = {
600
614
  name?: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smarterplan/ngx-smarterplan-core",
3
- "version": "1.4.15",
3
+ "version": "1.4.17",
4
4
  "dependencies": {
5
5
  "tslib": "^2.5.0"
6
6
  },
package/public-api.d.ts CHANGED
@@ -6,6 +6,7 @@ export * from './lib/services/tag.service';
6
6
  export * from './lib/services/baseVisibility.service';
7
7
  export * from './lib/services/content.service';
8
8
  export * from './lib/services/viewer.service';
9
+ export * from './lib/services/threejs.service';
9
10
  export * from './lib/services/navigator.service';
10
11
  export * from './lib/services/zoneChange.service';
11
12
  export * from './lib/config';
@@ -18,6 +19,7 @@ export * from './lib/services/filter.service';
18
19
  export * from './lib/services/search.service';
19
20
  export * from './lib/services/zone-drawer.service';
20
21
  export * from './lib/services/matterport-import.service';
22
+ export * from './lib/services/threejs-import.service';
21
23
  export * from './lib/services/matterport-tag-copy.service';
22
24
  export * from './lib/mattertagData';
23
25
  export * from './lib/services/utils/matterport-transform.util';
@@ -1,67 +1,67 @@
1
- {
2
- "version": "1.0",
3
- "payload": {
4
- "objects": [
5
- {
6
- "name": "slot_camera",
7
- "position": {
8
- "x": 2.8,
9
- "y": 2.4,
10
- "z": 10.71
11
- },
12
- "rotation": {
13
- "x": 0,
14
- "y": -22,
15
- "z": 0
16
- },
17
- "scale": {
18
- "x": 1,
19
- "y": 1,
20
- "z": 1
21
- },
22
- "components": [
23
- {
24
- "type": "mp.gltfLoader",
25
- "inputs": {
26
- "url": "https://static.matterport.com/showcase-sdk/examples/assets-1.0-2-g6b74572/assets/models/camera-1/scene.gltf",
27
- "localScale": { "x": 0.0008, "y": 0.0008, "z": 0.0008 },
28
- "localRotation": { "x": 0, "y": 90, "z": 0 }
29
- },
30
- "events": {
31
- "INTERACTION.CLICK": false,
32
- "INTERACTION.HOVER": false,
33
- "INTERACTION.DRAG": false
34
- }
35
- },
36
- {
37
- "type": "mp.securityCamera",
38
- "inputs": {
39
- "nearPlane": 0.1,
40
- "farPlane": 10,
41
- "horizontalFOV": 52,
42
- "aspect": 1.7777777777777777,
43
- "localPosition": {
44
- "x": 0,
45
- "y": 0.18,
46
- "z": -0.3
47
- },
48
- "localRotation": {
49
- "x": -15,
50
- "y": 0,
51
- "z": 0
52
- },
53
- "color": 65280,
54
- "panPeriod": 5,
55
- "panAngle": -45
56
- },
57
- "events": {
58
- "INTERACTION.CLICK": false,
59
- "INTERACTION.HOVER": false,
60
- "INTERACTION.DRAG": false
61
- }
62
- }
63
- ]
64
- }
65
- ]
66
- }
67
- }
1
+ {
2
+ "version": "1.0",
3
+ "payload": {
4
+ "objects": [
5
+ {
6
+ "name": "slot_camera",
7
+ "position": {
8
+ "x": 2.8,
9
+ "y": 2.4,
10
+ "z": 10.71
11
+ },
12
+ "rotation": {
13
+ "x": 0,
14
+ "y": -22,
15
+ "z": 0
16
+ },
17
+ "scale": {
18
+ "x": 1,
19
+ "y": 1,
20
+ "z": 1
21
+ },
22
+ "components": [
23
+ {
24
+ "type": "mp.gltfLoader",
25
+ "inputs": {
26
+ "url": "https://static.matterport.com/showcase-sdk/examples/assets-1.0-2-g6b74572/assets/models/camera-1/scene.gltf",
27
+ "localScale": { "x": 0.0008, "y": 0.0008, "z": 0.0008 },
28
+ "localRotation": { "x": 0, "y": 90, "z": 0 }
29
+ },
30
+ "events": {
31
+ "INTERACTION.CLICK": false,
32
+ "INTERACTION.HOVER": false,
33
+ "INTERACTION.DRAG": false
34
+ }
35
+ },
36
+ {
37
+ "type": "mp.securityCamera",
38
+ "inputs": {
39
+ "nearPlane": 0.1,
40
+ "farPlane": 10,
41
+ "horizontalFOV": 52,
42
+ "aspect": 1.7777777777777777,
43
+ "localPosition": {
44
+ "x": 0,
45
+ "y": 0.18,
46
+ "z": -0.3
47
+ },
48
+ "localRotation": {
49
+ "x": -15,
50
+ "y": 0,
51
+ "z": 0
52
+ },
53
+ "color": 65280,
54
+ "panPeriod": 5,
55
+ "panAngle": -45
56
+ },
57
+ "events": {
58
+ "INTERACTION.CLICK": false,
59
+ "INTERACTION.HOVER": false,
60
+ "INTERACTION.DRAG": false
61
+ }
62
+ }
63
+ ]
64
+ }
65
+ ]
66
+ }
67
+ }