@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.
- package/CHANGELOG.md +49 -0
- package/README.md +78 -28
- package/dist/ModelItemLabelPlugin/index.js +16 -4
- package/dist/ModelItemLabelPlugin/typings.d.ts +1 -0
- package/dist/ModelTVVideoPlugin/index.d.ts +4 -0
- package/dist/ModelTVVideoPlugin/index.js +326 -0
- package/dist/ModelTVVideoPlugin/typings.d.ts +25 -0
- package/dist/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
- package/dist/PanoMeasurePlugin/index.js +2 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.es.js +292 -7
- package/dist/index.js +292 -6
- package/dist/index.umd.js +292 -6
- package/docs/assets/main.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/ModelRoomLabelController.html +6 -6
- package/docs/enums/FLOOR_PLAN_ATTACHED_TO.html +1 -1
- package/docs/enums/ModelFloorplanErrorType.html +1 -1
- package/docs/index.html +78 -33
- package/docs/interfaces/LineJson.html +1 -1
- package/docs/interfaces/ModelChassisCompassPluginData.html +1 -1
- package/docs/interfaces/ModelChassisCompassPluginExportType.html +1 -1
- package/docs/interfaces/ModelChassisCompassPluginParameterType.html +1 -1
- package/docs/interfaces/ModelEntryDoorGuidePluginData.html +1 -1
- package/docs/interfaces/ModelEntryDoorGuidePluginExportType.html +1 -1
- package/docs/interfaces/ModelFloorplanParameterType.html +1 -1
- package/docs/interfaces/ModelFloorplanViewEvent.html +2 -2
- package/docs/interfaces/ModelItemLabelPluginData.html +1 -0
- package/docs/interfaces/ModelItemLabelPluginExportReturnsType.html +1 -0
- package/docs/interfaces/ModelItemLabelPluginParametersType.html +1 -0
- package/docs/interfaces/ModelRoomLabelPluginData.html +1 -1
- package/docs/interfaces/ModelTVVideoPluginData.html +1 -0
- package/docs/interfaces/ModelTVVideoPluginExportType.html +1 -0
- package/docs/interfaces/ModelTVVideoPluginParameterType.html +1 -0
- package/docs/interfaces/PanoCompassPluginData.html +1 -1
- package/docs/interfaces/PanoCompassPluginParameterType.html +1 -1
- package/docs/interfaces/PanoCursorRaycasterPluginExportType.html +6 -6
- package/docs/interfaces/PanoRulerPluginExportType.html +1 -1
- package/docs/interfaces/PanoRulerPluginOptions.html +1 -1
- package/docs/interfaces/PanoRulerPluginParameterType.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginData.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginExportType.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginParameterType.html +1 -1
- package/docs/interfaces/PointJson.html +1 -1
- package/docs/interfaces/RoomLabel.html +7 -7
- package/docs/interfaces/TopviewFloorplanPluginParameterType.html +1 -1
- package/docs/modules.html +12 -12
- package/libs/ModelItemLabelPlugin/index.js +16 -4
- package/libs/ModelItemLabelPlugin/typings.d.ts +1 -0
- package/libs/ModelTVVideoPlugin/index.d.ts +4 -0
- package/libs/ModelTVVideoPlugin/index.js +263 -0
- package/libs/ModelTVVideoPlugin/typings.d.ts +25 -0
- package/libs/ModelTVVideoPlugin/typings.js +7 -0
- package/libs/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
- package/libs/ModelTVVideoPlugin/utils/parseData.js +13 -0
- package/libs/index.d.ts +3 -0
- package/libs/index.js +1 -1
- 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();
|
|
@@ -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,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.
|
|
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",
|