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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +78 -28
  3. package/dist/CSS3DRenderPlugin/index.js +17 -14
  4. package/dist/CameraMovementPlugin/index.js +40 -15
  5. package/dist/ModelChassisCompassPlugin/index.js +32 -6
  6. package/dist/ModelEntryDoorGuidePlugin/index.js +48 -18
  7. package/dist/ModelItemLabelPlugin/events.type.d.ts +9 -0
  8. package/dist/ModelItemLabelPlugin/index.d.ts +4 -0
  9. package/dist/ModelItemLabelPlugin/index.js +691 -0
  10. package/dist/ModelItemLabelPlugin/typings.d.ts +56 -0
  11. package/dist/ModelItemLabelPlugin/utils/parseData.d.ts +3 -0
  12. package/dist/ModelRoomLabelPlugin/index.js +68 -27
  13. package/dist/ModelTVVideoPlugin/index.d.ts +4 -0
  14. package/dist/ModelTVVideoPlugin/index.js +326 -0
  15. package/dist/ModelTVVideoPlugin/typings.d.ts +25 -0
  16. package/dist/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
  17. package/dist/PanoCompassPlugin/index.js +311 -164
  18. package/dist/PanoCursorRaycasterPlugin/index.js +5 -3
  19. package/dist/PanoMeasurePlugin/index.js +1335 -581
  20. package/dist/PanoRulerPlugin/index.js +32 -5
  21. package/dist/PanoSpatialTagPlugin/index.js +73 -38
  22. package/dist/floorplan/ModelFloorplanPlugin/index.js +586 -362
  23. package/dist/floorplan/PanoFloorplanRadarPlugin/index.js +164 -72
  24. package/dist/floorplan/TopviewFloorplanPlugin/index.js +311 -153
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.es.js +3790 -1539
  27. package/dist/index.js +3794 -1540
  28. package/dist/index.umd.js +3797 -1544
  29. package/docs/assets/search.js +1 -1
  30. package/docs/classes/ModelRoomLabelController.html +6 -6
  31. package/docs/enums/FLOOR_PLAN_ATTACHED_TO.html +1 -1
  32. package/docs/enums/ModelFloorplanErrorType.html +1 -1
  33. package/docs/index.html +78 -33
  34. package/docs/interfaces/LineJson.html +1 -1
  35. package/docs/interfaces/ModelChassisCompassPluginData.html +1 -1
  36. package/docs/interfaces/ModelChassisCompassPluginExportType.html +1 -1
  37. package/docs/interfaces/ModelChassisCompassPluginParameterType.html +1 -1
  38. package/docs/interfaces/ModelEntryDoorGuidePluginData.html +1 -1
  39. package/docs/interfaces/ModelEntryDoorGuidePluginExportType.html +1 -1
  40. package/docs/interfaces/ModelFloorplanParameterType.html +1 -1
  41. package/docs/interfaces/ModelFloorplanViewEvent.html +2 -2
  42. package/docs/interfaces/ModelItemLabelPluginData.html +1 -0
  43. package/docs/interfaces/ModelItemLabelPluginExportReturnsType.html +1 -0
  44. package/docs/interfaces/ModelItemLabelPluginParametersType.html +1 -0
  45. package/docs/interfaces/ModelRoomLabelPluginData.html +1 -1
  46. package/docs/interfaces/ModelTVVideoPluginData.html +1 -0
  47. package/docs/interfaces/ModelTVVideoPluginExportType.html +1 -0
  48. package/docs/interfaces/ModelTVVideoPluginParameterType.html +1 -0
  49. package/docs/interfaces/PanoCompassPluginData.html +1 -1
  50. package/docs/interfaces/PanoCompassPluginParameterType.html +1 -1
  51. package/docs/interfaces/PanoCursorRaycasterPluginExportType.html +6 -6
  52. package/docs/interfaces/PanoRulerPluginExportType.html +1 -1
  53. package/docs/interfaces/PanoRulerPluginOptions.html +1 -1
  54. package/docs/interfaces/PanoRulerPluginParameterType.html +1 -1
  55. package/docs/interfaces/PanoSpatialTagPluginData.html +1 -1
  56. package/docs/interfaces/PanoSpatialTagPluginExportType.html +1 -1
  57. package/docs/interfaces/PanoSpatialTagPluginParameterType.html +1 -1
  58. package/docs/interfaces/PointJson.html +1 -1
  59. package/docs/interfaces/RoomLabel.html +7 -7
  60. package/docs/interfaces/TopviewFloorplanPluginParameterType.html +1 -1
  61. package/docs/modules.html +12 -12
  62. package/libs/CSS3DRenderPlugin/index.js +16 -13
  63. package/libs/CameraMovementPlugin/index.js +24 -15
  64. package/libs/ModelChassisCompassPlugin/index.js +14 -5
  65. package/libs/ModelEntryDoorGuidePlugin/index.js +24 -12
  66. package/libs/ModelItemLabelPlugin/ItemLabelComponent.js +422 -0
  67. package/libs/ModelItemLabelPlugin/ItemLabelItem.js +133 -0
  68. package/libs/ModelItemLabelPlugin/events.type.d.ts +9 -0
  69. package/libs/ModelItemLabelPlugin/events.type.js +1 -0
  70. package/libs/ModelItemLabelPlugin/index.d.ts +4 -0
  71. package/libs/ModelItemLabelPlugin/index.js +184 -0
  72. package/libs/ModelItemLabelPlugin/typings.d.ts +56 -0
  73. package/libs/ModelItemLabelPlugin/typings.js +6 -0
  74. package/libs/ModelItemLabelPlugin/utils/parseData.d.ts +3 -0
  75. package/libs/ModelItemLabelPlugin/utils/parseData.js +4 -0
  76. package/libs/ModelRoomLabelPlugin/Controller.js +64 -23
  77. package/libs/ModelRoomLabelPlugin/RoomLabelItems.js +4 -4
  78. package/libs/ModelTVVideoPlugin/index.d.ts +4 -0
  79. package/libs/ModelTVVideoPlugin/index.js +263 -0
  80. package/libs/ModelTVVideoPlugin/typings.d.ts +25 -0
  81. package/libs/ModelTVVideoPlugin/typings.js +7 -0
  82. package/libs/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
  83. package/libs/ModelTVVideoPlugin/utils/parseData.js +13 -0
  84. package/libs/PanoCompassPlugin/index.js +225 -128
  85. package/libs/PanoCursorRaycasterPlugin/index.js +5 -3
  86. package/libs/PanoMeasurePlugin/Controller/BaseController.js +68 -13
  87. package/libs/PanoMeasurePlugin/Controller/EditController.js +267 -154
  88. package/libs/PanoMeasurePlugin/Controller/ShortcutKeyController.js +40 -20
  89. package/libs/PanoMeasurePlugin/Controller/WatchController.js +234 -152
  90. package/libs/PanoMeasurePlugin/Controller/index.js +131 -47
  91. package/libs/PanoMeasurePlugin/Model/index.js +30 -5
  92. package/libs/PanoMeasurePlugin/Model/line.js +60 -10
  93. package/libs/PanoMeasurePlugin/Model/point.js +24 -4
  94. package/libs/PanoMeasurePlugin/Model/polyline.js +20 -3
  95. package/libs/PanoMeasurePlugin/Modules/DeleteDom/index.js +59 -14
  96. package/libs/PanoMeasurePlugin/Modules/FiveHelper.js +23 -8
  97. package/libs/PanoMeasurePlugin/Modules/GuideController.js +61 -26
  98. package/libs/PanoMeasurePlugin/Modules/Magnifier.js +60 -10
  99. package/libs/PanoMeasurePlugin/Modules/UIController/MainBtnController.js +83 -37
  100. package/libs/PanoMeasurePlugin/Modules/UIController/Revoke/index.js +52 -17
  101. package/libs/PanoMeasurePlugin/Modules/UIController/index.js +61 -30
  102. package/libs/PanoMeasurePlugin/utils/distanceDom.js +3 -2
  103. package/libs/PanoMeasurePlugin/utils/line.js +8 -7
  104. package/libs/PanoRulerPlugin/index.js +16 -5
  105. package/libs/PanoSpatialTagPlugin/Components/tag.js +9 -9
  106. package/libs/PanoSpatialTagPlugin/index.js +11 -9
  107. package/libs/floorplan/Components/BaseImage.js +10 -5
  108. package/libs/floorplan/Components/RoomHighlight/RoomHighlight.js +3 -1
  109. package/libs/floorplan/Components/RoomMaterials/RoomMaterial.js +5 -6
  110. package/libs/floorplan/ModelFloorplanPlugin/Components/Compass.js +7 -2
  111. package/libs/floorplan/ModelFloorplanPlugin/Components/RoomLabels/RoomLabel.js +3 -1
  112. package/libs/floorplan/ModelFloorplanPlugin/Controller.js +456 -273
  113. package/libs/floorplan/ModelFloorplanPlugin/utils/correctFiveState.js +33 -22
  114. package/libs/floorplan/PanoFloorplanRadarPlugin/Components/CurrentFloor/CurrentFloor.js +3 -1
  115. package/libs/floorplan/PanoFloorplanRadarPlugin/Controller.js +97 -36
  116. package/libs/floorplan/TopviewFloorplanPlugin/Controller.js +231 -108
  117. package/libs/floorplan/utils/formatData.js +43 -28
  118. package/libs/floorplan/utils/formatPosition.js +1 -1
  119. package/libs/index.d.ts +4 -0
  120. package/libs/index.js +2 -0
  121. package/libs/shared-utils/Subscribe.js +8 -1
  122. package/libs/shared-utils/animationFrame/BetterTween.js +47 -18
  123. package/libs/shared-utils/createCanvasTextTexture.js +6 -5
  124. package/libs/shared-utils/five/changeMode.js +23 -12
  125. package/libs/shared-utils/getPxmm.js +1 -1
  126. package/libs/shared-utils/math/evenNumber.js +1 -1
  127. package/libs/shared-utils/three/loadFbxObj.js +20 -9
  128. package/libs/shared-utils/three/loadTexture.js +17 -6
  129. package/libs/shared-utils/three/transfromToMeshBasicMaterial.js +2 -1
  130. package/libs/shared-utils/tinyEJSrender.js +36 -6
  131. package/libs/shared-utils/to.js +21 -10
  132. package/libs/shared-utils/useDebounce.js +1 -1
  133. package/libs/shared-utils/useThrottle.js +2 -1
  134. package/package.json +1 -1
@@ -0,0 +1,184 @@
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
+ pending: false
19
+ };
20
+ pluginState.container.setAttribute('class', 'model-item-label-plugin-container');
21
+ pluginState.container.style.cssText = `
22
+ position: absolute;
23
+ left: 0;
24
+ top: 0;
25
+ width: 100%;
26
+ height: 100%;
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 handleRerender = () => {
58
+ if (!pluginState.enabled || !pluginState.fiveModeEnabled || pluginState.pending)
59
+ return;
60
+ pluginState.pending = true;
61
+ disable();
62
+ };
63
+ const rerender = (a, b, c) => {
64
+ if (!pluginState.pending)
65
+ return;
66
+ if (!pluginState.fiveModeEnabled)
67
+ return;
68
+ if (!c)
69
+ return;
70
+ pluginState.pending = false;
71
+ enable();
72
+ render();
73
+ };
74
+ const handleInteriaPanRerender = (a, b) => {
75
+ if (!pluginState.pending)
76
+ return;
77
+ if (!pluginState.fiveModeEnabled)
78
+ return;
79
+ if (!b)
80
+ return;
81
+ pluginState.pending = false;
82
+ enable();
83
+ render();
84
+ };
85
+ const handleWantsPanGesture = (pose, final) => {
86
+ if (pose) {
87
+ handleRerender();
88
+ }
89
+ };
90
+ const handlePanGesture = (pose, final) => {
91
+ if (!pluginState.pending)
92
+ return;
93
+ if (!pluginState.fiveModeEnabled)
94
+ return;
95
+ if (!final)
96
+ return;
97
+ pluginState.pending = false;
98
+ enable();
99
+ render();
100
+ };
101
+ const render = () => {
102
+ var _a;
103
+ if (!pluginState.wrapper)
104
+ return;
105
+ // 只要不可展示,销毁容器
106
+ if (!pluginState.enabled || !pluginState.fiveModeEnabled) {
107
+ (_a = pluginState.app) === null || _a === void 0 ? void 0 : _a.$destroy();
108
+ pluginState.app = undefined;
109
+ return;
110
+ }
111
+ // 正常显示时,分为 app 存在和不存在两种情况,如果存在,传值,不存在则初始化并传值
112
+ if (!pluginState.app) {
113
+ pluginState.app = new ItemLabelComponent({
114
+ target: pluginState.container,
115
+ props: {
116
+ five: five,
117
+ modelOcclusionEnable: pluginState.modelOcclusionEnable,
118
+ itemLabels: pluginState.itemLabels,
119
+ wrapper: pluginState.wrapper,
120
+ hooks: pluginState.hooks,
121
+ displayStrategyType: pluginState.displayStrategyType
122
+ }
123
+ });
124
+ }
125
+ else {
126
+ pluginState.app.$set({
127
+ five: five,
128
+ itemLabels: pluginState.itemLabels
129
+ });
130
+ }
131
+ };
132
+ // 添加 five 监听
133
+ const addListener4Five = () => {
134
+ five.on('modeChange', onFiveModeChange);
135
+ five.once('dispose', dispose);
136
+ // five.on('wantsGesture', handleRerender)
137
+ // five.on('gesture', rerender)
138
+ five.on('wantsMouseWheel', handleRerender);
139
+ five.on('mouseWheel', rerender);
140
+ five.on('wantsInteriaPan', handleRerender);
141
+ five.on('interiaPan', handleInteriaPanRerender);
142
+ five.on('wantsPanGesture', handleWantsPanGesture);
143
+ five.on('panGesture', handlePanGesture);
144
+ five.on('wantsPinchGesture', handleRerender);
145
+ five.on('pinchGesture', rerender);
146
+ };
147
+ // 取消 five 监听
148
+ const removeListener4Five = () => {
149
+ five.off('modeChange', onFiveModeChange);
150
+ // five.off('wantsGesture', handleRerender)
151
+ // five.off('gesture', rerender)
152
+ five.off('wantsMouseWheel', handleRerender);
153
+ five.off('mouseWheel', rerender);
154
+ five.off('wantsInteriaPan', handleRerender);
155
+ five.off('interiaPan', handleInteriaPanRerender);
156
+ five.off('wantsPanGesture', handleWantsPanGesture);
157
+ five.off('panGesture', handlePanGesture);
158
+ five.off('wantsPinchGesture', handleRerender);
159
+ five.off('pinchGesture', rerender);
160
+ };
161
+ const onFiveModeChange = (mode) => {
162
+ if (!pluginState.enabled || pluginState.pending)
163
+ return;
164
+ if (mode !== Five.Mode.Floorplan) {
165
+ pluginState.fiveModeEnabled = false;
166
+ render();
167
+ return;
168
+ }
169
+ five.once('initAnimationEnded', () => {
170
+ pluginState.fiveModeEnabled = five.currentMode === Five.Mode.Floorplan;
171
+ render();
172
+ });
173
+ };
174
+ addListener4Five();
175
+ return {
176
+ appendTo,
177
+ load,
178
+ enable,
179
+ disable,
180
+ dispose,
181
+ hooks: pluginState.hooks
182
+ };
183
+ };
184
+ export default ModelItemLabelPlugin;
@@ -0,0 +1,56 @@
1
+ import ItemLabelComponent from './ItemLabelComponent';
2
+ import type { Subscribe } from "@realsee/five";
3
+ import { PluginEvent } from "./events.type";
4
+ export declare enum DISPLAY_STRATEGY_TYPE {
5
+ SMALL = "small",
6
+ MIDLLE = "middle",
7
+ LARGE = "large"
8
+ }
9
+ export interface ModelItemLabelPluginParametersType {
10
+ modelOcclusionEnable?: boolean;
11
+ displayStrategyType?: Partial<DISPLAY_STRATEGY_TYPE>;
12
+ }
13
+ export interface ModelItemLabelPluginData {
14
+ model_item_labels: Readonly<{
15
+ id: string;
16
+ library: string;
17
+ name: string;
18
+ size: [number, number, number];
19
+ center: [number, number, number];
20
+ position: [number, number, number];
21
+ type: string[];
22
+ [key: string]: any;
23
+ }>[];
24
+ }
25
+ export interface ItemLabel {
26
+ id: string;
27
+ library: string;
28
+ name: string;
29
+ size: [number, number, number];
30
+ center: [number, number, number];
31
+ position: [number, number, number];
32
+ type: string[];
33
+ modelPosition: [number, number, number];
34
+ [key: string]: any;
35
+ }
36
+ export interface ModelItemLabelPluginExportReturnsType {
37
+ appendTo: (wrapper: Element) => void;
38
+ load: (data: ModelItemLabelPluginData) => void;
39
+ disable: () => void;
40
+ enable: () => void;
41
+ dispose: () => void;
42
+ hooks: Subscribe<PluginEvent>;
43
+ }
44
+ export interface ModelItemLabelPluginState {
45
+ container: HTMLDivElement;
46
+ data: ModelItemLabelPluginData | null;
47
+ enabled: boolean;
48
+ itemLabels: ItemLabel[];
49
+ wrapper: HTMLElement | null;
50
+ fiveModeEnabled: boolean;
51
+ app?: ItemLabelComponent | undefined;
52
+ hooks: Subscribe<PluginEvent>;
53
+ modelOcclusionEnable: boolean;
54
+ displayStrategyType: Partial<DISPLAY_STRATEGY_TYPE>;
55
+ pending: boolean;
56
+ }
@@ -0,0 +1,6 @@
1
+ export var DISPLAY_STRATEGY_TYPE;
2
+ (function (DISPLAY_STRATEGY_TYPE) {
3
+ DISPLAY_STRATEGY_TYPE["SMALL"] = "small";
4
+ DISPLAY_STRATEGY_TYPE["MIDLLE"] = "middle";
5
+ DISPLAY_STRATEGY_TYPE["LARGE"] = "large";
6
+ })(DISPLAY_STRATEGY_TYPE || (DISPLAY_STRATEGY_TYPE = {}));
@@ -0,0 +1,3 @@
1
+ import { ModelItemLabelPluginData, ItemLabel } from '../typings';
2
+ /** @description 转成内部所需数据 */
3
+ export declare function parseModelItemLabelPluginData(data: ModelItemLabelPluginData): ItemLabel[];
@@ -0,0 +1,4 @@
1
+ /** @description 转成内部所需数据 */
2
+ export function parseModelItemLabelPluginData(data) {
3
+ return data.model_item_labels.map(label => (Object.assign({ modelPosition: [label.position[0], label.position[1] + label.size[1], label.position[2]] }, label)));
4
+ }
@@ -1,14 +1,69 @@
1
1
  import RoomLabelItems from './RoomLabelItems';
2
2
  import { parseModelRoomLabelPluginData } from './utils/parseData';
3
3
  export class ModelRoomLabelController {
4
- five;
5
- enabled = true;
6
- fiveModeEnabled;
7
- app = undefined;
8
- wrapper;
9
- roomLabels = [];
10
- container = document.createElement('div');
11
4
  constructor(five) {
5
+ Object.defineProperty(this, "five", {
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true,
9
+ value: void 0
10
+ });
11
+ Object.defineProperty(this, "enabled", {
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true,
15
+ value: true
16
+ });
17
+ Object.defineProperty(this, "fiveModeEnabled", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: void 0
22
+ });
23
+ Object.defineProperty(this, "app", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: undefined
28
+ });
29
+ Object.defineProperty(this, "wrapper", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: void 0
34
+ });
35
+ Object.defineProperty(this, "roomLabels", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: []
40
+ });
41
+ Object.defineProperty(this, "container", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: document.createElement('div')
46
+ });
47
+ /** 监听 Five Mode 变化
48
+ * @description
49
+ * Mode 不符合要求时,立刻消失,满足要求时,需要等待动画结束再展示
50
+ */
51
+ Object.defineProperty(this, "onFiveModeChange", {
52
+ enumerable: true,
53
+ configurable: true,
54
+ writable: true,
55
+ value: (mode) => {
56
+ if (mode !== 'Floorplan') {
57
+ this.fiveModeEnabled = false;
58
+ this.render();
59
+ return;
60
+ }
61
+ this.five.once('initAnimationEnded', () => {
62
+ this.fiveModeEnabled = this.five.currentMode === 'Floorplan';
63
+ this.render();
64
+ });
65
+ }
66
+ });
12
67
  this.five = five;
13
68
  this.fiveModeEnabled = this.five.currentMode === 'Floorplan';
14
69
  // init container style
@@ -61,26 +116,12 @@ export class ModelRoomLabelController {
61
116
  this.render();
62
117
  return this;
63
118
  }
64
- /** 监听 Five Mode 变化
65
- * @description
66
- * Mode 不符合要求时,立刻消失,满足要求时,需要等待动画结束再展示
67
- */
68
- onFiveModeChange = (mode) => {
69
- if (mode !== 'Floorplan') {
70
- this.fiveModeEnabled = false;
71
- this.render();
72
- return;
73
- }
74
- this.five.once('initAnimationEnded', () => {
75
- this.fiveModeEnabled = this.five.currentMode === 'Floorplan';
76
- this.render();
77
- });
78
- };
79
119
  render() {
120
+ var _a;
80
121
  if (!this.wrapper)
81
122
  return;
82
123
  if (!this.enabled || !this.fiveModeEnabled) {
83
- this.app?.$destroy();
124
+ (_a = this.app) === null || _a === void 0 ? void 0 : _a.$destroy();
84
125
  this.app = undefined;
85
126
  return;
86
127
  }
@@ -191,15 +191,15 @@ function instance($$self, $$props, $$invalidate) {
191
191
 
192
192
  function getFormatedRoomLabels(five, labels) {
193
193
  const newLabels = labels.map(roomLabelItem => {
194
- // 计算是否可见,入股不可见,不会更新位置
194
+ // 计算是否可见,如果不可见,不会更新位置
195
195
  const visible = getLabelVisible(five, roomLabelItem);
196
196
 
197
- if (!visible) return { ...roomLabelItem, visible };
197
+ if (!visible) return Object.assign(Object.assign({}, roomLabelItem), { visible });
198
198
 
199
199
  // 更新位置
200
200
  const transform = getLabelTransform(five, roomLabelItem);
201
201
 
202
- return { ...roomLabelItem, visible, transform };
202
+ return Object.assign(Object.assign({}, roomLabelItem), { visible, transform });
203
203
  });
204
204
 
205
205
  const sortedRoomLabelItems = newLabels.filter(({ visible }) => visible).map(roomLabelItem => ({
@@ -209,7 +209,7 @@ function instance($$self, $$props, $$invalidate) {
209
209
 
210
210
  return newLabels.map(roomLabelItem => {
211
211
  const sortIndex = sortedRoomLabelItems.findIndex(item => item.roomLabelItem.id === roomLabelItem.id);
212
- if (sortIndex !== undefined) return { ...roomLabelItem, zIndex: sortIndex * 10 };
212
+ if (sortIndex !== undefined) return Object.assign(Object.assign({}, roomLabelItem), { zIndex: sortIndex * 10 });
213
213
  return roomLabelItem;
214
214
  });
215
215
  }
@@ -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
+ }