@realsee/dnalogel 2.0.0-alpha.26-beta → 2.0.0-alpha.28-beta
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 +10 -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 +14 -8
- package/dist/ModelRoomLabelPlugin/index.js +82 -46
- 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/index.d.ts +16 -29
- package/dist/index.es.js +122 -70
- package/dist/index.js +145 -90
- package/dist/index.umd.js +145 -90
- package/docs/assets/search.js +1 -1
- package/docs/classes/ModelRoomLabelController.html +6 -6
- 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 +1 -1
- package/docs/interfaces/CSS3DRenderPluginExportType.html +4 -0
- package/docs/interfaces/CameraMovementPluginExportType.html +17 -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 +2 -2
- 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 +8 -8
- package/docs/modules.html +20 -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/ItemLabelComponent.js +1 -1
- 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/ModelRoomLabelPlugin/RoomLabelItems.js +83 -47
- 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/index.d.ts +16 -29
- package/libs/index.js +25 -16
- package/package.json +6 -5
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Five 模型插件
|
|
4
|
+
* @template ExportType 导出方法
|
|
5
|
+
*/
|
|
6
|
+
export const ModelViewPlugin = (five) => {
|
|
7
|
+
let needsRender = true;
|
|
8
|
+
let renderer = null;
|
|
9
|
+
const scene = new THREE.Scene();
|
|
10
|
+
const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 1000);
|
|
11
|
+
let model = new THREE.Object3D();
|
|
12
|
+
{
|
|
13
|
+
const light = new THREE.DirectionalLight(0xffffff, 0.5);
|
|
14
|
+
light.position.copy(new THREE.Vector3(1, 1, 1));
|
|
15
|
+
scene.add(light);
|
|
16
|
+
}
|
|
17
|
+
{
|
|
18
|
+
const light = new THREE.DirectionalLight(0xffffff, 0.3);
|
|
19
|
+
scene.add(light);
|
|
20
|
+
}
|
|
21
|
+
{
|
|
22
|
+
const light = new THREE.AmbientLight(0xffffff, 0.3);
|
|
23
|
+
scene.add(light);
|
|
24
|
+
}
|
|
25
|
+
scene.add(model);
|
|
26
|
+
const initRendererIfNeeds = () => {
|
|
27
|
+
if (!five.renderer)
|
|
28
|
+
return;
|
|
29
|
+
if (!renderer) {
|
|
30
|
+
renderer = new THREE.WebGLRenderer({ antialias: false, alpha: true });
|
|
31
|
+
renderer.setPixelRatio(five.renderer.getPixelRatio());
|
|
32
|
+
renderer.outputEncoding = THREE.sRGBEncoding;
|
|
33
|
+
renderer.setClearColor(0x181a1c, 0);
|
|
34
|
+
renderer.autoClear = true;
|
|
35
|
+
}
|
|
36
|
+
return renderer;
|
|
37
|
+
};
|
|
38
|
+
const handleModelWillLoad = () => {
|
|
39
|
+
model.traverse((object) => {
|
|
40
|
+
if (object instanceof THREE.Mesh) {
|
|
41
|
+
const materials = [].concat(object.material);
|
|
42
|
+
materials.forEach((material) => material.dispose());
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
scene.remove(model);
|
|
46
|
+
model = new THREE.Object3D();
|
|
47
|
+
scene.add(model);
|
|
48
|
+
update();
|
|
49
|
+
};
|
|
50
|
+
const handleModelLoaded = () => {
|
|
51
|
+
function cloneMaterial(material) {
|
|
52
|
+
material = material.clone();
|
|
53
|
+
material.uniforms.modelAlpha.value = 1;
|
|
54
|
+
if (material.uniforms.map.value) {
|
|
55
|
+
material.uniforms.map.value.needsUpdate = true;
|
|
56
|
+
}
|
|
57
|
+
return material;
|
|
58
|
+
}
|
|
59
|
+
function cloneModel(model) {
|
|
60
|
+
if (model instanceof THREE.Mesh) {
|
|
61
|
+
const geometry = model.geometry;
|
|
62
|
+
const material = Array.isArray(model.material)
|
|
63
|
+
? model.material.map(cloneMaterial)
|
|
64
|
+
: cloneMaterial(model.material);
|
|
65
|
+
return new THREE.Mesh(geometry, material);
|
|
66
|
+
}
|
|
67
|
+
else if (model instanceof THREE.Group) {
|
|
68
|
+
const group = new THREE.Group();
|
|
69
|
+
model.children.forEach((object) => group.add(cloneModel(object)));
|
|
70
|
+
return group;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const object3D = new THREE.Object3D();
|
|
74
|
+
model.children.forEach((object) => object3D.add(cloneModel(object)));
|
|
75
|
+
return object3D;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
scene.remove(model);
|
|
79
|
+
model = cloneModel(five.model);
|
|
80
|
+
scene.add(model);
|
|
81
|
+
update();
|
|
82
|
+
};
|
|
83
|
+
const appendTo = (element, size = {}) => {
|
|
84
|
+
const renderer = initRendererIfNeeds();
|
|
85
|
+
if (!renderer)
|
|
86
|
+
return;
|
|
87
|
+
element.appendChild(renderer.domElement);
|
|
88
|
+
refresh(size);
|
|
89
|
+
const positionType = window.getComputedStyle(element).position;
|
|
90
|
+
if (positionType !== 'relative' &&
|
|
91
|
+
positionType !== 'absolute' &&
|
|
92
|
+
positionType !== 'fixed' &&
|
|
93
|
+
positionType !== 'sticky')
|
|
94
|
+
element.style.position = 'relative';
|
|
95
|
+
};
|
|
96
|
+
const refresh = (size = {}) => {
|
|
97
|
+
if (!renderer)
|
|
98
|
+
return;
|
|
99
|
+
const element = renderer.domElement;
|
|
100
|
+
const container = element.parentNode;
|
|
101
|
+
if (container && container.nodeName) {
|
|
102
|
+
const { width = container.offsetWidth, height = container.offsetHeight } = size;
|
|
103
|
+
renderer.setSize(width, height);
|
|
104
|
+
// 修改摄像机 aspect 比值
|
|
105
|
+
camera.aspect = width / height;
|
|
106
|
+
camera.updateProjectionMatrix();
|
|
107
|
+
}
|
|
108
|
+
update();
|
|
109
|
+
};
|
|
110
|
+
const cameraDistance = () => {
|
|
111
|
+
const bounding = five.model.bounding;
|
|
112
|
+
const { fov, aspect } = camera;
|
|
113
|
+
const radius = Math.sqrt(Math.pow(bounding.max.x - bounding.min.x + 2, 2) +
|
|
114
|
+
Math.pow(bounding.max.y - bounding.min.y + 2, 2) +
|
|
115
|
+
Math.pow(bounding.max.z - bounding.min.z + 2, 2));
|
|
116
|
+
// fit screen
|
|
117
|
+
let distance = radius / 2 / Math.tan((Math.PI * fov) / 360);
|
|
118
|
+
if (aspect < 1)
|
|
119
|
+
distance = distance / aspect;
|
|
120
|
+
return isNaN(distance) ? radius : distance;
|
|
121
|
+
};
|
|
122
|
+
const update = () => {
|
|
123
|
+
const { longitude, latitude } = five.getPose();
|
|
124
|
+
const distance = cameraDistance();
|
|
125
|
+
const lookAt = five.model.bounding.getCenter(new THREE.Vector3());
|
|
126
|
+
const longitudeDistance = distance * Math.cos(latitude);
|
|
127
|
+
const cameraPosition = new THREE.Vector3();
|
|
128
|
+
cameraPosition.x = Math.sin(longitude) * longitudeDistance + lookAt.x;
|
|
129
|
+
cameraPosition.z = Math.cos(longitude) * longitudeDistance + lookAt.z;
|
|
130
|
+
cameraPosition.y = Math.sin(latitude) * distance + lookAt.y;
|
|
131
|
+
camera.position.copy(cameraPosition);
|
|
132
|
+
camera.lookAt(lookAt);
|
|
133
|
+
needsRender = true;
|
|
134
|
+
};
|
|
135
|
+
const render = () => {
|
|
136
|
+
if (needsRender !== true)
|
|
137
|
+
return;
|
|
138
|
+
if (!renderer)
|
|
139
|
+
return;
|
|
140
|
+
if (!renderer.domElement.parentNode)
|
|
141
|
+
return;
|
|
142
|
+
const parentNode = renderer.domElement.parentNode;
|
|
143
|
+
if (parentNode.offsetWidth === 0)
|
|
144
|
+
return;
|
|
145
|
+
renderer.render(scene, camera);
|
|
146
|
+
needsRender = false;
|
|
147
|
+
};
|
|
148
|
+
const dispose = () => {
|
|
149
|
+
if (renderer)
|
|
150
|
+
renderer.dispose();
|
|
151
|
+
renderer = null;
|
|
152
|
+
};
|
|
153
|
+
five.on('modelLoaded', handleModelLoaded);
|
|
154
|
+
five.on('modelWillLoad', handleModelWillLoad);
|
|
155
|
+
five.on('cameraDirectionUpdate', update);
|
|
156
|
+
five.on('dispose', dispose);
|
|
157
|
+
five.on('renderFrame', render);
|
|
158
|
+
return { appendTo, refresh };
|
|
159
|
+
};
|
|
160
|
+
export default ModelViewPlugin;
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
export
|
|
3
|
-
appendTo(element: HTMLElement, size?: {
|
|
4
|
-
width?: number;
|
|
5
|
-
height?: number;
|
|
6
|
-
}): void;
|
|
7
|
-
refresh(size?: {
|
|
8
|
-
width?: number;
|
|
9
|
-
height?: number;
|
|
10
|
-
}): void;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Five 模型插件
|
|
14
|
-
* @template ExportType 导出方法
|
|
15
|
-
*/
|
|
16
|
-
export declare const ModelViewPlugin: FivePlugin<void, ModelViewPluginExportType>;
|
|
1
|
+
import ModelViewPlugin from './Plugin';
|
|
2
|
+
export { ModelViewPlugin };
|
|
17
3
|
export default ModelViewPlugin;
|
|
4
|
+
export type { ModelViewPluginExportType } from './Plugin';
|
|
@@ -1,160 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
* Five 模型插件
|
|
4
|
-
* @template ExportType 导出方法
|
|
5
|
-
*/
|
|
6
|
-
export const ModelViewPlugin = (five) => {
|
|
7
|
-
let needsRender = true;
|
|
8
|
-
let renderer = null;
|
|
9
|
-
const scene = new THREE.Scene();
|
|
10
|
-
const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 1000);
|
|
11
|
-
let model = new THREE.Object3D();
|
|
12
|
-
{
|
|
13
|
-
const light = new THREE.DirectionalLight(0xffffff, 0.5);
|
|
14
|
-
light.position.copy(new THREE.Vector3(1, 1, 1));
|
|
15
|
-
scene.add(light);
|
|
16
|
-
}
|
|
17
|
-
{
|
|
18
|
-
const light = new THREE.DirectionalLight(0xffffff, 0.3);
|
|
19
|
-
scene.add(light);
|
|
20
|
-
}
|
|
21
|
-
{
|
|
22
|
-
const light = new THREE.AmbientLight(0xffffff, 0.3);
|
|
23
|
-
scene.add(light);
|
|
24
|
-
}
|
|
25
|
-
scene.add(model);
|
|
26
|
-
const initRendererIfNeeds = () => {
|
|
27
|
-
if (!five.renderer)
|
|
28
|
-
return;
|
|
29
|
-
if (!renderer) {
|
|
30
|
-
renderer = new THREE.WebGLRenderer({ antialias: false, alpha: true });
|
|
31
|
-
renderer.setPixelRatio(five.renderer.getPixelRatio());
|
|
32
|
-
renderer.outputEncoding = THREE.sRGBEncoding;
|
|
33
|
-
renderer.setClearColor(0x181a1c, 0);
|
|
34
|
-
renderer.autoClear = true;
|
|
35
|
-
}
|
|
36
|
-
return renderer;
|
|
37
|
-
};
|
|
38
|
-
const handleModelWillLoad = () => {
|
|
39
|
-
model.traverse((object) => {
|
|
40
|
-
if (object instanceof THREE.Mesh) {
|
|
41
|
-
const materials = [].concat(object.material);
|
|
42
|
-
materials.forEach((material) => material.dispose());
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
scene.remove(model);
|
|
46
|
-
model = new THREE.Object3D();
|
|
47
|
-
scene.add(model);
|
|
48
|
-
update();
|
|
49
|
-
};
|
|
50
|
-
const handleModelLoaded = () => {
|
|
51
|
-
function cloneMaterial(material) {
|
|
52
|
-
material = material.clone();
|
|
53
|
-
material.uniforms.modelAlpha.value = 1;
|
|
54
|
-
if (material.uniforms.map.value) {
|
|
55
|
-
material.uniforms.map.value.needsUpdate = true;
|
|
56
|
-
}
|
|
57
|
-
return material;
|
|
58
|
-
}
|
|
59
|
-
function cloneModel(model) {
|
|
60
|
-
if (model instanceof THREE.Mesh) {
|
|
61
|
-
const geometry = model.geometry;
|
|
62
|
-
const material = Array.isArray(model.material)
|
|
63
|
-
? model.material.map(cloneMaterial)
|
|
64
|
-
: cloneMaterial(model.material);
|
|
65
|
-
return new THREE.Mesh(geometry, material);
|
|
66
|
-
}
|
|
67
|
-
else if (model instanceof THREE.Group) {
|
|
68
|
-
const group = new THREE.Group();
|
|
69
|
-
model.children.forEach((object) => group.add(cloneModel(object)));
|
|
70
|
-
return group;
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
const object3D = new THREE.Object3D();
|
|
74
|
-
model.children.forEach((object) => object3D.add(cloneModel(object)));
|
|
75
|
-
return object3D;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
scene.remove(model);
|
|
79
|
-
model = cloneModel(five.model);
|
|
80
|
-
scene.add(model);
|
|
81
|
-
update();
|
|
82
|
-
};
|
|
83
|
-
const appendTo = (element, size = {}) => {
|
|
84
|
-
const renderer = initRendererIfNeeds();
|
|
85
|
-
if (!renderer)
|
|
86
|
-
return;
|
|
87
|
-
element.appendChild(renderer.domElement);
|
|
88
|
-
refresh(size);
|
|
89
|
-
const positionType = window.getComputedStyle(element).position;
|
|
90
|
-
if (positionType !== 'relative' &&
|
|
91
|
-
positionType !== 'absolute' &&
|
|
92
|
-
positionType !== 'fixed' &&
|
|
93
|
-
positionType !== 'sticky')
|
|
94
|
-
element.style.position = 'relative';
|
|
95
|
-
};
|
|
96
|
-
const refresh = (size = {}) => {
|
|
97
|
-
if (!renderer)
|
|
98
|
-
return;
|
|
99
|
-
const element = renderer.domElement;
|
|
100
|
-
const container = element.parentNode;
|
|
101
|
-
if (container && container.nodeName) {
|
|
102
|
-
const { width = container.offsetWidth, height = container.offsetHeight } = size;
|
|
103
|
-
renderer.setSize(width, height);
|
|
104
|
-
// 修改摄像机 aspect 比值
|
|
105
|
-
camera.aspect = width / height;
|
|
106
|
-
camera.updateProjectionMatrix();
|
|
107
|
-
}
|
|
108
|
-
update();
|
|
109
|
-
};
|
|
110
|
-
const cameraDistance = () => {
|
|
111
|
-
const bounding = five.model.bounding;
|
|
112
|
-
const { fov, aspect } = camera;
|
|
113
|
-
const radius = Math.sqrt(Math.pow(bounding.max.x - bounding.min.x + 2, 2) +
|
|
114
|
-
Math.pow(bounding.max.y - bounding.min.y + 2, 2) +
|
|
115
|
-
Math.pow(bounding.max.z - bounding.min.z + 2, 2));
|
|
116
|
-
// fit screen
|
|
117
|
-
let distance = radius / 2 / Math.tan((Math.PI * fov) / 360);
|
|
118
|
-
if (aspect < 1)
|
|
119
|
-
distance = distance / aspect;
|
|
120
|
-
return isNaN(distance) ? radius : distance;
|
|
121
|
-
};
|
|
122
|
-
const update = () => {
|
|
123
|
-
const { longitude, latitude } = five.getPose();
|
|
124
|
-
const distance = cameraDistance();
|
|
125
|
-
const lookAt = five.model.bounding.getCenter(new THREE.Vector3());
|
|
126
|
-
const longitudeDistance = distance * Math.cos(latitude);
|
|
127
|
-
const cameraPosition = new THREE.Vector3();
|
|
128
|
-
cameraPosition.x = Math.sin(longitude) * longitudeDistance + lookAt.x;
|
|
129
|
-
cameraPosition.z = Math.cos(longitude) * longitudeDistance + lookAt.z;
|
|
130
|
-
cameraPosition.y = Math.sin(latitude) * distance + lookAt.y;
|
|
131
|
-
camera.position.copy(cameraPosition);
|
|
132
|
-
camera.lookAt(lookAt);
|
|
133
|
-
needsRender = true;
|
|
134
|
-
};
|
|
135
|
-
const render = () => {
|
|
136
|
-
if (needsRender !== true)
|
|
137
|
-
return;
|
|
138
|
-
if (!renderer)
|
|
139
|
-
return;
|
|
140
|
-
if (!renderer.domElement.parentNode)
|
|
141
|
-
return;
|
|
142
|
-
const parentNode = renderer.domElement.parentNode;
|
|
143
|
-
if (parentNode.offsetWidth === 0)
|
|
144
|
-
return;
|
|
145
|
-
renderer.render(scene, camera);
|
|
146
|
-
needsRender = false;
|
|
147
|
-
};
|
|
148
|
-
const dispose = () => {
|
|
149
|
-
if (renderer)
|
|
150
|
-
renderer.dispose();
|
|
151
|
-
renderer = null;
|
|
152
|
-
};
|
|
153
|
-
five.on('modelLoaded', handleModelLoaded);
|
|
154
|
-
five.on('modelWillLoad', handleModelWillLoad);
|
|
155
|
-
five.on('cameraDirectionUpdate', update);
|
|
156
|
-
five.on('dispose', dispose);
|
|
157
|
-
five.on('renderFrame', render);
|
|
158
|
-
return { appendTo, refresh };
|
|
159
|
-
};
|
|
1
|
+
import ModelViewPlugin from './Plugin';
|
|
2
|
+
export { ModelViewPlugin };
|
|
160
3
|
export default ModelViewPlugin;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Five, FivePlugin } from '@realsee/five';
|
|
2
|
+
import type { FloorplanServerRoomItem } from '../floorplan/typings/floorplanServerData';
|
|
3
|
+
export interface PanoCompassPluginParameterType {
|
|
4
|
+
compassImageUrl?: string;
|
|
5
|
+
entryDoorImageUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface PanoCompassPluginData {
|
|
8
|
+
north_rad: null | number;
|
|
9
|
+
entrance: null | undefined | {
|
|
10
|
+
position: {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
z: number;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
room_observers: undefined | {
|
|
17
|
+
index: number;
|
|
18
|
+
floor_index: number;
|
|
19
|
+
room: FloorplanServerRoomItem;
|
|
20
|
+
}[];
|
|
21
|
+
}
|
|
22
|
+
export declare type PanoCompassPluginExportType = PanoCompassController;
|
|
23
|
+
export declare const PanoCompassPlugin: FivePlugin<PanoCompassPluginParameterType | undefined, PanoCompassController>;
|
|
24
|
+
export default PanoCompassPlugin;
|
|
25
|
+
declare class PanoCompassController {
|
|
26
|
+
five: Five;
|
|
27
|
+
data?: PanoCompassPluginData;
|
|
28
|
+
config?: PanoCompassPluginParameterType;
|
|
29
|
+
private group;
|
|
30
|
+
private modelLoaded;
|
|
31
|
+
private roomInfoInstance?;
|
|
32
|
+
private roomInfoWrapperInstance?;
|
|
33
|
+
private compassMeshTween?;
|
|
34
|
+
private compassMesh?;
|
|
35
|
+
private entryDoorMesh?;
|
|
36
|
+
constructor(five: Five, config?: PanoCompassPluginParameterType);
|
|
37
|
+
load(data: PanoCompassPluginData): void;
|
|
38
|
+
dispose: () => void;
|
|
39
|
+
private onFiveFistPanoLoaded;
|
|
40
|
+
private init;
|
|
41
|
+
private loadCompassMesh;
|
|
42
|
+
private loadEntryDoorMesh;
|
|
43
|
+
private loadRoomInfo;
|
|
44
|
+
private onFivePanoWillArrive;
|
|
45
|
+
private onFivePanoArrived;
|
|
46
|
+
private onFiveCameraDirectionUpdate;
|
|
47
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { getRoomInfoInstance } from './getRoomInfoInstance';
|
|
3
|
+
import { loadTexture } from '../shared-utils/three/loadTexture';
|
|
4
|
+
import CSS3DRenderPlugin from '../CSS3DRenderPlugin';
|
|
5
|
+
import { tweenProgress } from '../shared-utils/animationFrame/BetterTween';
|
|
6
|
+
export const PanoCompassPlugin = function (five, config) {
|
|
7
|
+
return new PanoCompassController(five, config);
|
|
8
|
+
};
|
|
9
|
+
export default PanoCompassPlugin;
|
|
10
|
+
class PanoCompassController {
|
|
11
|
+
constructor(five, config) {
|
|
12
|
+
Object.defineProperty(this, "five", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: void 0
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(this, "data", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
writable: true,
|
|
22
|
+
value: void 0
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(this, "config", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
writable: true,
|
|
28
|
+
value: void 0
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(this, "group", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: new THREE.Group()
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(this, "modelLoaded", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: false
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(this, "roomInfoInstance", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
configurable: true,
|
|
45
|
+
writable: true,
|
|
46
|
+
value: void 0
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(this, "roomInfoWrapperInstance", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
configurable: true,
|
|
51
|
+
writable: true,
|
|
52
|
+
value: void 0
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(this, "compassMeshTween", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
configurable: true,
|
|
57
|
+
writable: true,
|
|
58
|
+
value: void 0
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(this, "compassMesh", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
configurable: true,
|
|
63
|
+
writable: true,
|
|
64
|
+
value: void 0
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(this, "entryDoorMesh", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true,
|
|
69
|
+
writable: true,
|
|
70
|
+
value: void 0
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(this, "dispose", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: () => {
|
|
77
|
+
var _a, _b, _c, _d;
|
|
78
|
+
this.five.scene.remove(this.group);
|
|
79
|
+
this.group.remove(...this.group.children);
|
|
80
|
+
(_b = (_a = this.compassMesh) === null || _a === void 0 ? void 0 : _a.material.map) === null || _b === void 0 ? void 0 : _b.dispose();
|
|
81
|
+
(_d = (_c = this.entryDoorMesh) === null || _c === void 0 ? void 0 : _c.material.map) === null || _d === void 0 ? void 0 : _d.dispose();
|
|
82
|
+
this.five.off('panoArrived', this.onFivePanoArrived);
|
|
83
|
+
this.five.off('panoWillArrive', this.onFivePanoWillArrive);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
Object.defineProperty(this, "onFiveFistPanoLoaded", {
|
|
87
|
+
enumerable: true,
|
|
88
|
+
configurable: true,
|
|
89
|
+
writable: true,
|
|
90
|
+
value: () => {
|
|
91
|
+
this.modelLoaded = true;
|
|
92
|
+
if (this.data)
|
|
93
|
+
this.init();
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(this, "onFivePanoWillArrive", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
configurable: true,
|
|
99
|
+
writable: true,
|
|
100
|
+
value: (panoIndex) => {
|
|
101
|
+
var _a, _b;
|
|
102
|
+
if (panoIndex === this.five.panoIndex)
|
|
103
|
+
return;
|
|
104
|
+
(_a = this.compassMeshTween) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
105
|
+
(_b = this.compassMesh) === null || _b === void 0 ? void 0 : _b.material.setValues({ opacity: 0 });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(this, "onFivePanoArrived", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
configurable: true,
|
|
111
|
+
writable: true,
|
|
112
|
+
value: (panoIndex) => {
|
|
113
|
+
var _a, _b, _c, _d;
|
|
114
|
+
// ======== fix compass position ========
|
|
115
|
+
const standingPosition = this.five.work.observers[panoIndex].standingPosition;
|
|
116
|
+
if (this.compassMesh) {
|
|
117
|
+
// 指南针上移 0.01m,防止与地板重合
|
|
118
|
+
this.compassMesh.position.copy(standingPosition.clone().setY(standingPosition.y + 0.01));
|
|
119
|
+
if (this.compassMesh.material.opacity !== 0)
|
|
120
|
+
return;
|
|
121
|
+
(_a = this.compassMeshTween) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
122
|
+
this.compassMeshTween = tweenProgress(1000)
|
|
123
|
+
.onUpdate(({ progress }) => {
|
|
124
|
+
var _a;
|
|
125
|
+
(_a = this.compassMesh) === null || _a === void 0 ? void 0 : _a.material.setValues({ opacity: progress });
|
|
126
|
+
this.five.needsRender = true;
|
|
127
|
+
})
|
|
128
|
+
.play();
|
|
129
|
+
}
|
|
130
|
+
// ======== fix entry door label position and rotation ========
|
|
131
|
+
if (this.entryDoorMesh) {
|
|
132
|
+
const entryDoorPosition = new THREE.Vector3(this.data.entrance.position.x, this.data.entrance.position.y, this.data.entrance.position.z);
|
|
133
|
+
const panoToEntryDoorVector = entryDoorPosition
|
|
134
|
+
.clone()
|
|
135
|
+
.setY(standingPosition.y)
|
|
136
|
+
.sub(standingPosition)
|
|
137
|
+
.normalize();
|
|
138
|
+
const compassEntryDoorPosition = standingPosition
|
|
139
|
+
.clone()
|
|
140
|
+
.add(panoToEntryDoorVector.clone().multiplyScalar(0.7))
|
|
141
|
+
.setY(standingPosition.y + 0.01);
|
|
142
|
+
this.entryDoorMesh.rotation.z = new THREE.Vector3(0, 0, -1).angleTo(panoToEntryDoorVector);
|
|
143
|
+
this.entryDoorMesh.position.copy(compassEntryDoorPosition);
|
|
144
|
+
// 不是客厅时,隐藏入户门指引
|
|
145
|
+
((_b = this.data) === null || _b === void 0 ? void 0 : _b.room_observers[panoIndex].room.type) === 1
|
|
146
|
+
? (_c = this.entryDoorMesh) === null || _c === void 0 ? void 0 : _c.material.setValues({ opacity: 1 })
|
|
147
|
+
: (_d = this.entryDoorMesh) === null || _d === void 0 ? void 0 : _d.material.setValues({ opacity: 0 });
|
|
148
|
+
}
|
|
149
|
+
// ======== fix room info ========
|
|
150
|
+
if (this.roomInfoInstance && this.roomInfoWrapperInstance) {
|
|
151
|
+
this.roomInfoWrapperInstance.css3DObject.position.copy(standingPosition.clone().setY(standingPosition.y + 0.01));
|
|
152
|
+
this.roomInfoInstance.setRoom(this.data.room_observers[panoIndex].room);
|
|
153
|
+
}
|
|
154
|
+
this.five.needsRender = true;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
Object.defineProperty(this, "onFiveCameraDirectionUpdate", {
|
|
158
|
+
enumerable: true,
|
|
159
|
+
configurable: true,
|
|
160
|
+
writable: true,
|
|
161
|
+
value: ({ longitude, latitude, }) => {
|
|
162
|
+
var _a, _b;
|
|
163
|
+
if (!this.roomInfoWrapperInstance)
|
|
164
|
+
return;
|
|
165
|
+
this.roomInfoWrapperInstance.css3DObject.rotation.z = longitude;
|
|
166
|
+
latitude > 0.66 && this.five.getCurrentState().mode === 'Panorama'
|
|
167
|
+
? (_a = this.roomInfoInstance) === null || _a === void 0 ? void 0 : _a.show()
|
|
168
|
+
: (_b = this.roomInfoInstance) === null || _b === void 0 ? void 0 : _b.hide();
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
this.five = five;
|
|
172
|
+
this.config = config;
|
|
173
|
+
this.five.scene.add(this.group);
|
|
174
|
+
five.once('dispose', this.dispose);
|
|
175
|
+
five.once('modelLoaded', this.onFiveFistPanoLoaded);
|
|
176
|
+
this.five.on('panoArrived', this.onFivePanoArrived);
|
|
177
|
+
this.five.on('panoWillArrive', this.onFivePanoWillArrive);
|
|
178
|
+
this.five.on('cameraDirectionUpdate', this.onFiveCameraDirectionUpdate);
|
|
179
|
+
}
|
|
180
|
+
load(data) {
|
|
181
|
+
this.data = data;
|
|
182
|
+
if (this.modelLoaded)
|
|
183
|
+
this.init();
|
|
184
|
+
}
|
|
185
|
+
async init() {
|
|
186
|
+
if (!this.data || !this.modelLoaded)
|
|
187
|
+
return;
|
|
188
|
+
const northRad = this.data.north_rad;
|
|
189
|
+
if (northRad != null) {
|
|
190
|
+
this.compassMesh = await this.loadCompassMesh();
|
|
191
|
+
this.compassMesh.rotateX(-Math.PI / 2);
|
|
192
|
+
this.compassMesh.rotateZ(northRad - Math.PI / 2);
|
|
193
|
+
this.group.add(this.compassMesh);
|
|
194
|
+
}
|
|
195
|
+
if (this.data.entrance != null) {
|
|
196
|
+
this.entryDoorMesh = await this.loadEntryDoorMesh();
|
|
197
|
+
this.roomInfoWrapperInstance = this.loadRoomInfo();
|
|
198
|
+
this.roomInfoInstance = getRoomInfoInstance();
|
|
199
|
+
this.entryDoorMesh.rotateX(-Math.PI / 2);
|
|
200
|
+
if (this.roomInfoWrapperInstance)
|
|
201
|
+
this.roomInfoInstance.appendTo(this.roomInfoWrapperInstance.container);
|
|
202
|
+
this.group.add(this.entryDoorMesh);
|
|
203
|
+
}
|
|
204
|
+
this.onFivePanoArrived(this.five.panoIndex || 0);
|
|
205
|
+
this.five.needsRender = true;
|
|
206
|
+
}
|
|
207
|
+
async loadCompassMesh() {
|
|
208
|
+
var _a;
|
|
209
|
+
const compassImageUrl = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.compassImageUrl) ||
|
|
210
|
+
'//vrlab-image4.ljcdn.com/release/web/v3/north-point-circle.96498e69.png';
|
|
211
|
+
const compassTexture = await loadTexture(compassImageUrl);
|
|
212
|
+
const compassGeometry = new THREE.CircleGeometry(0.7, 32);
|
|
213
|
+
const compassMaterial = new THREE.MeshBasicMaterial({
|
|
214
|
+
map: compassTexture,
|
|
215
|
+
transparent: true,
|
|
216
|
+
opacity: 0,
|
|
217
|
+
depthTest: false,
|
|
218
|
+
});
|
|
219
|
+
const compassMesh = new THREE.Mesh(compassGeometry, compassMaterial);
|
|
220
|
+
compassMesh.name = 'pano-compass-mesh';
|
|
221
|
+
return compassMesh;
|
|
222
|
+
}
|
|
223
|
+
async loadEntryDoorMesh() {
|
|
224
|
+
var _a;
|
|
225
|
+
const entryDoorImageUrl = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.entryDoorImageUrl) ||
|
|
226
|
+
'//vrlab-image4.ljcdn.com/release/web/enterDoor.831b8208.png';
|
|
227
|
+
const entryDoorTexture = await loadTexture(entryDoorImageUrl);
|
|
228
|
+
const entryDoorGeometry = new THREE.PlaneGeometry(0.2, 0.16);
|
|
229
|
+
const entryDoorMaterial = new THREE.MeshBasicMaterial({
|
|
230
|
+
map: entryDoorTexture,
|
|
231
|
+
transparent: true,
|
|
232
|
+
opacity: 0.8,
|
|
233
|
+
depthTest: false,
|
|
234
|
+
});
|
|
235
|
+
const entryDoorMesh = new THREE.Mesh(entryDoorGeometry, entryDoorMaterial);
|
|
236
|
+
entryDoorMesh.name = 'pano-compass-entry-door';
|
|
237
|
+
return entryDoorMesh;
|
|
238
|
+
}
|
|
239
|
+
loadRoomInfo() {
|
|
240
|
+
const points = [
|
|
241
|
+
new THREE.Vector3(-0.7, 0, -0.7),
|
|
242
|
+
new THREE.Vector3(0.7, 0, -0.7),
|
|
243
|
+
new THREE.Vector3(0.7, 0, 0.7),
|
|
244
|
+
new THREE.Vector3(-0.7, 0, 0.7),
|
|
245
|
+
];
|
|
246
|
+
const roomInfo = CSS3DRenderPlugin(this.five).create3DDomContainer(points);
|
|
247
|
+
return roomInfo;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
@@ -1,51 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
entryDoorImageUrl?: string;
|
|
6
|
-
}
|
|
7
|
-
export interface PanoCompassPluginData {
|
|
8
|
-
north_rad: null | number;
|
|
9
|
-
entrance: null | undefined | {
|
|
10
|
-
position: {
|
|
11
|
-
x: number;
|
|
12
|
-
y: number;
|
|
13
|
-
z: number;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
room_observers: undefined | {
|
|
17
|
-
index: number;
|
|
18
|
-
floor_index: number;
|
|
19
|
-
room: FloorplanServerRoomItem;
|
|
20
|
-
}[];
|
|
21
|
-
}
|
|
22
|
-
export declare type PanoCompassPluginExportType = PanoCompassController;
|
|
1
|
+
import PanoCompassPlugin from './Plugin';
|
|
2
|
+
export { PanoCompassPlugin };
|
|
3
|
+
export default PanoCompassPlugin;
|
|
4
|
+
export type { PanoCompassPluginParameterType, PanoCompassPluginData, PanoCompassPluginExportType } from './Plugin';
|
|
23
5
|
export declare const panoCompassPluginServerParams: {
|
|
24
6
|
name: string;
|
|
25
7
|
version: number;
|
|
26
8
|
};
|
|
27
|
-
export declare const PanoCompassPlugin: FivePlugin<PanoCompassPluginParameterType | undefined, PanoCompassController>;
|
|
28
|
-
export default PanoCompassPlugin;
|
|
29
|
-
declare class PanoCompassController {
|
|
30
|
-
five: Five;
|
|
31
|
-
data?: PanoCompassPluginData;
|
|
32
|
-
config?: PanoCompassPluginParameterType;
|
|
33
|
-
private group;
|
|
34
|
-
private modelLoaded;
|
|
35
|
-
private roomInfoInstance?;
|
|
36
|
-
private roomInfoWrapperInstance?;
|
|
37
|
-
private compassMeshTween?;
|
|
38
|
-
private compassMesh?;
|
|
39
|
-
private entryDoorMesh?;
|
|
40
|
-
constructor(five: Five, config?: PanoCompassPluginParameterType);
|
|
41
|
-
load(data: PanoCompassPluginData): void;
|
|
42
|
-
dispose: () => void;
|
|
43
|
-
private onFiveFistPanoLoaded;
|
|
44
|
-
private init;
|
|
45
|
-
private loadCompassMesh;
|
|
46
|
-
private loadEntryDoorMesh;
|
|
47
|
-
private loadRoomInfo;
|
|
48
|
-
private onFivePanoWillArrive;
|
|
49
|
-
private onFivePanoArrived;
|
|
50
|
-
private onFiveCameraDirectionUpdate;
|
|
51
|
-
}
|