@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.
- package/CHANGELOG.md +11 -0
- package/README.md +78 -28
- package/dist/CSS3DRenderPlugin/index.js +17 -14
- package/dist/CameraMovementPlugin/index.js +40 -15
- package/dist/ModelChassisCompassPlugin/index.js +32 -6
- package/dist/ModelEntryDoorGuidePlugin/index.js +48 -18
- package/dist/ModelItemLabelPlugin/events.type.d.ts +9 -0
- package/dist/ModelItemLabelPlugin/index.d.ts +4 -0
- package/dist/ModelItemLabelPlugin/index.js +691 -0
- package/dist/ModelItemLabelPlugin/typings.d.ts +56 -0
- package/dist/ModelItemLabelPlugin/utils/parseData.d.ts +3 -0
- package/dist/ModelRoomLabelPlugin/index.js +68 -27
- package/dist/ModelTVVideoPlugin/index.d.ts +4 -0
- package/dist/ModelTVVideoPlugin/index.js +326 -0
- package/dist/ModelTVVideoPlugin/typings.d.ts +25 -0
- package/dist/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
- package/dist/PanoCompassPlugin/index.js +311 -164
- package/dist/PanoCursorRaycasterPlugin/index.js +5 -3
- package/dist/PanoMeasurePlugin/index.js +1335 -581
- package/dist/PanoRulerPlugin/index.js +32 -5
- package/dist/PanoSpatialTagPlugin/index.js +73 -38
- package/dist/floorplan/ModelFloorplanPlugin/index.js +586 -362
- package/dist/floorplan/PanoFloorplanRadarPlugin/index.js +164 -72
- package/dist/floorplan/TopviewFloorplanPlugin/index.js +311 -153
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +3790 -1539
- package/dist/index.js +3794 -1540
- package/dist/index.umd.js +3797 -1544
- package/docs/assets/search.js +1 -1
- package/docs/classes/ModelRoomLabelController.html +6 -6
- package/docs/enums/FLOOR_PLAN_ATTACHED_TO.html +1 -1
- package/docs/enums/ModelFloorplanErrorType.html +1 -1
- package/docs/index.html +78 -33
- package/docs/interfaces/LineJson.html +1 -1
- package/docs/interfaces/ModelChassisCompassPluginData.html +1 -1
- package/docs/interfaces/ModelChassisCompassPluginExportType.html +1 -1
- package/docs/interfaces/ModelChassisCompassPluginParameterType.html +1 -1
- package/docs/interfaces/ModelEntryDoorGuidePluginData.html +1 -1
- package/docs/interfaces/ModelEntryDoorGuidePluginExportType.html +1 -1
- package/docs/interfaces/ModelFloorplanParameterType.html +1 -1
- package/docs/interfaces/ModelFloorplanViewEvent.html +2 -2
- package/docs/interfaces/ModelItemLabelPluginData.html +1 -0
- package/docs/interfaces/ModelItemLabelPluginExportReturnsType.html +1 -0
- package/docs/interfaces/ModelItemLabelPluginParametersType.html +1 -0
- package/docs/interfaces/ModelRoomLabelPluginData.html +1 -1
- package/docs/interfaces/ModelTVVideoPluginData.html +1 -0
- package/docs/interfaces/ModelTVVideoPluginExportType.html +1 -0
- package/docs/interfaces/ModelTVVideoPluginParameterType.html +1 -0
- package/docs/interfaces/PanoCompassPluginData.html +1 -1
- package/docs/interfaces/PanoCompassPluginParameterType.html +1 -1
- package/docs/interfaces/PanoCursorRaycasterPluginExportType.html +6 -6
- package/docs/interfaces/PanoRulerPluginExportType.html +1 -1
- package/docs/interfaces/PanoRulerPluginOptions.html +1 -1
- package/docs/interfaces/PanoRulerPluginParameterType.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginData.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginExportType.html +1 -1
- package/docs/interfaces/PanoSpatialTagPluginParameterType.html +1 -1
- package/docs/interfaces/PointJson.html +1 -1
- package/docs/interfaces/RoomLabel.html +7 -7
- package/docs/interfaces/TopviewFloorplanPluginParameterType.html +1 -1
- package/docs/modules.html +12 -12
- package/libs/CSS3DRenderPlugin/index.js +16 -13
- package/libs/CameraMovementPlugin/index.js +24 -15
- package/libs/ModelChassisCompassPlugin/index.js +14 -5
- package/libs/ModelEntryDoorGuidePlugin/index.js +24 -12
- package/libs/ModelItemLabelPlugin/ItemLabelComponent.js +422 -0
- package/libs/ModelItemLabelPlugin/ItemLabelItem.js +133 -0
- package/libs/ModelItemLabelPlugin/events.type.d.ts +9 -0
- package/libs/ModelItemLabelPlugin/events.type.js +1 -0
- package/libs/ModelItemLabelPlugin/index.d.ts +4 -0
- package/libs/ModelItemLabelPlugin/index.js +184 -0
- package/libs/ModelItemLabelPlugin/typings.d.ts +56 -0
- package/libs/ModelItemLabelPlugin/typings.js +6 -0
- package/libs/ModelItemLabelPlugin/utils/parseData.d.ts +3 -0
- package/libs/ModelItemLabelPlugin/utils/parseData.js +4 -0
- package/libs/ModelRoomLabelPlugin/Controller.js +64 -23
- package/libs/ModelRoomLabelPlugin/RoomLabelItems.js +4 -4
- package/libs/ModelTVVideoPlugin/index.d.ts +4 -0
- package/libs/ModelTVVideoPlugin/index.js +263 -0
- package/libs/ModelTVVideoPlugin/typings.d.ts +25 -0
- package/libs/ModelTVVideoPlugin/typings.js +7 -0
- package/libs/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
- package/libs/ModelTVVideoPlugin/utils/parseData.js +13 -0
- package/libs/PanoCompassPlugin/index.js +225 -128
- package/libs/PanoCursorRaycasterPlugin/index.js +5 -3
- package/libs/PanoMeasurePlugin/Controller/BaseController.js +68 -13
- package/libs/PanoMeasurePlugin/Controller/EditController.js +267 -154
- package/libs/PanoMeasurePlugin/Controller/ShortcutKeyController.js +40 -20
- package/libs/PanoMeasurePlugin/Controller/WatchController.js +234 -152
- package/libs/PanoMeasurePlugin/Controller/index.js +131 -47
- package/libs/PanoMeasurePlugin/Model/index.js +30 -5
- package/libs/PanoMeasurePlugin/Model/line.js +60 -10
- package/libs/PanoMeasurePlugin/Model/point.js +24 -4
- package/libs/PanoMeasurePlugin/Model/polyline.js +20 -3
- package/libs/PanoMeasurePlugin/Modules/DeleteDom/index.js +59 -14
- package/libs/PanoMeasurePlugin/Modules/FiveHelper.js +23 -8
- package/libs/PanoMeasurePlugin/Modules/GuideController.js +61 -26
- package/libs/PanoMeasurePlugin/Modules/Magnifier.js +60 -10
- package/libs/PanoMeasurePlugin/Modules/UIController/MainBtnController.js +83 -37
- package/libs/PanoMeasurePlugin/Modules/UIController/Revoke/index.js +52 -17
- package/libs/PanoMeasurePlugin/Modules/UIController/index.js +61 -30
- package/libs/PanoMeasurePlugin/utils/distanceDom.js +3 -2
- package/libs/PanoMeasurePlugin/utils/line.js +8 -7
- package/libs/PanoRulerPlugin/index.js +16 -5
- package/libs/PanoSpatialTagPlugin/Components/tag.js +9 -9
- package/libs/PanoSpatialTagPlugin/index.js +11 -9
- package/libs/floorplan/Components/BaseImage.js +10 -5
- package/libs/floorplan/Components/RoomHighlight/RoomHighlight.js +3 -1
- package/libs/floorplan/Components/RoomMaterials/RoomMaterial.js +5 -6
- package/libs/floorplan/ModelFloorplanPlugin/Components/Compass.js +7 -2
- package/libs/floorplan/ModelFloorplanPlugin/Components/RoomLabels/RoomLabel.js +3 -1
- package/libs/floorplan/ModelFloorplanPlugin/Controller.js +456 -273
- package/libs/floorplan/ModelFloorplanPlugin/utils/correctFiveState.js +33 -22
- package/libs/floorplan/PanoFloorplanRadarPlugin/Components/CurrentFloor/CurrentFloor.js +3 -1
- package/libs/floorplan/PanoFloorplanRadarPlugin/Controller.js +97 -36
- package/libs/floorplan/TopviewFloorplanPlugin/Controller.js +231 -108
- package/libs/floorplan/utils/formatData.js +43 -28
- package/libs/floorplan/utils/formatPosition.js +1 -1
- package/libs/index.d.ts +4 -0
- package/libs/index.js +2 -0
- package/libs/shared-utils/Subscribe.js +8 -1
- package/libs/shared-utils/animationFrame/BetterTween.js +47 -18
- package/libs/shared-utils/createCanvasTextTexture.js +6 -5
- package/libs/shared-utils/five/changeMode.js +23 -12
- package/libs/shared-utils/getPxmm.js +1 -1
- package/libs/shared-utils/math/evenNumber.js +1 -1
- package/libs/shared-utils/three/loadFbxObj.js +20 -9
- package/libs/shared-utils/three/loadTexture.js +17 -6
- package/libs/shared-utils/three/transfromToMeshBasicMaterial.js +2 -1
- package/libs/shared-utils/tinyEJSrender.js +36 -6
- package/libs/shared-utils/to.js +21 -10
- package/libs/shared-utils/useDebounce.js +1 -1
- package/libs/shared-utils/useThrottle.js +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import ItemLabelComponent from './ItemLabelComponent.svelte';
|
|
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
|
+
}
|
|
@@ -275,15 +275,15 @@ function instance($$self, $$props, $$invalidate) {
|
|
|
275
275
|
|
|
276
276
|
function getFormatedRoomLabels(five, labels) {
|
|
277
277
|
const newLabels = labels.map(roomLabelItem => {
|
|
278
|
-
//
|
|
278
|
+
// 计算是否可见,如果不可见,不会更新位置
|
|
279
279
|
const visible = getLabelVisible(five, roomLabelItem);
|
|
280
280
|
|
|
281
|
-
if (!visible) return {
|
|
281
|
+
if (!visible) return Object.assign(Object.assign({}, roomLabelItem), { visible });
|
|
282
282
|
|
|
283
283
|
// 更新位置
|
|
284
284
|
const transform = getLabelTransform(five, roomLabelItem);
|
|
285
285
|
|
|
286
|
-
return {
|
|
286
|
+
return Object.assign(Object.assign({}, roomLabelItem), { visible, transform });
|
|
287
287
|
});
|
|
288
288
|
|
|
289
289
|
const sortedRoomLabelItems = newLabels.filter(({ visible }) => visible).map(roomLabelItem => ({
|
|
@@ -293,7 +293,7 @@ function instance($$self, $$props, $$invalidate) {
|
|
|
293
293
|
|
|
294
294
|
return newLabels.map(roomLabelItem => {
|
|
295
295
|
const sortIndex = sortedRoomLabelItems.findIndex(item => item.roomLabelItem.id === roomLabelItem.id);
|
|
296
|
-
if (sortIndex !== undefined) return {
|
|
296
|
+
if (sortIndex !== undefined) return Object.assign(Object.assign({}, roomLabelItem), { zIndex: sortIndex * 10 });
|
|
297
297
|
return roomLabelItem;
|
|
298
298
|
});
|
|
299
299
|
}
|
|
@@ -352,14 +352,69 @@ function parseModelRoomLabelPluginData(data) {
|
|
|
352
352
|
}
|
|
353
353
|
|
|
354
354
|
class ModelRoomLabelController {
|
|
355
|
-
five;
|
|
356
|
-
enabled = true;
|
|
357
|
-
fiveModeEnabled;
|
|
358
|
-
app = undefined;
|
|
359
|
-
wrapper;
|
|
360
|
-
roomLabels = [];
|
|
361
|
-
container = document.createElement('div');
|
|
362
355
|
constructor(five) {
|
|
356
|
+
Object.defineProperty(this, "five", {
|
|
357
|
+
enumerable: true,
|
|
358
|
+
configurable: true,
|
|
359
|
+
writable: true,
|
|
360
|
+
value: void 0
|
|
361
|
+
});
|
|
362
|
+
Object.defineProperty(this, "enabled", {
|
|
363
|
+
enumerable: true,
|
|
364
|
+
configurable: true,
|
|
365
|
+
writable: true,
|
|
366
|
+
value: true
|
|
367
|
+
});
|
|
368
|
+
Object.defineProperty(this, "fiveModeEnabled", {
|
|
369
|
+
enumerable: true,
|
|
370
|
+
configurable: true,
|
|
371
|
+
writable: true,
|
|
372
|
+
value: void 0
|
|
373
|
+
});
|
|
374
|
+
Object.defineProperty(this, "app", {
|
|
375
|
+
enumerable: true,
|
|
376
|
+
configurable: true,
|
|
377
|
+
writable: true,
|
|
378
|
+
value: undefined
|
|
379
|
+
});
|
|
380
|
+
Object.defineProperty(this, "wrapper", {
|
|
381
|
+
enumerable: true,
|
|
382
|
+
configurable: true,
|
|
383
|
+
writable: true,
|
|
384
|
+
value: void 0
|
|
385
|
+
});
|
|
386
|
+
Object.defineProperty(this, "roomLabels", {
|
|
387
|
+
enumerable: true,
|
|
388
|
+
configurable: true,
|
|
389
|
+
writable: true,
|
|
390
|
+
value: []
|
|
391
|
+
});
|
|
392
|
+
Object.defineProperty(this, "container", {
|
|
393
|
+
enumerable: true,
|
|
394
|
+
configurable: true,
|
|
395
|
+
writable: true,
|
|
396
|
+
value: document.createElement('div')
|
|
397
|
+
});
|
|
398
|
+
/** 监听 Five Mode 变化
|
|
399
|
+
* @description
|
|
400
|
+
* Mode 不符合要求时,立刻消失,满足要求时,需要等待动画结束再展示
|
|
401
|
+
*/
|
|
402
|
+
Object.defineProperty(this, "onFiveModeChange", {
|
|
403
|
+
enumerable: true,
|
|
404
|
+
configurable: true,
|
|
405
|
+
writable: true,
|
|
406
|
+
value: (mode) => {
|
|
407
|
+
if (mode !== 'Floorplan') {
|
|
408
|
+
this.fiveModeEnabled = false;
|
|
409
|
+
this.render();
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
this.five.once('initAnimationEnded', () => {
|
|
413
|
+
this.fiveModeEnabled = this.five.currentMode === 'Floorplan';
|
|
414
|
+
this.render();
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
});
|
|
363
418
|
this.five = five;
|
|
364
419
|
this.fiveModeEnabled = this.five.currentMode === 'Floorplan';
|
|
365
420
|
// init container style
|
|
@@ -412,26 +467,12 @@ class ModelRoomLabelController {
|
|
|
412
467
|
this.render();
|
|
413
468
|
return this;
|
|
414
469
|
}
|
|
415
|
-
/** 监听 Five Mode 变化
|
|
416
|
-
* @description
|
|
417
|
-
* Mode 不符合要求时,立刻消失,满足要求时,需要等待动画结束再展示
|
|
418
|
-
*/
|
|
419
|
-
onFiveModeChange = (mode) => {
|
|
420
|
-
if (mode !== 'Floorplan') {
|
|
421
|
-
this.fiveModeEnabled = false;
|
|
422
|
-
this.render();
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
this.five.once('initAnimationEnded', () => {
|
|
426
|
-
this.fiveModeEnabled = this.five.currentMode === 'Floorplan';
|
|
427
|
-
this.render();
|
|
428
|
-
});
|
|
429
|
-
};
|
|
430
470
|
render() {
|
|
471
|
+
var _a;
|
|
431
472
|
if (!this.wrapper)
|
|
432
473
|
return;
|
|
433
474
|
if (!this.enabled || !this.fiveModeEnabled) {
|
|
434
|
-
this.app
|
|
475
|
+
(_a = this.app) === null || _a === void 0 ? void 0 : _a.$destroy();
|
|
435
476
|
this.app = undefined;
|
|
436
477
|
return;
|
|
437
478
|
}
|
|
@@ -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,326 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var THREE = require('three');
|
|
6
|
+
|
|
7
|
+
function _interopNamespace(e) {
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n["default"] = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
26
|
+
|
|
27
|
+
/*! *****************************************************************************
|
|
28
|
+
Copyright (c) Microsoft Corporation.
|
|
29
|
+
|
|
30
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
31
|
+
purpose with or without fee is hereby granted.
|
|
32
|
+
|
|
33
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
34
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
35
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
36
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
37
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
38
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
39
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
40
|
+
***************************************************************************** */
|
|
41
|
+
|
|
42
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
43
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
44
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
45
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
46
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
47
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
48
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var DIRECTION;
|
|
53
|
+
(function (DIRECTION) {
|
|
54
|
+
DIRECTION["TOP_LEFT"] = "topLeft";
|
|
55
|
+
DIRECTION["TOP_RIGHT"] = "topRight";
|
|
56
|
+
DIRECTION["BOTTOM_LEFT"] = "bottomLeft";
|
|
57
|
+
DIRECTION["BOTTOM_RIGHT"] = "bottomRight";
|
|
58
|
+
})(DIRECTION || (DIRECTION = {}));
|
|
59
|
+
|
|
60
|
+
function parseModelTVVideoPoints(points) {
|
|
61
|
+
if (points.length === 0)
|
|
62
|
+
return [];
|
|
63
|
+
if (Array.isArray(points[0]))
|
|
64
|
+
return points;
|
|
65
|
+
let newPoints = [];
|
|
66
|
+
points.map(point => {
|
|
67
|
+
const newPoint = [point[DIRECTION.TOP_LEFT], point[DIRECTION.BOTTOM_LEFT], point[DIRECTION.BOTTOM_RIGHT], point[DIRECTION.TOP_RIGHT]];
|
|
68
|
+
newPoints.push(newPoint);
|
|
69
|
+
});
|
|
70
|
+
return newPoints;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const ModelTVVideoPlugin = (five, { videoElement }) => {
|
|
74
|
+
const state = {
|
|
75
|
+
videoMeshes: [],
|
|
76
|
+
videoTextureEnabled: false,
|
|
77
|
+
videoSource: '',
|
|
78
|
+
rectPoints: [],
|
|
79
|
+
enabled: false,
|
|
80
|
+
videoElement: videoElement,
|
|
81
|
+
};
|
|
82
|
+
const setMuted = (muted) => {
|
|
83
|
+
if (state.videoTexture) {
|
|
84
|
+
state.videoTexture.image.muted = muted;
|
|
85
|
+
state.videoTexture.image.play();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const getMuted = () => {
|
|
89
|
+
if (state.videoTexture)
|
|
90
|
+
return state.videoTexture.image.muted;
|
|
91
|
+
else
|
|
92
|
+
return true;
|
|
93
|
+
};
|
|
94
|
+
const enable = () => {
|
|
95
|
+
if (state.enabled)
|
|
96
|
+
return;
|
|
97
|
+
if (!state.videoTexture)
|
|
98
|
+
return;
|
|
99
|
+
state.enabled = true;
|
|
100
|
+
state.videoMeshes = createPanoVideoMeshes();
|
|
101
|
+
console.log('state.videoMeshes', state.videoMeshes);
|
|
102
|
+
state.videoMeshes.forEach((mesh) => five.scene.add(mesh));
|
|
103
|
+
const play = () => {
|
|
104
|
+
console.log('play', state.videoTexture);
|
|
105
|
+
if (!state.videoTexture)
|
|
106
|
+
return;
|
|
107
|
+
const timeupdate = () => {
|
|
108
|
+
var _a;
|
|
109
|
+
if (!state.videoTexture)
|
|
110
|
+
return;
|
|
111
|
+
(_a = state.videoTexture) === null || _a === void 0 ? void 0 : _a.image.removeEventListener('timeupdate', timeupdate);
|
|
112
|
+
state.videoTextureEnabled = true;
|
|
113
|
+
state.videoMeshes.forEach((mesh) => {
|
|
114
|
+
if (mesh.material.map !== state.videoTexture)
|
|
115
|
+
mesh.material.map = state.videoTexture;
|
|
116
|
+
});
|
|
117
|
+
five.needsRender = true;
|
|
118
|
+
};
|
|
119
|
+
state.videoTexture.image.addEventListener('timeupdate', timeupdate);
|
|
120
|
+
if (state.videoTexture && state.videoMeshes.length) {
|
|
121
|
+
state.videoTexture.image.play();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
if (five.model.loaded)
|
|
125
|
+
play();
|
|
126
|
+
else {
|
|
127
|
+
return five.once('modelLoaded', () => play());
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const disable = () => {
|
|
131
|
+
if (!state.enabled)
|
|
132
|
+
return;
|
|
133
|
+
state.enabled = false;
|
|
134
|
+
state.videoMeshes.forEach((mesh) => {
|
|
135
|
+
mesh.geometry.dispose();
|
|
136
|
+
mesh.material.dispose();
|
|
137
|
+
five.scene.remove(mesh);
|
|
138
|
+
if (state.videoTexture)
|
|
139
|
+
state.videoTexture.image.pause();
|
|
140
|
+
});
|
|
141
|
+
state.videoMeshes = [];
|
|
142
|
+
five.needsRender = true;
|
|
143
|
+
};
|
|
144
|
+
const createPanoVideoMeshes = () => {
|
|
145
|
+
return state.rectPoints.map((points, index) => {
|
|
146
|
+
const geometry = new THREE__namespace.BufferGeometry();
|
|
147
|
+
const segments = 128;
|
|
148
|
+
const verticesArray = [];
|
|
149
|
+
verticesArray.push(points[0].x, points[0].y, points[0].z);
|
|
150
|
+
for (let i = 1; i < segments; i++) {
|
|
151
|
+
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);
|
|
152
|
+
}
|
|
153
|
+
verticesArray.push(points[1].x, points[1].y, points[1].z);
|
|
154
|
+
verticesArray.push(points[2].x, points[2].y, points[2].z);
|
|
155
|
+
for (let i = 1; i < segments; i++) {
|
|
156
|
+
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);
|
|
157
|
+
}
|
|
158
|
+
verticesArray.push(points[3].x, points[3].y, points[3].z);
|
|
159
|
+
const uvArray = [];
|
|
160
|
+
uvArray.push(0, 1);
|
|
161
|
+
for (let i = 1; i < segments; i++) {
|
|
162
|
+
uvArray.push(0, 1 - i / segments);
|
|
163
|
+
}
|
|
164
|
+
uvArray.push(0, 0);
|
|
165
|
+
uvArray.push(1, 0);
|
|
166
|
+
for (let i = 1; i < segments; i++) {
|
|
167
|
+
uvArray.push(1, i / segments);
|
|
168
|
+
}
|
|
169
|
+
uvArray.push(1, 1);
|
|
170
|
+
const indicesArray = [];
|
|
171
|
+
for (let i = 0; i < segments; i++) {
|
|
172
|
+
indicesArray.push(i, i + 1, segments * 2 - i, i, segments * 2 - i, segments * 2 + 1 - i);
|
|
173
|
+
}
|
|
174
|
+
geometry.setAttribute('position', new THREE__namespace.BufferAttribute(new Float32Array(verticesArray), 3));
|
|
175
|
+
geometry.setAttribute('uv', new THREE__namespace.BufferAttribute(new Float32Array(uvArray), 2));
|
|
176
|
+
geometry.setIndex(new THREE__namespace.BufferAttribute(new Uint32Array(indicesArray), 1));
|
|
177
|
+
const material = new THREE__namespace.MeshBasicMaterial({
|
|
178
|
+
map: state.videoTextureEnabled ? state.videoTexture : state.imageTexture,
|
|
179
|
+
side: THREE__namespace.DoubleSide,
|
|
180
|
+
});
|
|
181
|
+
const mesh = new THREE__namespace.Mesh(geometry, material);
|
|
182
|
+
mesh.renderOrder = 1;
|
|
183
|
+
mesh.name = `ModelTVVideoPlugin-${index}-${performance.now()}`;
|
|
184
|
+
return mesh;
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
const getImageTexture = (source) => {
|
|
188
|
+
const texture = new THREE__namespace.TextureLoader().load(source);
|
|
189
|
+
texture.minFilter = THREE__namespace.LinearFilter;
|
|
190
|
+
texture.magFilter = THREE__namespace.LinearFilter;
|
|
191
|
+
texture.format = THREE__namespace.RGBFormat;
|
|
192
|
+
return texture;
|
|
193
|
+
};
|
|
194
|
+
const getVideoTexture = (source, video) => {
|
|
195
|
+
return new Promise((resolve, reject) => {
|
|
196
|
+
const xhr = new XMLHttpRequest();
|
|
197
|
+
xhr.onreadystatechange = () => {
|
|
198
|
+
if (xhr.readyState == 4) {
|
|
199
|
+
if (xhr.status == 200) {
|
|
200
|
+
const url = window.URL || window.webkitURL;
|
|
201
|
+
video = video || document.createElement('video');
|
|
202
|
+
video.crossOrigin = 'anonymous';
|
|
203
|
+
video.autoplay = true;
|
|
204
|
+
video.muted = true;
|
|
205
|
+
video.loop = true;
|
|
206
|
+
video.playsInline = true;
|
|
207
|
+
video.src = url.createObjectURL(xhr.response);
|
|
208
|
+
const texture = new THREE__namespace.VideoTexture(video);
|
|
209
|
+
texture.minFilter = THREE__namespace.LinearFilter;
|
|
210
|
+
texture.magFilter = THREE__namespace.LinearFilter;
|
|
211
|
+
texture.format = THREE__namespace.RGBFormat;
|
|
212
|
+
resolve(Object.assign(texture, { videoSource: source }));
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
reject(new Error('Video download Error: ' + xhr.status));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
xhr.onerror = (error) => reject(error);
|
|
220
|
+
xhr.open('GET', source);
|
|
221
|
+
xhr.responseType = 'blob';
|
|
222
|
+
xhr.send();
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
const load = (data, videoElement) => __awaiter(void 0, void 0, void 0, function* () {
|
|
226
|
+
const { video_src, video_poster_src, points } = data;
|
|
227
|
+
state.videoSource = video_src;
|
|
228
|
+
// TODO 存疑,先处理多一次遍历 o(2n)
|
|
229
|
+
state.rectPoints = parseModelTVVideoPoints(points)
|
|
230
|
+
.map((items) => items.map(({ x, y, z }) => new THREE__namespace.Vector3(x, y, z)));
|
|
231
|
+
state.imageTexture = getImageTexture(video_poster_src);
|
|
232
|
+
if (videoElement) {
|
|
233
|
+
state.videoElement = videoElement;
|
|
234
|
+
}
|
|
235
|
+
state.videoTexture = yield getVideoTexture(state.videoSource, state.videoElement);
|
|
236
|
+
state.enabled = !!data.enable;
|
|
237
|
+
if (state.enabled)
|
|
238
|
+
enable();
|
|
239
|
+
});
|
|
240
|
+
const dispose = () => {
|
|
241
|
+
disable();
|
|
242
|
+
state.videoTexture = undefined;
|
|
243
|
+
five.off('modeChange', () => setMuted(true));
|
|
244
|
+
five.off('wantsTapGesture', (raycaster) => {
|
|
245
|
+
if (!state.enabled)
|
|
246
|
+
return;
|
|
247
|
+
const [intersect] = raycaster.intersectObjects(five.scene.children, true);
|
|
248
|
+
if (!!intersect && /^video/.test(intersect.object.name)) {
|
|
249
|
+
if (state.videoTexture)
|
|
250
|
+
setMuted(!state.videoTexture.image.muted);
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
five.off('panoArrived', () => {
|
|
255
|
+
if (!state.enabled)
|
|
256
|
+
return;
|
|
257
|
+
if (getMuted())
|
|
258
|
+
return;
|
|
259
|
+
const cameraPosition = five.camera.position;
|
|
260
|
+
const visible = state.rectPoints.find((points) => {
|
|
261
|
+
const centerVector = points.reduce((total, curr) => new THREE__namespace.Vector3(total.x + curr.x / points.length, total.y + curr.y / points.length, total.z + curr.z / points.length), new THREE__namespace.Vector3());
|
|
262
|
+
return (points.map((point) => new THREE__namespace.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
|
|
263
|
+
vector = vector.clone().sub(cameraPosition).normalize();
|
|
264
|
+
const raycaster = new THREE__namespace.Raycaster(cameraPosition, vector);
|
|
265
|
+
const [intersect] = raycaster.intersectObjects(five.scene.children, true);
|
|
266
|
+
return !!intersect && /^video/.test(intersect.object.name);
|
|
267
|
+
}).length >= 2);
|
|
268
|
+
});
|
|
269
|
+
if (!visible)
|
|
270
|
+
setMuted(true);
|
|
271
|
+
});
|
|
272
|
+
five.off('renderFrame', () => {
|
|
273
|
+
// console.log('renderFrame', state.videoMeshes)
|
|
274
|
+
state.videoMeshes.forEach((meshes) => {
|
|
275
|
+
if (meshes)
|
|
276
|
+
//@ts-ignore
|
|
277
|
+
meshes.needsRender = true;
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
five.on('modeChange', () => setMuted(true));
|
|
282
|
+
five.on('wantsTapGesture', (raycaster) => {
|
|
283
|
+
if (!state.enabled)
|
|
284
|
+
return;
|
|
285
|
+
const targetMesh = five.scene.children.find(item => /^ModelTVVideoPlugin/.test(item.name));
|
|
286
|
+
if (!targetMesh)
|
|
287
|
+
return;
|
|
288
|
+
const intersectObjects = raycaster.intersectObjects([targetMesh]);
|
|
289
|
+
if (intersectObjects.length === 0)
|
|
290
|
+
return;
|
|
291
|
+
if (state.videoTexture)
|
|
292
|
+
setMuted(!state.videoTexture.image.muted); // TODO toggle video play
|
|
293
|
+
return false;
|
|
294
|
+
});
|
|
295
|
+
five.on('panoArrived', () => {
|
|
296
|
+
if (!state.enabled)
|
|
297
|
+
return;
|
|
298
|
+
if (getMuted())
|
|
299
|
+
return;
|
|
300
|
+
const cameraPosition = five.camera.position;
|
|
301
|
+
const visible = state.rectPoints.find((points) => {
|
|
302
|
+
const centerVector = points.reduce((total, curr) => new THREE__namespace.Vector3(total.x + curr.x / points.length, total.y + curr.y / points.length, total.z + curr.z / points.length), new THREE__namespace.Vector3());
|
|
303
|
+
return (points.map((point) => new THREE__namespace.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
|
|
304
|
+
vector = vector.clone().sub(cameraPosition).normalize();
|
|
305
|
+
const raycaster = new THREE__namespace.Raycaster(cameraPosition, vector);
|
|
306
|
+
const [intersect] = raycaster.intersectObjects(five.scene.children, true);
|
|
307
|
+
return !!intersect && /^video/.test(intersect.object.name);
|
|
308
|
+
}).length >= 2);
|
|
309
|
+
});
|
|
310
|
+
if (!visible)
|
|
311
|
+
setMuted(true);
|
|
312
|
+
});
|
|
313
|
+
five.on('renderFrame', () => {
|
|
314
|
+
// console.log('renderFrame', state.videoMeshes)
|
|
315
|
+
state.videoMeshes.forEach((meshes) => {
|
|
316
|
+
if (meshes)
|
|
317
|
+
//@ts-ignore
|
|
318
|
+
meshes.needsRender = true;
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
Object.assign(window, { $state: state });
|
|
322
|
+
return { enable, disable, load, dispose };
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
exports.ModelTVVideoPlugin = ModelTVVideoPlugin;
|
|
326
|
+
exports["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
|
+
}
|