@realsee/dnalogel 2.0.0-alpha.13 → 2.0.0-alpha.14

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 (58) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +78 -28
  3. package/dist/ModelItemLabelPlugin/index.js +16 -4
  4. package/dist/ModelItemLabelPlugin/typings.d.ts +1 -0
  5. package/dist/ModelTVVideoPlugin/index.d.ts +4 -0
  6. package/dist/ModelTVVideoPlugin/index.js +326 -0
  7. package/dist/ModelTVVideoPlugin/typings.d.ts +25 -0
  8. package/dist/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
  9. package/dist/PanoMeasurePlugin/index.js +2 -2
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.es.js +292 -7
  12. package/dist/index.js +292 -6
  13. package/dist/index.umd.js +292 -6
  14. package/docs/assets/main.js +1 -1
  15. package/docs/assets/search.js +1 -1
  16. package/docs/classes/ModelRoomLabelController.html +6 -6
  17. package/docs/enums/FLOOR_PLAN_ATTACHED_TO.html +1 -1
  18. package/docs/enums/ModelFloorplanErrorType.html +1 -1
  19. package/docs/index.html +78 -33
  20. package/docs/interfaces/LineJson.html +1 -1
  21. package/docs/interfaces/ModelChassisCompassPluginData.html +1 -1
  22. package/docs/interfaces/ModelChassisCompassPluginExportType.html +1 -1
  23. package/docs/interfaces/ModelChassisCompassPluginParameterType.html +1 -1
  24. package/docs/interfaces/ModelEntryDoorGuidePluginData.html +1 -1
  25. package/docs/interfaces/ModelEntryDoorGuidePluginExportType.html +1 -1
  26. package/docs/interfaces/ModelFloorplanParameterType.html +1 -1
  27. package/docs/interfaces/ModelFloorplanViewEvent.html +2 -2
  28. package/docs/interfaces/ModelItemLabelPluginData.html +1 -0
  29. package/docs/interfaces/ModelItemLabelPluginExportReturnsType.html +1 -0
  30. package/docs/interfaces/ModelItemLabelPluginParametersType.html +1 -0
  31. package/docs/interfaces/ModelRoomLabelPluginData.html +1 -1
  32. package/docs/interfaces/ModelTVVideoPluginData.html +1 -0
  33. package/docs/interfaces/ModelTVVideoPluginExportType.html +1 -0
  34. package/docs/interfaces/ModelTVVideoPluginParameterType.html +1 -0
  35. package/docs/interfaces/PanoCompassPluginData.html +1 -1
  36. package/docs/interfaces/PanoCompassPluginParameterType.html +1 -1
  37. package/docs/interfaces/PanoCursorRaycasterPluginExportType.html +6 -6
  38. package/docs/interfaces/PanoRulerPluginExportType.html +1 -1
  39. package/docs/interfaces/PanoRulerPluginOptions.html +1 -1
  40. package/docs/interfaces/PanoRulerPluginParameterType.html +1 -1
  41. package/docs/interfaces/PanoSpatialTagPluginData.html +1 -1
  42. package/docs/interfaces/PanoSpatialTagPluginExportType.html +1 -1
  43. package/docs/interfaces/PanoSpatialTagPluginParameterType.html +1 -1
  44. package/docs/interfaces/PointJson.html +1 -1
  45. package/docs/interfaces/RoomLabel.html +7 -7
  46. package/docs/interfaces/TopviewFloorplanPluginParameterType.html +1 -1
  47. package/docs/modules.html +12 -12
  48. package/libs/ModelItemLabelPlugin/index.js +16 -4
  49. package/libs/ModelItemLabelPlugin/typings.d.ts +1 -0
  50. package/libs/ModelTVVideoPlugin/index.d.ts +4 -0
  51. package/libs/ModelTVVideoPlugin/index.js +263 -0
  52. package/libs/ModelTVVideoPlugin/typings.d.ts +25 -0
  53. package/libs/ModelTVVideoPlugin/typings.js +7 -0
  54. package/libs/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
  55. package/libs/ModelTVVideoPlugin/utils/parseData.js +13 -0
  56. package/libs/index.d.ts +3 -0
  57. package/libs/index.js +1 -1
  58. package/package.json +1 -1
@@ -14,7 +14,8 @@ export const ModelItemLabelPlugin = (five, params) => {
14
14
  app: undefined,
15
15
  hooks: new Subscribe(),
16
16
  modelOcclusionEnable: (_a = params === null || params === void 0 ? void 0 : params.modelOcclusionEnable) !== null && _a !== void 0 ? _a : true,
17
- displayStrategyType: (_b = params === null || params === void 0 ? void 0 : params.displayStrategyType) !== null && _b !== void 0 ? _b : DISPLAY_STRATEGY_TYPE.SMALL
17
+ displayStrategyType: (_b = params === null || params === void 0 ? void 0 : params.displayStrategyType) !== null && _b !== void 0 ? _b : DISPLAY_STRATEGY_TYPE.SMALL,
18
+ pending: false
18
19
  };
19
20
  pluginState.container.setAttribute('class', 'model-item-label-plugin-container');
20
21
  pluginState.container.style.cssText = `
@@ -23,8 +24,8 @@ export const ModelItemLabelPlugin = (five, params) => {
23
24
  top: 0;
24
25
  width: 100%;
25
26
  height: 100%;
26
- pointerEvents: none;
27
27
  `;
28
+ pluginState.container.style.pointerEvents = 'none'; // 写到 cssText 里不生效
28
29
  const appendTo = (wrapper) => {
29
30
  pluginState.wrapper = wrapper;
30
31
  wrapper.appendChild(pluginState.container);
@@ -32,7 +33,6 @@ export const ModelItemLabelPlugin = (five, params) => {
32
33
  return true;
33
34
  };
34
35
  const load = (data) => {
35
- console.log('🐶--当前标签总条数: ', data.model_item_labels.length);
36
36
  pluginState.itemLabels = parseModelItemLabelPluginData(data);
37
37
  render();
38
38
  };
@@ -55,23 +55,30 @@ export const ModelItemLabelPlugin = (five, params) => {
55
55
  pluginState.container.remove();
56
56
  };
57
57
  const handleRerender = () => {
58
- if (!pluginState.enabled || !pluginState.fiveModeEnabled)
58
+ if (!pluginState.enabled || !pluginState.fiveModeEnabled || pluginState.pending)
59
59
  return;
60
+ pluginState.pending = true;
60
61
  disable();
61
62
  };
62
63
  const rerender = (a, b, c) => {
64
+ if (!pluginState.pending)
65
+ return;
63
66
  if (!pluginState.fiveModeEnabled)
64
67
  return;
65
68
  if (!c)
66
69
  return;
70
+ pluginState.pending = false;
67
71
  enable();
68
72
  render();
69
73
  };
70
74
  const handleInteriaPanRerender = (a, b) => {
75
+ if (!pluginState.pending)
76
+ return;
71
77
  if (!pluginState.fiveModeEnabled)
72
78
  return;
73
79
  if (!b)
74
80
  return;
81
+ pluginState.pending = false;
75
82
  enable();
76
83
  render();
77
84
  };
@@ -81,10 +88,13 @@ export const ModelItemLabelPlugin = (five, params) => {
81
88
  }
82
89
  };
83
90
  const handlePanGesture = (pose, final) => {
91
+ if (!pluginState.pending)
92
+ return;
84
93
  if (!pluginState.fiveModeEnabled)
85
94
  return;
86
95
  if (!final)
87
96
  return;
97
+ pluginState.pending = false;
88
98
  enable();
89
99
  render();
90
100
  };
@@ -149,6 +159,8 @@ export const ModelItemLabelPlugin = (five, params) => {
149
159
  five.off('pinchGesture', rerender);
150
160
  };
151
161
  const onFiveModeChange = (mode) => {
162
+ if (!pluginState.enabled || pluginState.pending)
163
+ return;
152
164
  if (mode !== Five.Mode.Floorplan) {
153
165
  pluginState.fiveModeEnabled = false;
154
166
  render();
@@ -52,4 +52,5 @@ export interface ModelItemLabelPluginState {
52
52
  hooks: Subscribe<PluginEvent>;
53
53
  modelOcclusionEnable: boolean;
54
54
  displayStrategyType: Partial<DISPLAY_STRATEGY_TYPE>;
55
+ pending: boolean;
55
56
  }
@@ -0,0 +1,4 @@
1
+ import type { FivePlugin } from '@realsee/five';
2
+ import { ModelTVVideoPluginExportType, ModelTVVideoPluginParameterType } from "./typings";
3
+ export declare const ModelTVVideoPlugin: FivePlugin<ModelTVVideoPluginParameterType, ModelTVVideoPluginExportType>;
4
+ export default ModelTVVideoPlugin;
@@ -0,0 +1,263 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import * as THREE from 'three';
11
+ import { parseModelTVVideoPoints } from "./utils/parseData";
12
+ export const ModelTVVideoPlugin = (five, { videoElement }) => {
13
+ const state = {
14
+ videoMeshes: [],
15
+ videoTextureEnabled: false,
16
+ videoSource: '',
17
+ rectPoints: [],
18
+ enabled: false,
19
+ videoElement: videoElement,
20
+ };
21
+ const setMuted = (muted) => {
22
+ if (state.videoTexture) {
23
+ state.videoTexture.image.muted = muted;
24
+ state.videoTexture.image.play();
25
+ }
26
+ };
27
+ const getMuted = () => {
28
+ if (state.videoTexture)
29
+ return state.videoTexture.image.muted;
30
+ else
31
+ return true;
32
+ };
33
+ const enable = () => {
34
+ if (state.enabled)
35
+ return;
36
+ if (!state.videoTexture)
37
+ return;
38
+ state.enabled = true;
39
+ state.videoMeshes = createPanoVideoMeshes();
40
+ console.log('state.videoMeshes', state.videoMeshes);
41
+ state.videoMeshes.forEach((mesh) => five.scene.add(mesh));
42
+ const play = () => {
43
+ console.log('play', state.videoTexture);
44
+ if (!state.videoTexture)
45
+ return;
46
+ const timeupdate = () => {
47
+ var _a;
48
+ if (!state.videoTexture)
49
+ return;
50
+ (_a = state.videoTexture) === null || _a === void 0 ? void 0 : _a.image.removeEventListener('timeupdate', timeupdate);
51
+ state.videoTextureEnabled = true;
52
+ state.videoMeshes.forEach((mesh) => {
53
+ if (mesh.material.map !== state.videoTexture)
54
+ mesh.material.map = state.videoTexture;
55
+ });
56
+ five.needsRender = true;
57
+ };
58
+ state.videoTexture.image.addEventListener('timeupdate', timeupdate);
59
+ if (state.videoTexture && state.videoMeshes.length) {
60
+ state.videoTexture.image.play();
61
+ }
62
+ };
63
+ if (five.model.loaded)
64
+ play();
65
+ else {
66
+ return five.once('modelLoaded', () => play());
67
+ }
68
+ };
69
+ const disable = () => {
70
+ if (!state.enabled)
71
+ return;
72
+ state.enabled = false;
73
+ state.videoMeshes.forEach((mesh) => {
74
+ mesh.geometry.dispose();
75
+ mesh.material.dispose();
76
+ five.scene.remove(mesh);
77
+ if (state.videoTexture)
78
+ state.videoTexture.image.pause();
79
+ });
80
+ state.videoMeshes = [];
81
+ five.needsRender = true;
82
+ };
83
+ const createPanoVideoMeshes = () => {
84
+ return state.rectPoints.map((points, index) => {
85
+ const geometry = new THREE.BufferGeometry();
86
+ const segments = 128;
87
+ const verticesArray = [];
88
+ verticesArray.push(points[0].x, points[0].y, points[0].z);
89
+ for (let i = 1; i < segments; i++) {
90
+ verticesArray.push(points[0].x + ((points[1].x - points[0].x) * i) / segments, points[0].y + ((points[1].y - points[0].y) * i) / segments, points[0].z + ((points[1].z - points[0].z) * i) / segments);
91
+ }
92
+ verticesArray.push(points[1].x, points[1].y, points[1].z);
93
+ verticesArray.push(points[2].x, points[2].y, points[2].z);
94
+ for (let i = 1; i < segments; i++) {
95
+ verticesArray.push(points[2].x + ((points[3].x - points[2].x) * i) / segments, points[2].y + ((points[3].y - points[2].y) * i) / segments, points[2].z + ((points[3].z - points[2].z) * i) / segments);
96
+ }
97
+ verticesArray.push(points[3].x, points[3].y, points[3].z);
98
+ const uvArray = [];
99
+ uvArray.push(0, 1);
100
+ for (let i = 1; i < segments; i++) {
101
+ uvArray.push(0, 1 - i / segments);
102
+ }
103
+ uvArray.push(0, 0);
104
+ uvArray.push(1, 0);
105
+ for (let i = 1; i < segments; i++) {
106
+ uvArray.push(1, i / segments);
107
+ }
108
+ uvArray.push(1, 1);
109
+ const indicesArray = [];
110
+ for (let i = 0; i < segments; i++) {
111
+ indicesArray.push(i, i + 1, segments * 2 - i, i, segments * 2 - i, segments * 2 + 1 - i);
112
+ }
113
+ geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(verticesArray), 3));
114
+ geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvArray), 2));
115
+ geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(indicesArray), 1));
116
+ const material = new THREE.MeshBasicMaterial({
117
+ map: state.videoTextureEnabled ? state.videoTexture : state.imageTexture,
118
+ side: THREE.DoubleSide,
119
+ });
120
+ const mesh = new THREE.Mesh(geometry, material);
121
+ mesh.renderOrder = 1;
122
+ mesh.name = `ModelTVVideoPlugin-${index}-${performance.now()}`;
123
+ return mesh;
124
+ });
125
+ };
126
+ const getImageTexture = (source) => {
127
+ const texture = new THREE.TextureLoader().load(source);
128
+ texture.minFilter = THREE.LinearFilter;
129
+ texture.magFilter = THREE.LinearFilter;
130
+ texture.format = THREE.RGBFormat;
131
+ return texture;
132
+ };
133
+ const getVideoTexture = (source, video) => {
134
+ return new Promise((resolve, reject) => {
135
+ const xhr = new XMLHttpRequest();
136
+ xhr.onreadystatechange = () => {
137
+ if (xhr.readyState == 4) {
138
+ if (xhr.status == 200) {
139
+ const url = window.URL || window.webkitURL;
140
+ video = video || document.createElement('video');
141
+ video.crossOrigin = 'anonymous';
142
+ video.autoplay = true;
143
+ video.muted = true;
144
+ video.loop = true;
145
+ video.playsInline = true;
146
+ video.src = url.createObjectURL(xhr.response);
147
+ const texture = new THREE.VideoTexture(video);
148
+ texture.minFilter = THREE.LinearFilter;
149
+ texture.magFilter = THREE.LinearFilter;
150
+ texture.format = THREE.RGBFormat;
151
+ resolve(Object.assign(texture, { videoSource: source }));
152
+ }
153
+ else {
154
+ reject(new Error('Video download Error: ' + xhr.status));
155
+ }
156
+ }
157
+ };
158
+ xhr.onerror = (error) => reject(error);
159
+ xhr.open('GET', source);
160
+ xhr.responseType = 'blob';
161
+ xhr.send();
162
+ });
163
+ };
164
+ const load = (data, videoElement) => __awaiter(void 0, void 0, void 0, function* () {
165
+ const { video_src, video_poster_src, points } = data;
166
+ state.videoSource = video_src;
167
+ // TODO 存疑,先处理多一次遍历 o(2n)
168
+ state.rectPoints = parseModelTVVideoPoints(points)
169
+ .map((items) => items.map(({ x, y, z }) => new THREE.Vector3(x, y, z)));
170
+ state.imageTexture = getImageTexture(video_poster_src);
171
+ if (videoElement) {
172
+ state.videoElement = videoElement;
173
+ }
174
+ state.videoTexture = yield getVideoTexture(state.videoSource, state.videoElement);
175
+ state.enabled = !!data.enable;
176
+ if (state.enabled)
177
+ enable();
178
+ });
179
+ const dispose = () => {
180
+ disable();
181
+ state.videoTexture = undefined;
182
+ five.off('modeChange', () => setMuted(true));
183
+ five.off('wantsTapGesture', (raycaster) => {
184
+ if (!state.enabled)
185
+ return;
186
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
187
+ if (!!intersect && /^video/.test(intersect.object.name)) {
188
+ if (state.videoTexture)
189
+ setMuted(!state.videoTexture.image.muted);
190
+ return false;
191
+ }
192
+ });
193
+ five.off('panoArrived', () => {
194
+ if (!state.enabled)
195
+ return;
196
+ if (getMuted())
197
+ return;
198
+ const cameraPosition = five.camera.position;
199
+ const visible = state.rectPoints.find((points) => {
200
+ const centerVector = points.reduce((total, curr) => new THREE.Vector3(total.x + curr.x / points.length, total.y + curr.y / points.length, total.z + curr.z / points.length), new THREE.Vector3());
201
+ return (points.map((point) => new THREE.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
202
+ vector = vector.clone().sub(cameraPosition).normalize();
203
+ const raycaster = new THREE.Raycaster(cameraPosition, vector);
204
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
205
+ return !!intersect && /^video/.test(intersect.object.name);
206
+ }).length >= 2);
207
+ });
208
+ if (!visible)
209
+ setMuted(true);
210
+ });
211
+ five.off('renderFrame', () => {
212
+ // console.log('renderFrame', state.videoMeshes)
213
+ state.videoMeshes.forEach((meshes) => {
214
+ if (meshes)
215
+ //@ts-ignore
216
+ meshes.needsRender = true;
217
+ });
218
+ });
219
+ };
220
+ five.on('modeChange', () => setMuted(true));
221
+ five.on('wantsTapGesture', (raycaster) => {
222
+ if (!state.enabled)
223
+ return;
224
+ const targetMesh = five.scene.children.find(item => /^ModelTVVideoPlugin/.test(item.name));
225
+ if (!targetMesh)
226
+ return;
227
+ const intersectObjects = raycaster.intersectObjects([targetMesh]);
228
+ if (intersectObjects.length === 0)
229
+ return;
230
+ if (state.videoTexture)
231
+ setMuted(!state.videoTexture.image.muted); // TODO toggle video play
232
+ return false;
233
+ });
234
+ five.on('panoArrived', () => {
235
+ if (!state.enabled)
236
+ return;
237
+ if (getMuted())
238
+ return;
239
+ const cameraPosition = five.camera.position;
240
+ const visible = state.rectPoints.find((points) => {
241
+ const centerVector = points.reduce((total, curr) => new THREE.Vector3(total.x + curr.x / points.length, total.y + curr.y / points.length, total.z + curr.z / points.length), new THREE.Vector3());
242
+ return (points.map((point) => new THREE.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
243
+ vector = vector.clone().sub(cameraPosition).normalize();
244
+ const raycaster = new THREE.Raycaster(cameraPosition, vector);
245
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
246
+ return !!intersect && /^video/.test(intersect.object.name);
247
+ }).length >= 2);
248
+ });
249
+ if (!visible)
250
+ setMuted(true);
251
+ });
252
+ five.on('renderFrame', () => {
253
+ // console.log('renderFrame', state.videoMeshes)
254
+ state.videoMeshes.forEach((meshes) => {
255
+ if (meshes)
256
+ //@ts-ignore
257
+ meshes.needsRender = true;
258
+ });
259
+ });
260
+ Object.assign(window, { $state: state });
261
+ return { enable, disable, load, dispose };
262
+ };
263
+ export default ModelTVVideoPlugin;
@@ -0,0 +1,25 @@
1
+ export interface ModelTVVideoPluginParameterType {
2
+ videoElement?: HTMLVideoElement;
3
+ }
4
+ export declare enum DIRECTION {
5
+ TOP_LEFT = "topLeft",
6
+ TOP_RIGHT = "topRight",
7
+ BOTTOM_LEFT = "bottomLeft",
8
+ BOTTOM_RIGHT = "bottomRight"
9
+ }
10
+ export interface Point {
11
+ x: number;
12
+ y: number;
13
+ z: number;
14
+ }
15
+ export interface ModelTVVideoPluginData {
16
+ enable?: boolean;
17
+ video_src: string;
18
+ video_poster_src: string;
19
+ points: Point[][] | Record<DIRECTION, Point>[];
20
+ }
21
+ export interface ModelTVVideoPluginExportType {
22
+ enable: () => void;
23
+ disable: () => void;
24
+ load: (data: ModelTVVideoPluginData, videoElement?: HTMLVideoElement) => Promise<void>;
25
+ }
@@ -0,0 +1,7 @@
1
+ export var DIRECTION;
2
+ (function (DIRECTION) {
3
+ DIRECTION["TOP_LEFT"] = "topLeft";
4
+ DIRECTION["TOP_RIGHT"] = "topRight";
5
+ DIRECTION["BOTTOM_LEFT"] = "bottomLeft";
6
+ DIRECTION["BOTTOM_RIGHT"] = "bottomRight";
7
+ })(DIRECTION || (DIRECTION = {}));
@@ -0,0 +1,2 @@
1
+ import { DIRECTION, Point } from "../typings";
2
+ export declare function parseModelTVVideoPoints(points: Point[][] | Record<DIRECTION, Point>[]): Point[][];
@@ -0,0 +1,13 @@
1
+ import { DIRECTION } from "../typings";
2
+ export function parseModelTVVideoPoints(points) {
3
+ if (points.length === 0)
4
+ return [];
5
+ if (Array.isArray(points[0]))
6
+ return points;
7
+ let newPoints = [];
8
+ points.map(point => {
9
+ const newPoint = [point[DIRECTION.TOP_LEFT], point[DIRECTION.BOTTOM_LEFT], point[DIRECTION.BOTTOM_RIGHT], point[DIRECTION.TOP_RIGHT]];
10
+ newPoints.push(newPoint);
11
+ });
12
+ return newPoints;
13
+ }
package/libs/index.d.ts CHANGED
@@ -24,4 +24,7 @@ export type { PluginReturns, PluginEvent, LineJson, PointJson } from './PanoMeas
24
24
  export { default as PanoMeasurePlugin } from './PanoMeasurePlugin';
25
25
  export type { PanoSpatialTagPluginParameterType, PanoSpatialTagPluginData, PanoSpatialTagPluginExportType } from './PanoSpatialTagPlugin';
26
26
  export { default as PanoSpatialTagPlugin } from './PanoSpatialTagPlugin';
27
+ export type { ModelItemLabelPluginData, ModelItemLabelPluginExportReturnsType, ModelItemLabelPluginParametersType } from './ModelItemLabelPlugin/typings';
27
28
  export { default as ModelItemLabelPlugin } from './ModelItemLabelPlugin';
29
+ export type { ModelTVVideoPluginData, ModelTVVideoPluginParameterType, ModelTVVideoPluginExportType } from './ModelTVVideoPlugin/typings';
30
+ export { default as ModelTVVideoPlugin } from './ModelTVVideoPlugin';
package/libs/index.js CHANGED
@@ -14,5 +14,5 @@ export { default as PanoRulerPlugin } from './PanoRulerPlugin';
14
14
  export { default as PanoCompassPlugin } from './PanoCompassPlugin';
15
15
  export { default as PanoMeasurePlugin } from './PanoMeasurePlugin';
16
16
  export { default as PanoSpatialTagPlugin } from './PanoSpatialTagPlugin';
17
- // 模型物品标签插件
18
17
  export { default as ModelItemLabelPlugin } from './ModelItemLabelPlugin';
18
+ export { default as ModelTVVideoPlugin } from './ModelTVVideoPlugin';
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "author": "REALSEE-DEVELOPER",
7
7
  "repository": "https://github.com/realsee-developer/dnalogel.git",
8
8
  "private": false,
9
- "version": "2.0.0-alpha.13",
9
+ "version": "2.0.0-alpha.14",
10
10
  "license": "SEE LICENSE IN TERMS.txt",
11
11
  "scripts": {
12
12
  "build": "yarn run tsb && yarn run build:rollup && yarn build:docs",