@realsee/dnalogel 2.0.0-alpha.26 → 2.0.0-alpha.28
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 +6 -0
- package/dist/CSS3DRenderPlugin/Plugin.d.ts +49 -0
- package/dist/CSS3DRenderPlugin/index.d.ts +3 -48
- package/dist/CameraMovementPlugin/CameraMovementPlugin.d.ts +7 -0
- package/dist/CameraMovementPlugin/index.d.ts +4 -6
- package/dist/CameraMovementPlugin/index.js +12 -12
- package/dist/ModelChassisCompassPlugin/Plugin.d.ts +19 -0
- package/dist/ModelChassisCompassPlugin/index.d.ts +3 -18
- package/dist/ModelEntryDoorGuidePlugin/Plugin.d.ts +26 -0
- package/dist/ModelEntryDoorGuidePlugin/index.d.ts +3 -25
- package/dist/ModelEntryDoorGuidePlugin/index.js +0 -5
- package/dist/ModelItemLabelPlugin/ModelItemLabelPlugin.d.ts +4 -0
- package/dist/ModelItemLabelPlugin/index.d.ts +8 -3
- package/dist/ModelItemLabelPlugin/index.js +13 -7
- package/dist/ModelTVVideoPlugin/Plugin.d.ts +4 -0
- package/dist/ModelTVVideoPlugin/index.d.ts +4 -3
- package/dist/ModelTVVideoPlugin/index.js +3 -3
- package/dist/ModelViewPlugin/Plugin.d.ts +17 -0
- package/dist/ModelViewPlugin/index.d.ts +3 -16
- package/dist/PanoCompassPlugin/Plugin.d.ts +47 -0
- package/dist/PanoCompassPlugin/index.d.ts +4 -47
- package/dist/PanoCompassPlugin/index.js +5 -4
- package/dist/PanoMeasurePlugin/index.d.ts +1 -1
- package/dist/PanoMeasurePlugin/index.js +4 -1
- package/dist/PanoRulerPlugin/Plugin.d.ts +31 -0
- package/dist/PanoRulerPlugin/index.d.ts +4 -30
- package/dist/PanoRulerPlugin/index.js +0 -5
- package/dist/PanoSpatialTagPlugin/Plugin.d.ts +33 -0
- package/dist/PanoSpatialTagPlugin/index.d.ts +4 -32
- package/dist/PanoSpatialTagPlugin/index.js +23 -21
- package/dist/_index.d.ts +30 -0
- package/dist/floorplan/index.d.ts +6 -0
- package/dist/index.d.ts +15 -30
- package/dist/index.es.js +149 -22
- package/dist/index.js +177 -43
- package/dist/index.umd.js +180 -47
- package/docs/assets/search.js +1 -1
- package/docs/classes/ModelRoomLabelController.html +5 -8
- package/docs/classes/PanoFloorplanRadarPluginController.html +3 -0
- package/docs/enums/CameraMovementEffect.html +3 -0
- package/docs/enums/DIRECTION.html +1 -0
- package/docs/enums/DISPLAY_STRATEGY_TYPE.html +1 -0
- package/docs/enums/FLOOR_PLAN_ATTACHED_TO.html +1 -1
- package/docs/enums/ModelFloorplanErrorType.html +1 -1
- package/docs/enums/Rotation.html +3 -0
- package/docs/index.html +2 -2
- package/docs/interfaces/CSS3DRenderPluginExportType.html +4 -0
- package/docs/interfaces/CameraMovementPluginExportType.html +17 -0
- package/docs/interfaces/FloorplanBounding.html +10 -0
- package/docs/interfaces/FloorplanData.html +3 -0
- package/docs/interfaces/FloorplanEntrance.html +15 -0
- package/docs/interfaces/FloorplanExtraObject.html +7 -0
- package/docs/interfaces/FloorplanExtraObject3D.html +3 -0
- package/docs/interfaces/FloorplanFloorData.html +3 -0
- package/docs/interfaces/FloorplanImagePosition.html +3 -0
- package/docs/interfaces/FloorplanObserver.html +5 -0
- package/docs/interfaces/FloorplanOutlineItem.html +3 -0
- package/docs/interfaces/FloorplanPosition.html +3 -0
- package/docs/interfaces/FloorplanRoomItem.html +17 -0
- package/docs/interfaces/FloorplanRoomLabelItem.html +7 -0
- package/docs/interfaces/FloorplanServerBounding.html +10 -0
- package/docs/interfaces/FloorplanServerComputedData.html +1 -0
- package/docs/interfaces/FloorplanServerData.html +3 -0
- package/docs/interfaces/FloorplanServerEntrance.html +15 -0
- package/docs/interfaces/FloorplanServerFloorData.html +3 -0
- package/docs/interfaces/FloorplanServerImagePosition.html +3 -0
- package/docs/interfaces/FloorplanServerObserver.html +5 -0
- package/docs/interfaces/FloorplanServerOutlineItem.html +3 -0
- package/docs/interfaces/FloorplanServerPosition.html +3 -0
- package/docs/interfaces/FloorplanServerRoomItem.html +20 -0
- package/docs/interfaces/FloorplanServerRoomLabelItem.html +7 -0
- 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 +3 -3
- package/docs/interfaces/ModelItemLabelPluginData.html +1 -1
- package/docs/interfaces/ModelItemLabelPluginExportReturnsType.html +1 -1
- package/docs/interfaces/ModelItemLabelPluginParametersType.html +1 -1
- package/docs/interfaces/ModelRoomLabelPluginData.html +1 -1
- package/docs/interfaces/ModelTVVideoPluginData.html +1 -1
- package/docs/interfaces/ModelTVVideoPluginExportType.html +1 -1
- package/docs/interfaces/ModelTVVideoPluginParameterType.html +1 -1
- package/docs/interfaces/ModelViewPluginExportType.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/PanoCursorRaycasterPluginParameterType.html +1 -0
- package/docs/interfaces/PanoFloorplanRadarPluginControllerParameter.html +1 -0
- package/docs/interfaces/PanoRulerPluginExportType.html +1 -1
- package/docs/interfaces/PanoRulerPluginOptions.html +1 -1
- package/docs/interfaces/PanoRulerPluginParameterType.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginContentEvent.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginContentReplacement.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginData.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginDataElement.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginExportType.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginOriginElement.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginParameterType.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginPointElement.html +1 -0
- package/docs/interfaces/PanoSpatialTagPluginTagElement.html +1 -0
- package/docs/interfaces/Point.html +1 -0
- package/docs/interfaces/PointJson.html +1 -1
- package/docs/interfaces/Room.html +1 -0
- package/docs/interfaces/RoomInfo.html +1 -0
- package/docs/interfaces/RoomLabel.html +7 -7
- package/docs/interfaces/RoomRules.html +1 -0
- package/docs/interfaces/Rooms.html +1 -0
- package/docs/interfaces/TopviewFloorplanPluginParameterType.html +10 -10
- package/docs/modules.html +28 -12
- package/libs/CSS3DRenderPlugin/Plugin.d.ts +49 -0
- package/libs/CSS3DRenderPlugin/Plugin.js +182 -0
- package/libs/CSS3DRenderPlugin/index.d.ts +3 -48
- package/libs/CSS3DRenderPlugin/index.js +2 -181
- package/libs/CameraMovementPlugin/CameraMovementPlugin.d.ts +7 -0
- package/libs/CameraMovementPlugin/CameraMovementPlugin.js +159 -0
- package/libs/CameraMovementPlugin/index.d.ts +4 -6
- package/libs/CameraMovementPlugin/index.js +3 -158
- package/libs/ModelChassisCompassPlugin/Plugin.d.ts +19 -0
- package/libs/ModelChassisCompassPlugin/Plugin.js +75 -0
- package/libs/ModelChassisCompassPlugin/index.d.ts +3 -18
- package/libs/ModelChassisCompassPlugin/index.js +2 -74
- package/libs/ModelEntryDoorGuidePlugin/Plugin.d.ts +26 -0
- package/libs/ModelEntryDoorGuidePlugin/Plugin.js +140 -0
- package/libs/ModelEntryDoorGuidePlugin/index.d.ts +3 -25
- package/libs/ModelEntryDoorGuidePlugin/index.js +2 -139
- package/libs/ModelItemLabelPlugin/ModelItemLabelPlugin.d.ts +4 -0
- package/libs/ModelItemLabelPlugin/ModelItemLabelPlugin.js +120 -0
- package/libs/ModelItemLabelPlugin/index.d.ts +8 -3
- package/libs/ModelItemLabelPlugin/index.js +7 -119
- package/libs/ModelTVVideoPlugin/Plugin.d.ts +4 -0
- package/libs/ModelTVVideoPlugin/Plugin.js +254 -0
- package/libs/ModelTVVideoPlugin/index.d.ts +4 -3
- package/libs/ModelTVVideoPlugin/index.js +3 -253
- package/libs/ModelViewPlugin/Plugin.d.ts +17 -0
- package/libs/ModelViewPlugin/Plugin.js +160 -0
- package/libs/ModelViewPlugin/index.d.ts +3 -16
- package/libs/ModelViewPlugin/index.js +2 -159
- package/libs/PanoCompassPlugin/Plugin.d.ts +47 -0
- package/libs/PanoCompassPlugin/Plugin.js +249 -0
- package/libs/PanoCompassPlugin/index.d.ts +4 -47
- package/libs/PanoCompassPlugin/index.js +3 -249
- package/libs/PanoMeasurePlugin/index.d.ts +1 -1
- package/libs/PanoMeasurePlugin/index.js +1 -1
- package/libs/PanoRulerPlugin/Plugin.d.ts +31 -0
- package/libs/PanoRulerPlugin/Plugin.js +402 -0
- package/libs/PanoRulerPlugin/index.d.ts +4 -30
- package/libs/PanoRulerPlugin/index.js +2 -401
- package/libs/PanoSpatialTagPlugin/Plugin.d.ts +33 -0
- package/libs/PanoSpatialTagPlugin/Plugin.js +415 -0
- package/libs/PanoSpatialTagPlugin/index.d.ts +4 -32
- package/libs/PanoSpatialTagPlugin/index.js +4 -412
- package/libs/_index.d.ts +30 -0
- package/libs/_index.js +18 -0
- package/libs/floorplan/index.d.ts +6 -0
- package/libs/floorplan/index.js +7 -0
- package/libs/index.d.ts +15 -30
- package/libs/index.js +25 -17
- package/package.json +5 -4
|
@@ -1,140 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
|
|
4
|
-
import createCanvasTextTexture from '../shared-utils/createCanvasTextTexture';
|
|
5
|
-
import transformPositionToVector3 from '../shared-utils/three/transformPositionToVector3';
|
|
6
|
-
import transfromToMeshBasicMaterial from '../shared-utils/three/transfromToMeshBasicMaterial';
|
|
7
|
-
/**
|
|
8
|
-
* 模型入户门引导插件
|
|
9
|
-
*/
|
|
10
|
-
export const ModelEntryDoorGuidePlugin = (five, params) => {
|
|
11
|
-
var _a, _b, _c;
|
|
12
|
-
// 局部状态
|
|
13
|
-
const state = {};
|
|
14
|
-
const defaultAnimationEnable = (_a = params.animationEnabled) !== null && _a !== void 0 ? _a : true;
|
|
15
|
-
const defaultModelPosition = (_b = params.position) !== null && _b !== void 0 ? _b : undefined;
|
|
16
|
-
const defaultRad = (_c = params.rad) !== null && _c !== void 0 ? _c : undefined;
|
|
17
|
-
const defaultFbxUrl = params.fbx_url || '//vrlab-image4.ljcdn.com/release/web/entryDoorMini/Anim_Door1.fbx';
|
|
18
|
-
const mixers = [];
|
|
19
|
-
const load = async (data) => {
|
|
20
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
21
|
-
const position = (_a = data === null || data === void 0 ? void 0 : data.position) !== null && _a !== void 0 ? _a : defaultModelPosition;
|
|
22
|
-
if (!position)
|
|
23
|
-
return Promise.reject(`ModelEntryDoorGuidePlugin.load(): position is undefined`);
|
|
24
|
-
const modelPosition = transformPositionToVector3(position);
|
|
25
|
-
const rad = (_b = data === null || data === void 0 ? void 0 : data.rad) !== null && _b !== void 0 ? _b : defaultRad;
|
|
26
|
-
const fbxUrl = (_c = data === null || data === void 0 ? void 0 : data.fbx_url) !== null && _c !== void 0 ? _c : defaultFbxUrl;
|
|
27
|
-
state.rad = rad;
|
|
28
|
-
if (rad === undefined)
|
|
29
|
-
return Promise.reject(`ModelEntryDoorGuidePlugin.load(): rad is ${rad}`);
|
|
30
|
-
// 加载模型
|
|
31
|
-
const object = await new FBXLoader().loadAsync(fbxUrl);
|
|
32
|
-
// 设置位置
|
|
33
|
-
object.position.copy(modelPosition);
|
|
34
|
-
object.rotation.z = rad;
|
|
35
|
-
object.scale.set(0.8, 0.8, 0.8);
|
|
36
|
-
transfromToMeshBasicMaterial(object, { transparent: true, side: THREE.DoubleSide });
|
|
37
|
-
const textMesh = (_g = (_f = (_e = (_d = object.children) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.children) === null || _f === void 0 ? void 0 : _f[3]) === null || _g === void 0 ? void 0 : _g.clone();
|
|
38
|
-
if (!textMesh)
|
|
39
|
-
return Promise.reject(`ModelEntryDoorGuidePlugin.load(): textMesh is ${textMesh}`);
|
|
40
|
-
textMesh.material = new MeshBasicMaterial({ transparent: true, map: createCanvasTextTexture('入户门') });
|
|
41
|
-
textMesh.renderOrder = 3;
|
|
42
|
-
object.children[0].add(textMesh);
|
|
43
|
-
state.object = object;
|
|
44
|
-
return true;
|
|
45
|
-
};
|
|
46
|
-
const initAnimation = () => {
|
|
47
|
-
if (state.animation)
|
|
48
|
-
return;
|
|
49
|
-
if (!state.object)
|
|
50
|
-
return console.error('ModelEntryDoorGuidePlugin.initAnimation(): state.object is ', state.object);
|
|
51
|
-
// action
|
|
52
|
-
const animationSpeed = 1;
|
|
53
|
-
const mixer = new AnimationMixer(state.object);
|
|
54
|
-
mixers.push(mixer);
|
|
55
|
-
const action = mixer.clipAction(state.object.animations[0]);
|
|
56
|
-
action.timeScale = animationSpeed;
|
|
57
|
-
let stopAnimation;
|
|
58
|
-
const requestAnimationFrameLoop = () => {
|
|
59
|
-
let index = 0;
|
|
60
|
-
let oldTime = 0;
|
|
61
|
-
const minDeltaTime = 1000 / 30;
|
|
62
|
-
const animation = (time) => {
|
|
63
|
-
index = requestAnimationFrame(animation);
|
|
64
|
-
const deltaTime = time - oldTime;
|
|
65
|
-
if (deltaTime < minDeltaTime)
|
|
66
|
-
return;
|
|
67
|
-
oldTime = time;
|
|
68
|
-
mixers.forEach((mixer) => mixer.update(deltaTime / 1000));
|
|
69
|
-
five.needsRender = true;
|
|
70
|
-
};
|
|
71
|
-
index = requestAnimationFrame(animation);
|
|
72
|
-
return () => {
|
|
73
|
-
cancelAnimationFrame(index);
|
|
74
|
-
};
|
|
75
|
-
};
|
|
76
|
-
const play = () => {
|
|
77
|
-
if (stopAnimation)
|
|
78
|
-
return;
|
|
79
|
-
action.play();
|
|
80
|
-
stopAnimation = requestAnimationFrameLoop();
|
|
81
|
-
// 开始播动画时,rotation可能会还原
|
|
82
|
-
requestAnimationFrame(() => {
|
|
83
|
-
if (state.object && state.object.rotation.z !== state.rad)
|
|
84
|
-
state.object.rotation.z = state.rad;
|
|
85
|
-
});
|
|
86
|
-
};
|
|
87
|
-
const stop = () => {
|
|
88
|
-
action.stop();
|
|
89
|
-
stopAnimation === null || stopAnimation === void 0 ? void 0 : stopAnimation();
|
|
90
|
-
stopAnimation = undefined;
|
|
91
|
-
};
|
|
92
|
-
const animation = { play, stop };
|
|
93
|
-
state.animation = animation;
|
|
94
|
-
};
|
|
95
|
-
const show = (config) => {
|
|
96
|
-
var _a;
|
|
97
|
-
if (!state.object)
|
|
98
|
-
return console.error('ModelEntryDoorGuidePlugin.enable(): object is ', state.object);
|
|
99
|
-
const animationEnable = (_a = config === null || config === void 0 ? void 0 : config.animationEnable) !== null && _a !== void 0 ? _a : defaultAnimationEnable;
|
|
100
|
-
if (animationEnable) {
|
|
101
|
-
if (!state.animation)
|
|
102
|
-
initAnimation();
|
|
103
|
-
state.animation.play();
|
|
104
|
-
}
|
|
105
|
-
five.scene.add(state.object);
|
|
106
|
-
five.needsRender = true;
|
|
107
|
-
};
|
|
108
|
-
const hide = () => {
|
|
109
|
-
if (!state.object)
|
|
110
|
-
return;
|
|
111
|
-
if (state.animation)
|
|
112
|
-
state.animation.stop();
|
|
113
|
-
five.scene.remove(state.object);
|
|
114
|
-
five.needsRender = true;
|
|
115
|
-
};
|
|
116
|
-
const modeChangeHandler = (mode) => (mode === 'Floorplan' ? show() : hide());
|
|
117
|
-
const enable = (config) => {
|
|
118
|
-
if (state.enabled)
|
|
119
|
-
return true;
|
|
120
|
-
state.enabled = true;
|
|
121
|
-
modeChangeHandler(five.currentMode);
|
|
122
|
-
five.on('modeChange', modeChangeHandler);
|
|
123
|
-
show(config);
|
|
124
|
-
return true;
|
|
125
|
-
};
|
|
126
|
-
const disable = () => {
|
|
127
|
-
if (!state.enabled)
|
|
128
|
-
return true;
|
|
129
|
-
state.enabled = false;
|
|
130
|
-
hide();
|
|
131
|
-
five.off('modeChange', modeChangeHandler);
|
|
132
|
-
return true;
|
|
133
|
-
};
|
|
134
|
-
return { load, enable, disable };
|
|
135
|
-
};
|
|
136
|
-
export const modelEntryDoorGuidePluginServerParams = {
|
|
137
|
-
name: 'ModelEntryDoorGuidePlugin',
|
|
138
|
-
version: 0,
|
|
139
|
-
};
|
|
1
|
+
import ModelEntryDoorGuidePlugin from './Plugin';
|
|
2
|
+
export { ModelEntryDoorGuidePlugin };
|
|
140
3
|
export default ModelEntryDoorGuidePlugin;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FivePlugin } from "@realsee/five";
|
|
2
|
+
import { ModelItemLabelPluginExportReturnsType, ModelItemLabelPluginParametersType } from "./typings";
|
|
3
|
+
export declare const ModelItemLabelPlugin: FivePlugin<ModelItemLabelPluginParametersType, ModelItemLabelPluginExportReturnsType>;
|
|
4
|
+
export default ModelItemLabelPlugin;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Five, Subscribe } from "@realsee/five";
|
|
2
|
+
import ItemLabelComponent from './ItemLabelComponent';
|
|
3
|
+
import { DISPLAY_STRATEGY_TYPE } from "./typings";
|
|
4
|
+
import { parseModelItemLabelPluginData } from "./utils/parseData";
|
|
5
|
+
export const ModelItemLabelPlugin = (five, params) => {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
const pluginState = {
|
|
8
|
+
container: document.createElement('div'),
|
|
9
|
+
data: null,
|
|
10
|
+
enabled: true,
|
|
11
|
+
fiveModeEnabled: undefined,
|
|
12
|
+
itemLabels: [],
|
|
13
|
+
wrapper: null,
|
|
14
|
+
app: undefined,
|
|
15
|
+
hooks: new Subscribe(),
|
|
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,
|
|
18
|
+
};
|
|
19
|
+
pluginState.container.setAttribute('class', 'model-item-label-plugin-container');
|
|
20
|
+
pluginState.container.style.cssText = `
|
|
21
|
+
position: absolute;
|
|
22
|
+
left: 0;
|
|
23
|
+
top: 0;
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
z-index: 5;
|
|
27
|
+
`;
|
|
28
|
+
pluginState.container.style.pointerEvents = 'none'; // 写到 cssText 里不生效
|
|
29
|
+
const appendTo = (wrapper) => {
|
|
30
|
+
pluginState.wrapper = wrapper;
|
|
31
|
+
wrapper.appendChild(pluginState.container);
|
|
32
|
+
render();
|
|
33
|
+
return true;
|
|
34
|
+
};
|
|
35
|
+
const load = (data) => {
|
|
36
|
+
pluginState.itemLabels = parseModelItemLabelPluginData(data);
|
|
37
|
+
render();
|
|
38
|
+
};
|
|
39
|
+
const enable = () => {
|
|
40
|
+
if (pluginState.enabled)
|
|
41
|
+
return true;
|
|
42
|
+
pluginState.enabled = true;
|
|
43
|
+
render();
|
|
44
|
+
return true;
|
|
45
|
+
};
|
|
46
|
+
const disable = () => {
|
|
47
|
+
if (!pluginState.enabled)
|
|
48
|
+
return true;
|
|
49
|
+
pluginState.enabled = false;
|
|
50
|
+
render();
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
53
|
+
const dispose = () => {
|
|
54
|
+
removeListener4Five();
|
|
55
|
+
pluginState.container.remove();
|
|
56
|
+
};
|
|
57
|
+
const render = () => {
|
|
58
|
+
var _a;
|
|
59
|
+
if (!pluginState.wrapper)
|
|
60
|
+
return;
|
|
61
|
+
// 只要不可展示,销毁容器
|
|
62
|
+
if (!pluginState.enabled || !pluginState.fiveModeEnabled) {
|
|
63
|
+
(_a = pluginState.app) === null || _a === void 0 ? void 0 : _a.$destroy();
|
|
64
|
+
pluginState.app = undefined;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// 正常显示时,分为 app 存在和不存在两种情况,如果存在,传值,不存在则初始化并传值
|
|
68
|
+
if (!pluginState.app) {
|
|
69
|
+
pluginState.app = new ItemLabelComponent({
|
|
70
|
+
target: pluginState.container,
|
|
71
|
+
props: {
|
|
72
|
+
five: five,
|
|
73
|
+
modelOcclusionEnable: pluginState.modelOcclusionEnable,
|
|
74
|
+
itemLabels: pluginState.itemLabels,
|
|
75
|
+
wrapper: pluginState.wrapper,
|
|
76
|
+
hooks: pluginState.hooks,
|
|
77
|
+
displayStrategyType: pluginState.displayStrategyType
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
pluginState.app.$set({
|
|
83
|
+
five: five,
|
|
84
|
+
itemLabels: pluginState.itemLabels
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
// 添加 five 监听
|
|
89
|
+
const addListener4Five = () => {
|
|
90
|
+
five.on('modeChange', onFiveModeChange);
|
|
91
|
+
five.once('dispose', dispose);
|
|
92
|
+
};
|
|
93
|
+
// 取消 five 监听
|
|
94
|
+
const removeListener4Five = () => {
|
|
95
|
+
five.off('modeChange', onFiveModeChange);
|
|
96
|
+
};
|
|
97
|
+
const onFiveModeChange = (mode) => {
|
|
98
|
+
if (!pluginState.enabled)
|
|
99
|
+
return;
|
|
100
|
+
if (mode !== Five.Mode.Floorplan) {
|
|
101
|
+
pluginState.fiveModeEnabled = false;
|
|
102
|
+
render();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
five.once('initAnimationEnded', () => {
|
|
106
|
+
pluginState.fiveModeEnabled = five.currentMode === Five.Mode.Floorplan;
|
|
107
|
+
render();
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
addListener4Five();
|
|
111
|
+
return {
|
|
112
|
+
appendTo,
|
|
113
|
+
load,
|
|
114
|
+
enable,
|
|
115
|
+
disable,
|
|
116
|
+
dispose,
|
|
117
|
+
hooks: pluginState.hooks
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
export default ModelItemLabelPlugin;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export declare const ModelItemLabelPlugin: FivePlugin<ModelItemLabelPluginParametersType, ModelItemLabelPluginExportReturnsType>;
|
|
1
|
+
import ModelItemLabelPlugin from './ModelItemLabelPlugin';
|
|
2
|
+
export { ModelItemLabelPlugin };
|
|
4
3
|
export default ModelItemLabelPlugin;
|
|
4
|
+
export declare const modelItemLabelPluginServerParams: {
|
|
5
|
+
name: string;
|
|
6
|
+
version: number;
|
|
7
|
+
};
|
|
8
|
+
export type { ModelItemLabelPluginParametersType, ModelItemLabelPluginData, ModelItemLabelPluginExportReturnsType } from './typings';
|
|
9
|
+
export { DISPLAY_STRATEGY_TYPE } from './typings';
|
|
@@ -1,120 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { DISPLAY_STRATEGY_TYPE } from "./typings";
|
|
4
|
-
import { parseModelItemLabelPluginData } from "./utils/parseData";
|
|
5
|
-
export const ModelItemLabelPlugin = (five, params) => {
|
|
6
|
-
var _a, _b;
|
|
7
|
-
const pluginState = {
|
|
8
|
-
container: document.createElement('div'),
|
|
9
|
-
data: null,
|
|
10
|
-
enabled: true,
|
|
11
|
-
fiveModeEnabled: undefined,
|
|
12
|
-
itemLabels: [],
|
|
13
|
-
wrapper: null,
|
|
14
|
-
app: undefined,
|
|
15
|
-
hooks: new Subscribe(),
|
|
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,
|
|
18
|
-
};
|
|
19
|
-
pluginState.container.setAttribute('class', 'model-item-label-plugin-container');
|
|
20
|
-
pluginState.container.style.cssText = `
|
|
21
|
-
position: absolute;
|
|
22
|
-
left: 0;
|
|
23
|
-
top: 0;
|
|
24
|
-
width: 100%;
|
|
25
|
-
height: 100%;
|
|
26
|
-
z-index: 5;
|
|
27
|
-
`;
|
|
28
|
-
pluginState.container.style.pointerEvents = 'none'; // 写到 cssText 里不生效
|
|
29
|
-
const appendTo = (wrapper) => {
|
|
30
|
-
pluginState.wrapper = wrapper;
|
|
31
|
-
wrapper.appendChild(pluginState.container);
|
|
32
|
-
render();
|
|
33
|
-
return true;
|
|
34
|
-
};
|
|
35
|
-
const load = (data) => {
|
|
36
|
-
pluginState.itemLabels = parseModelItemLabelPluginData(data);
|
|
37
|
-
render();
|
|
38
|
-
};
|
|
39
|
-
const enable = () => {
|
|
40
|
-
if (pluginState.enabled)
|
|
41
|
-
return true;
|
|
42
|
-
pluginState.enabled = true;
|
|
43
|
-
render();
|
|
44
|
-
return true;
|
|
45
|
-
};
|
|
46
|
-
const disable = () => {
|
|
47
|
-
if (!pluginState.enabled)
|
|
48
|
-
return true;
|
|
49
|
-
pluginState.enabled = false;
|
|
50
|
-
render();
|
|
51
|
-
return true;
|
|
52
|
-
};
|
|
53
|
-
const dispose = () => {
|
|
54
|
-
removeListener4Five();
|
|
55
|
-
pluginState.container.remove();
|
|
56
|
-
};
|
|
57
|
-
const render = () => {
|
|
58
|
-
var _a;
|
|
59
|
-
if (!pluginState.wrapper)
|
|
60
|
-
return;
|
|
61
|
-
// 只要不可展示,销毁容器
|
|
62
|
-
if (!pluginState.enabled || !pluginState.fiveModeEnabled) {
|
|
63
|
-
(_a = pluginState.app) === null || _a === void 0 ? void 0 : _a.$destroy();
|
|
64
|
-
pluginState.app = undefined;
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
// 正常显示时,分为 app 存在和不存在两种情况,如果存在,传值,不存在则初始化并传值
|
|
68
|
-
if (!pluginState.app) {
|
|
69
|
-
pluginState.app = new ItemLabelComponent({
|
|
70
|
-
target: pluginState.container,
|
|
71
|
-
props: {
|
|
72
|
-
five: five,
|
|
73
|
-
modelOcclusionEnable: pluginState.modelOcclusionEnable,
|
|
74
|
-
itemLabels: pluginState.itemLabels,
|
|
75
|
-
wrapper: pluginState.wrapper,
|
|
76
|
-
hooks: pluginState.hooks,
|
|
77
|
-
displayStrategyType: pluginState.displayStrategyType
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
pluginState.app.$set({
|
|
83
|
-
five: five,
|
|
84
|
-
itemLabels: pluginState.itemLabels
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
// 添加 five 监听
|
|
89
|
-
const addListener4Five = () => {
|
|
90
|
-
five.on('modeChange', onFiveModeChange);
|
|
91
|
-
five.once('dispose', dispose);
|
|
92
|
-
};
|
|
93
|
-
// 取消 five 监听
|
|
94
|
-
const removeListener4Five = () => {
|
|
95
|
-
five.off('modeChange', onFiveModeChange);
|
|
96
|
-
};
|
|
97
|
-
const onFiveModeChange = (mode) => {
|
|
98
|
-
if (!pluginState.enabled)
|
|
99
|
-
return;
|
|
100
|
-
if (mode !== Five.Mode.Floorplan) {
|
|
101
|
-
pluginState.fiveModeEnabled = false;
|
|
102
|
-
render();
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
five.once('initAnimationEnded', () => {
|
|
106
|
-
pluginState.fiveModeEnabled = five.currentMode === Five.Mode.Floorplan;
|
|
107
|
-
render();
|
|
108
|
-
});
|
|
109
|
-
};
|
|
110
|
-
addListener4Five();
|
|
111
|
-
return {
|
|
112
|
-
appendTo,
|
|
113
|
-
load,
|
|
114
|
-
enable,
|
|
115
|
-
disable,
|
|
116
|
-
dispose,
|
|
117
|
-
hooks: pluginState.hooks
|
|
118
|
-
};
|
|
119
|
-
};
|
|
1
|
+
import ModelItemLabelPlugin from './ModelItemLabelPlugin';
|
|
2
|
+
export { ModelItemLabelPlugin };
|
|
120
3
|
export default ModelItemLabelPlugin;
|
|
4
|
+
export const modelItemLabelPluginServerParams = {
|
|
5
|
+
name: 'ModelItemLabelPlugin',
|
|
6
|
+
version: 0,
|
|
7
|
+
};
|
|
8
|
+
export { DISPLAY_STRATEGY_TYPE } from './typings';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FivePlugin } from '@realsee/five';
|
|
2
|
+
import type { ModelTVVideoPluginExportType, ModelTVVideoPluginParameterType } from "./typings";
|
|
3
|
+
export declare const ModelTVVideoPlugin: FivePlugin<ModelTVVideoPluginParameterType, ModelTVVideoPluginExportType>;
|
|
4
|
+
export default ModelTVVideoPlugin;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { parseModelTVVideoPoints } from "./utils/parseData";
|
|
3
|
+
export const ModelTVVideoPlugin = (five, { videoElement }) => {
|
|
4
|
+
const state = {
|
|
5
|
+
videoMeshes: [],
|
|
6
|
+
videoTextureEnabled: false,
|
|
7
|
+
videoSource: '',
|
|
8
|
+
rectPoints: [],
|
|
9
|
+
enabled: false,
|
|
10
|
+
videoElement: videoElement,
|
|
11
|
+
};
|
|
12
|
+
const setMuted = (muted) => {
|
|
13
|
+
if (state.videoTexture) {
|
|
14
|
+
state.videoTexture.image.muted = muted;
|
|
15
|
+
state.videoTexture.image.play();
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const getMuted = () => {
|
|
19
|
+
if (state.videoTexture)
|
|
20
|
+
return state.videoTexture.image.muted;
|
|
21
|
+
else
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
24
|
+
const enable = () => {
|
|
25
|
+
if (state.enabled)
|
|
26
|
+
return;
|
|
27
|
+
if (!state.videoTexture)
|
|
28
|
+
return;
|
|
29
|
+
state.enabled = true;
|
|
30
|
+
state.videoMeshes = createPanoVideoMeshes();
|
|
31
|
+
console.log('state.videoMeshes', state.videoMeshes);
|
|
32
|
+
state.videoMeshes.forEach((mesh) => five.scene.add(mesh));
|
|
33
|
+
const play = () => {
|
|
34
|
+
console.log('play', state.videoTexture);
|
|
35
|
+
if (!state.videoTexture)
|
|
36
|
+
return;
|
|
37
|
+
const timeupdate = () => {
|
|
38
|
+
var _a;
|
|
39
|
+
if (!state.videoTexture)
|
|
40
|
+
return;
|
|
41
|
+
(_a = state.videoTexture) === null || _a === void 0 ? void 0 : _a.image.removeEventListener('timeupdate', timeupdate);
|
|
42
|
+
state.videoTextureEnabled = true;
|
|
43
|
+
state.videoMeshes.forEach((mesh) => {
|
|
44
|
+
if (mesh.material.map !== state.videoTexture)
|
|
45
|
+
mesh.material.map = state.videoTexture;
|
|
46
|
+
});
|
|
47
|
+
five.needsRender = true;
|
|
48
|
+
};
|
|
49
|
+
state.videoTexture.image.addEventListener('timeupdate', timeupdate);
|
|
50
|
+
if (state.videoTexture && state.videoMeshes.length) {
|
|
51
|
+
state.videoTexture.image.play();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
if (five.model.loaded)
|
|
55
|
+
play();
|
|
56
|
+
else {
|
|
57
|
+
return five.once('modelLoaded', () => play());
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const disable = () => {
|
|
61
|
+
if (!state.enabled)
|
|
62
|
+
return;
|
|
63
|
+
state.enabled = false;
|
|
64
|
+
state.videoMeshes.forEach((mesh) => {
|
|
65
|
+
mesh.geometry.dispose();
|
|
66
|
+
mesh.material.dispose();
|
|
67
|
+
five.scene.remove(mesh);
|
|
68
|
+
if (state.videoTexture)
|
|
69
|
+
state.videoTexture.image.pause();
|
|
70
|
+
});
|
|
71
|
+
state.videoMeshes = [];
|
|
72
|
+
five.needsRender = true;
|
|
73
|
+
};
|
|
74
|
+
const createPanoVideoMeshes = () => {
|
|
75
|
+
return state.rectPoints.map((points, index) => {
|
|
76
|
+
const geometry = new THREE.BufferGeometry();
|
|
77
|
+
const segments = 128;
|
|
78
|
+
const verticesArray = [];
|
|
79
|
+
verticesArray.push(points[0].x, points[0].y, points[0].z);
|
|
80
|
+
for (let i = 1; i < segments; i++) {
|
|
81
|
+
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);
|
|
82
|
+
}
|
|
83
|
+
verticesArray.push(points[1].x, points[1].y, points[1].z);
|
|
84
|
+
verticesArray.push(points[2].x, points[2].y, points[2].z);
|
|
85
|
+
for (let i = 1; i < segments; i++) {
|
|
86
|
+
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);
|
|
87
|
+
}
|
|
88
|
+
verticesArray.push(points[3].x, points[3].y, points[3].z);
|
|
89
|
+
const uvArray = [];
|
|
90
|
+
uvArray.push(0, 1);
|
|
91
|
+
for (let i = 1; i < segments; i++) {
|
|
92
|
+
uvArray.push(0, 1 - i / segments);
|
|
93
|
+
}
|
|
94
|
+
uvArray.push(0, 0);
|
|
95
|
+
uvArray.push(1, 0);
|
|
96
|
+
for (let i = 1; i < segments; i++) {
|
|
97
|
+
uvArray.push(1, i / segments);
|
|
98
|
+
}
|
|
99
|
+
uvArray.push(1, 1);
|
|
100
|
+
const indicesArray = [];
|
|
101
|
+
for (let i = 0; i < segments; i++) {
|
|
102
|
+
indicesArray.push(i, i + 1, segments * 2 - i, i, segments * 2 - i, segments * 2 + 1 - i);
|
|
103
|
+
}
|
|
104
|
+
geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(verticesArray), 3));
|
|
105
|
+
geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvArray), 2));
|
|
106
|
+
geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(indicesArray), 1));
|
|
107
|
+
const material = new THREE.MeshBasicMaterial({
|
|
108
|
+
map: state.videoTextureEnabled ? state.videoTexture : state.imageTexture,
|
|
109
|
+
side: THREE.DoubleSide,
|
|
110
|
+
});
|
|
111
|
+
const mesh = new THREE.Mesh(geometry, material);
|
|
112
|
+
mesh.renderOrder = 1;
|
|
113
|
+
mesh.name = `ModelTVVideoPlugin-${index}-${performance.now()}`;
|
|
114
|
+
return mesh;
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
const getImageTexture = (source) => {
|
|
118
|
+
const texture = new THREE.TextureLoader().load(source);
|
|
119
|
+
texture.minFilter = THREE.LinearFilter;
|
|
120
|
+
texture.magFilter = THREE.LinearFilter;
|
|
121
|
+
texture.format = THREE.RGBFormat;
|
|
122
|
+
return texture;
|
|
123
|
+
};
|
|
124
|
+
const getVideoTexture = (source, video) => {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
const xhr = new XMLHttpRequest();
|
|
127
|
+
xhr.onreadystatechange = () => {
|
|
128
|
+
if (xhr.readyState == 4) {
|
|
129
|
+
if (xhr.status == 200) {
|
|
130
|
+
const url = window.URL || window.webkitURL;
|
|
131
|
+
video = video || document.createElement('video');
|
|
132
|
+
video.crossOrigin = 'anonymous';
|
|
133
|
+
video.autoplay = true;
|
|
134
|
+
video.muted = true;
|
|
135
|
+
video.loop = true;
|
|
136
|
+
video.playsInline = true;
|
|
137
|
+
video.src = url.createObjectURL(xhr.response);
|
|
138
|
+
const texture = new THREE.VideoTexture(video);
|
|
139
|
+
texture.minFilter = THREE.LinearFilter;
|
|
140
|
+
texture.magFilter = THREE.LinearFilter;
|
|
141
|
+
texture.format = THREE.RGBFormat;
|
|
142
|
+
resolve(Object.assign(texture, { videoSource: source }));
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
reject(new Error('Video download Error: ' + xhr.status));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
xhr.onerror = (error) => reject(error);
|
|
150
|
+
xhr.open('GET', source);
|
|
151
|
+
xhr.responseType = 'blob';
|
|
152
|
+
xhr.send();
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
const load = async (data, videoElement) => {
|
|
156
|
+
const { video_src, video_poster_src, points } = data;
|
|
157
|
+
state.videoSource = video_src;
|
|
158
|
+
// TODO 存疑,先处理多一次遍历 o(2n)
|
|
159
|
+
state.rectPoints = parseModelTVVideoPoints(points)
|
|
160
|
+
.map((items) => items.map(({ x, y, z }) => new THREE.Vector3(x, y, z)));
|
|
161
|
+
state.imageTexture = getImageTexture(video_poster_src);
|
|
162
|
+
if (videoElement) {
|
|
163
|
+
state.videoElement = videoElement;
|
|
164
|
+
}
|
|
165
|
+
state.videoTexture = await getVideoTexture(state.videoSource, state.videoElement);
|
|
166
|
+
state.enabled = !!data.enable;
|
|
167
|
+
if (state.enabled)
|
|
168
|
+
enable();
|
|
169
|
+
};
|
|
170
|
+
const dispose = () => {
|
|
171
|
+
disable();
|
|
172
|
+
state.videoTexture = undefined;
|
|
173
|
+
five.off('modeChange', () => setMuted(true));
|
|
174
|
+
five.off('wantsTapGesture', (raycaster) => {
|
|
175
|
+
if (!state.enabled)
|
|
176
|
+
return;
|
|
177
|
+
const [intersect] = raycaster.intersectObjects(five.scene.children, true);
|
|
178
|
+
if (!!intersect && /^video/.test(intersect.object.name)) {
|
|
179
|
+
if (state.videoTexture)
|
|
180
|
+
setMuted(!state.videoTexture.image.muted);
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
five.off('panoArrived', () => {
|
|
185
|
+
if (!state.enabled)
|
|
186
|
+
return;
|
|
187
|
+
if (getMuted())
|
|
188
|
+
return;
|
|
189
|
+
const cameraPosition = five.camera.position;
|
|
190
|
+
const visible = state.rectPoints.find((points) => {
|
|
191
|
+
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());
|
|
192
|
+
return (points.map((point) => new THREE.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
|
|
193
|
+
vector = vector.clone().sub(cameraPosition).normalize();
|
|
194
|
+
const raycaster = new THREE.Raycaster(cameraPosition, vector);
|
|
195
|
+
const [intersect] = raycaster.intersectObjects(five.scene.children, true);
|
|
196
|
+
return !!intersect && /^video/.test(intersect.object.name);
|
|
197
|
+
}).length >= 2);
|
|
198
|
+
});
|
|
199
|
+
if (!visible)
|
|
200
|
+
setMuted(true);
|
|
201
|
+
});
|
|
202
|
+
five.off('renderFrame', () => {
|
|
203
|
+
// console.log('renderFrame', state.videoMeshes)
|
|
204
|
+
state.videoMeshes.forEach((meshes) => {
|
|
205
|
+
if (meshes)
|
|
206
|
+
//@ts-ignore
|
|
207
|
+
meshes.needsRender = true;
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
five.on('modeChange', () => setMuted(true));
|
|
212
|
+
five.on('wantsTapGesture', (raycaster) => {
|
|
213
|
+
if (!state.enabled)
|
|
214
|
+
return;
|
|
215
|
+
const targetMesh = five.scene.children.find(item => /^ModelTVVideoPlugin/.test(item.name));
|
|
216
|
+
if (!targetMesh)
|
|
217
|
+
return;
|
|
218
|
+
const intersectObjects = raycaster.intersectObjects([targetMesh]);
|
|
219
|
+
if (intersectObjects.length === 0)
|
|
220
|
+
return;
|
|
221
|
+
if (state.videoTexture)
|
|
222
|
+
setMuted(!state.videoTexture.image.muted); // TODO toggle video play
|
|
223
|
+
return false;
|
|
224
|
+
});
|
|
225
|
+
five.on('panoArrived', () => {
|
|
226
|
+
if (!state.enabled)
|
|
227
|
+
return;
|
|
228
|
+
if (getMuted())
|
|
229
|
+
return;
|
|
230
|
+
const cameraPosition = five.camera.position;
|
|
231
|
+
const visible = state.rectPoints.find((points) => {
|
|
232
|
+
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());
|
|
233
|
+
return (points.map((point) => new THREE.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
|
|
234
|
+
vector = vector.clone().sub(cameraPosition).normalize();
|
|
235
|
+
const raycaster = new THREE.Raycaster(cameraPosition, vector);
|
|
236
|
+
const [intersect] = raycaster.intersectObjects(five.scene.children, true);
|
|
237
|
+
return !!intersect && /^video/.test(intersect.object.name);
|
|
238
|
+
}).length >= 2);
|
|
239
|
+
});
|
|
240
|
+
if (!visible)
|
|
241
|
+
setMuted(true);
|
|
242
|
+
});
|
|
243
|
+
five.on('renderFrame', () => {
|
|
244
|
+
// console.log('renderFrame', state.videoMeshes)
|
|
245
|
+
state.videoMeshes.forEach((meshes) => {
|
|
246
|
+
if (meshes)
|
|
247
|
+
//@ts-ignore
|
|
248
|
+
meshes.needsRender = true;
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
Object.assign(window, { $state: state });
|
|
252
|
+
return { enable, disable, load, dispose };
|
|
253
|
+
};
|
|
254
|
+
export default ModelTVVideoPlugin;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export declare const ModelTVVideoPlugin: FivePlugin<ModelTVVideoPluginParameterType, ModelTVVideoPluginExportType>;
|
|
1
|
+
import ModelTVVideoPlugin from './Plugin';
|
|
2
|
+
export { ModelTVVideoPlugin };
|
|
4
3
|
export default ModelTVVideoPlugin;
|
|
4
|
+
export type { ModelTVVideoPluginParameterType, ModelTVVideoPluginData, Point, ModelTVVideoPluginExportType } from './typings';
|
|
5
|
+
export { DIRECTION } from './typings';
|