@realsee/dnalogel 2.0.0-alpha.13 → 2.0.0-alpha.16

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 (62) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +78 -28
  3. package/dist/ModelItemLabelPlugin/index.js +72 -83
  4. package/dist/ModelItemLabelPlugin/typings.d.ts +2 -1
  5. package/dist/ModelRoomLabelPlugin/index.js +1 -0
  6. package/dist/ModelTVVideoPlugin/index.d.ts +4 -0
  7. package/dist/ModelTVVideoPlugin/index.js +326 -0
  8. package/dist/ModelTVVideoPlugin/typings.d.ts +25 -0
  9. package/dist/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
  10. package/dist/PanoMeasurePlugin/index.js +2 -2
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.es.js +349 -86
  13. package/dist/index.js +349 -85
  14. package/dist/index.umd.js +349 -85
  15. package/docs/assets/main.js +1 -1
  16. package/docs/assets/search.js +1 -1
  17. package/docs/classes/ModelRoomLabelController.html +6 -6
  18. package/docs/enums/FLOOR_PLAN_ATTACHED_TO.html +1 -1
  19. package/docs/enums/ModelFloorplanErrorType.html +1 -1
  20. package/docs/index.html +78 -33
  21. package/docs/interfaces/LineJson.html +1 -1
  22. package/docs/interfaces/ModelChassisCompassPluginData.html +1 -1
  23. package/docs/interfaces/ModelChassisCompassPluginExportType.html +1 -1
  24. package/docs/interfaces/ModelChassisCompassPluginParameterType.html +1 -1
  25. package/docs/interfaces/ModelEntryDoorGuidePluginData.html +1 -1
  26. package/docs/interfaces/ModelEntryDoorGuidePluginExportType.html +1 -1
  27. package/docs/interfaces/ModelFloorplanParameterType.html +1 -1
  28. package/docs/interfaces/ModelFloorplanViewEvent.html +2 -2
  29. package/docs/interfaces/ModelItemLabelPluginData.html +1 -0
  30. package/docs/interfaces/ModelItemLabelPluginExportReturnsType.html +1 -0
  31. package/docs/interfaces/ModelItemLabelPluginParametersType.html +1 -0
  32. package/docs/interfaces/ModelRoomLabelPluginData.html +1 -1
  33. package/docs/interfaces/ModelTVVideoPluginData.html +1 -0
  34. package/docs/interfaces/ModelTVVideoPluginExportType.html +1 -0
  35. package/docs/interfaces/ModelTVVideoPluginParameterType.html +1 -0
  36. package/docs/interfaces/PanoCompassPluginData.html +1 -1
  37. package/docs/interfaces/PanoCompassPluginParameterType.html +1 -1
  38. package/docs/interfaces/PanoCursorRaycasterPluginExportType.html +6 -6
  39. package/docs/interfaces/PanoRulerPluginExportType.html +1 -1
  40. package/docs/interfaces/PanoRulerPluginOptions.html +1 -1
  41. package/docs/interfaces/PanoRulerPluginParameterType.html +1 -1
  42. package/docs/interfaces/PanoSpatialTagPluginData.html +1 -1
  43. package/docs/interfaces/PanoSpatialTagPluginExportType.html +1 -1
  44. package/docs/interfaces/PanoSpatialTagPluginParameterType.html +1 -1
  45. package/docs/interfaces/PointJson.html +1 -1
  46. package/docs/interfaces/RoomLabel.html +7 -7
  47. package/docs/interfaces/TopviewFloorplanPluginParameterType.html +1 -1
  48. package/docs/modules.html +12 -12
  49. package/libs/ModelItemLabelPlugin/ItemLabelComponent.js +48 -61
  50. package/libs/ModelItemLabelPlugin/index.js +5 -57
  51. package/libs/ModelItemLabelPlugin/typings.d.ts +2 -1
  52. package/libs/ModelItemLabelPlugin/typings.js +1 -0
  53. package/libs/ModelRoomLabelPlugin/Controller.js +1 -0
  54. package/libs/ModelTVVideoPlugin/index.d.ts +4 -0
  55. package/libs/ModelTVVideoPlugin/index.js +263 -0
  56. package/libs/ModelTVVideoPlugin/typings.d.ts +25 -0
  57. package/libs/ModelTVVideoPlugin/typings.js +7 -0
  58. package/libs/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
  59. package/libs/ModelTVVideoPlugin/utils/parseData.js +13 -0
  60. package/libs/index.d.ts +3 -0
  61. package/libs/index.js +1 -1
  62. package/package.json +2 -1
package/dist/index.es.js CHANGED
@@ -892,6 +892,7 @@ class ModelRoomLabelController {
892
892
  this.container.style.pointerEvents = 'none';
893
893
  this.container.style.left = '0';
894
894
  this.container.style.top = '0';
895
+ this.container.style.zIndex = '5';
895
896
  // five listener
896
897
  this.five.once('dispose', () => this.dispose());
897
898
  this.five.on('modeChange', this.onFiveModeChange);
@@ -10633,10 +10634,10 @@ if (typeof undefined$1 === 'function' && undefined$1.amd) {
10633
10634
 
10634
10635
  var Hammer = hammer.exports;
10635
10636
 
10636
- var Hammer$1 = /*#__PURE__*/_mergeNamespaces({
10637
+ var Hammer$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/_mergeNamespaces({
10637
10638
  __proto__: null,
10638
10639
  'default': Hammer
10639
- }, [hammer.exports]);
10640
+ }, [hammer.exports]));
10640
10641
 
10641
10642
  // uuid
10642
10643
  function S4() {
@@ -14252,6 +14253,7 @@ var DISPLAY_STRATEGY_TYPE;
14252
14253
  DISPLAY_STRATEGY_TYPE["SMALL"] = "small";
14253
14254
  DISPLAY_STRATEGY_TYPE["MIDLLE"] = "middle";
14254
14255
  DISPLAY_STRATEGY_TYPE["LARGE"] = "large";
14256
+ DISPLAY_STRATEGY_TYPE["EXTRA_LARGE"] = "x-large";
14255
14257
  })(DISPLAY_STRATEGY_TYPE || (DISPLAY_STRATEGY_TYPE = {}));
14256
14258
 
14257
14259
  /* src/ModelItemLabelPlugin/ItemLabelItem.svelte generated by Svelte v3.47.0 */
@@ -14365,6 +14367,21 @@ class ItemLabelItem extends SvelteComponent {
14365
14367
  }
14366
14368
  }
14367
14369
 
14370
+ /**
14371
+ * 创建一个防抖动函数,该函数会在 wait 毫秒后调用 func 方法
14372
+ * @param func - 要防抖动的函数
14373
+ * @param [wait=0] - 需要延迟的毫秒数
14374
+ */
14375
+ function debounce(func, wait = 200) {
14376
+ let last;
14377
+ return function (...args) {
14378
+ clearTimeout(last);
14379
+ last = setTimeout(() => {
14380
+ func(...args);
14381
+ }, wait);
14382
+ };
14383
+ }
14384
+
14368
14385
  /* src/ModelItemLabelPlugin/ItemLabelComponent.svelte generated by Svelte v3.47.0 */
14369
14386
 
14370
14387
  function add_css(target) {
@@ -14373,11 +14390,11 @@ function add_css(target) {
14373
14390
 
14374
14391
  function get_each_context(ctx, list, i) {
14375
14392
  const child_ctx = ctx.slice();
14376
- child_ctx[26] = list[i];
14393
+ child_ctx[28] = list[i];
14377
14394
  return child_ctx;
14378
14395
  }
14379
14396
 
14380
- // (179:1) {#each renderItemLabels as itemLabelItem (itemLabelItem.id)}
14397
+ // (162:1) {#each renderItemLabels as itemLabelItem (itemLabelItem.id)}
14381
14398
  function create_each_block(key_1, ctx) {
14382
14399
  let first;
14383
14400
  let itemlabelitem;
@@ -14385,7 +14402,7 @@ function create_each_block(key_1, ctx) {
14385
14402
 
14386
14403
  itemlabelitem = new ItemLabelItem({
14387
14404
  props: {
14388
- itemLabel: /*itemLabelItem*/ ctx[26],
14405
+ itemLabel: /*itemLabelItem*/ ctx[28],
14389
14406
  hooks: /*hooks*/ ctx[0]
14390
14407
  }
14391
14408
  });
@@ -14406,7 +14423,7 @@ function create_each_block(key_1, ctx) {
14406
14423
  p(new_ctx, dirty) {
14407
14424
  ctx = new_ctx;
14408
14425
  const itemlabelitem_changes = {};
14409
- if (dirty & /*renderItemLabels*/ 2) itemlabelitem_changes.itemLabel = /*itemLabelItem*/ ctx[26];
14426
+ if (dirty & /*renderItemLabels*/ 2) itemlabelitem_changes.itemLabel = /*itemLabelItem*/ ctx[28];
14410
14427
  if (dirty & /*hooks*/ 1) itemlabelitem_changes.hooks = /*hooks*/ ctx[0];
14411
14428
  itemlabelitem.$set(itemlabelitem_changes);
14412
14429
  },
@@ -14433,7 +14450,7 @@ function create_fragment(ctx) {
14433
14450
  let div_resize_listener;
14434
14451
  let current;
14435
14452
  let each_value = /*renderItemLabels*/ ctx[1];
14436
- const get_key = ctx => /*itemLabelItem*/ ctx[26].id;
14453
+ const get_key = ctx => /*itemLabelItem*/ ctx[28].id;
14437
14454
 
14438
14455
  for (let i = 0; i < each_value.length; i += 1) {
14439
14456
  let child_ctx = get_each_context(ctx, each_value, i);
@@ -14450,7 +14467,8 @@ function create_fragment(ctx) {
14450
14467
  }
14451
14468
 
14452
14469
  attr(div, "class", "item-labels-container svelte-rmdeb");
14453
- add_render_callback(() => /*div_elementresize_handler*/ ctx[9].call(div));
14470
+ add_render_callback(() => /*div_elementresize_handler*/ ctx[10].call(div));
14471
+ set_style(div, "opacity", /*itemsVisible*/ ctx[4] ? 1 : 0, false);
14454
14472
  },
14455
14473
  m(target, anchor) {
14456
14474
  insert(target, div, anchor);
@@ -14459,7 +14477,7 @@ function create_fragment(ctx) {
14459
14477
  each_blocks[i].m(div, null);
14460
14478
  }
14461
14479
 
14462
- div_resize_listener = add_resize_listener(div, /*div_elementresize_handler*/ ctx[9].bind(div));
14480
+ div_resize_listener = add_resize_listener(div, /*div_elementresize_handler*/ ctx[10].bind(div));
14463
14481
  current = true;
14464
14482
  },
14465
14483
  p(ctx, [dirty]) {
@@ -14469,6 +14487,10 @@ function create_fragment(ctx) {
14469
14487
  each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div, outro_and_destroy_block, create_each_block, null, get_each_context);
14470
14488
  check_outros();
14471
14489
  }
14490
+
14491
+ if (dirty & /*itemsVisible*/ 16) {
14492
+ set_style(div, "opacity", /*itemsVisible*/ ctx[4] ? 1 : 0, false);
14493
+ }
14472
14494
  },
14473
14495
  i(local) {
14474
14496
  if (current) return;
@@ -14518,6 +14540,14 @@ function instance($$self, $$props, $$invalidate) {
14518
14540
  // 计算重叠
14519
14541
  let cssOffsetLists = [];
14520
14542
 
14543
+ // 动画过程中 itemsVisible 为 false
14544
+ let itemsVisible = true;
14545
+
14546
+ /**
14547
+ * 可见性策略:
14548
+ * 1、当前楼层(假设先不考虑多楼层)
14549
+ * 2、模型未被遮挡(一个 box 有没有被遮挡的计算? TODO)
14550
+ * */
14521
14551
  const getLabelVisible = (five, itemLabel) => {
14522
14552
  // 虚拟 VR 仅有一层,不考虑楼层信息
14523
14553
  const raycaster = new Raycaster();
@@ -14571,6 +14601,8 @@ function instance($$self, $$props, $$invalidate) {
14571
14601
  return Math.ceil(-38.9 * itemSpaceHeight + 130);
14572
14602
  case DISPLAY_STRATEGY_TYPE.LARGE:
14573
14603
  return Math.ceil(-44.44 * itemSpaceHeight + 140);
14604
+ case DISPLAY_STRATEGY_TYPE.EXTRA_LARGE:
14605
+ return Math.ceil(-92.59 * itemSpaceHeight + 300);
14574
14606
  }
14575
14607
  }
14576
14608
 
@@ -14617,15 +14649,27 @@ function instance($$self, $$props, $$invalidate) {
14617
14649
  addDataUpdateListener();
14618
14650
  });
14619
14651
 
14652
+ const handleCameraUpdateCallback = () => {
14653
+ $$invalidate(4, itemsVisible = false);
14654
+ handleCameraUpdate();
14655
+ };
14656
+
14620
14657
  onMount(() => {
14621
14658
  $$invalidate(1, renderItemLabels = itemLabels);
14622
14659
  curItemLabels = itemLabels;
14623
14660
  onItemLabelUpdate();
14624
-
14625
- // five.on('cameraUpdate', onItemLabelUpdate)
14626
14661
  addResizeListener();
14662
+ five.on('cameraUpdate', handleCameraUpdateCallback);
14627
14663
  });
14628
14664
 
14665
+ const handleCameraUpdate = debounce(
14666
+ () => {
14667
+ $$invalidate(4, itemsVisible = true);
14668
+ onItemLabelUpdate();
14669
+ },
14670
+ 300
14671
+ );
14672
+
14629
14673
  const addResizeListener = () => {
14630
14674
  wrapperSize = {
14631
14675
  width: wrapper.clientWidth,
@@ -14639,7 +14683,6 @@ function instance($$self, $$props, $$invalidate) {
14639
14683
  if (curItemLabels !== itemLabels) {
14640
14684
  $$invalidate(1, renderItemLabels = itemLabels);
14641
14685
  curItemLabels = itemLabels;
14642
- console.log('--debug--update--');
14643
14686
  onItemLabelUpdate();
14644
14687
  }
14645
14688
  };
@@ -14657,13 +14700,11 @@ function instance($$self, $$props, $$invalidate) {
14657
14700
  });
14658
14701
 
14659
14702
  onDestroy(() => {
14660
- // five.off('cameraUpdate', onItemLabelUpdate)
14703
+ five.off('cameraUpdate', handleCameraUpdateCallback);
14661
14704
  resizeObserver.unobserve(wrapper);
14662
-
14663
- curItemLabels = null;
14664
- $$invalidate(1, renderItemLabels = null);
14665
- wrapperSize = { width: 0, height: 0 };
14666
- });
14705
+ }); // curItemLabels = null
14706
+ // renderItemLabels = null
14707
+ // wrapperSize = { width: 0, height: 0 }
14667
14708
 
14668
14709
  function div_elementresize_handler() {
14669
14710
  containerWidth = this.clientWidth;
@@ -14673,12 +14714,12 @@ function instance($$self, $$props, $$invalidate) {
14673
14714
  }
14674
14715
 
14675
14716
  $$self.$$set = $$props => {
14676
- if ('five' in $$props) $$invalidate(4, five = $$props.five);
14677
- if ('modelOcclusionEnable' in $$props) $$invalidate(5, modelOcclusionEnable = $$props.modelOcclusionEnable);
14678
- if ('itemLabels' in $$props) $$invalidate(6, itemLabels = $$props.itemLabels);
14679
- if ('wrapper' in $$props) $$invalidate(7, wrapper = $$props.wrapper);
14717
+ if ('five' in $$props) $$invalidate(5, five = $$props.five);
14718
+ if ('modelOcclusionEnable' in $$props) $$invalidate(6, modelOcclusionEnable = $$props.modelOcclusionEnable);
14719
+ if ('itemLabels' in $$props) $$invalidate(7, itemLabels = $$props.itemLabels);
14720
+ if ('wrapper' in $$props) $$invalidate(8, wrapper = $$props.wrapper);
14680
14721
  if ('hooks' in $$props) $$invalidate(0, hooks = $$props.hooks);
14681
- if ('displayStrategyType' in $$props) $$invalidate(8, displayStrategyType = $$props.displayStrategyType);
14722
+ if ('displayStrategyType' in $$props) $$invalidate(9, displayStrategyType = $$props.displayStrategyType);
14682
14723
  };
14683
14724
 
14684
14725
  return [
@@ -14686,6 +14727,7 @@ function instance($$self, $$props, $$invalidate) {
14686
14727
  renderItemLabels,
14687
14728
  containerWidth,
14688
14729
  containerHeight,
14730
+ itemsVisible,
14689
14731
  five,
14690
14732
  modelOcclusionEnable,
14691
14733
  itemLabels,
@@ -14706,12 +14748,12 @@ class ItemLabelComponent extends SvelteComponent {
14706
14748
  create_fragment,
14707
14749
  safe_not_equal,
14708
14750
  {
14709
- five: 4,
14710
- modelOcclusionEnable: 5,
14711
- itemLabels: 6,
14712
- wrapper: 7,
14751
+ five: 5,
14752
+ modelOcclusionEnable: 6,
14753
+ itemLabels: 7,
14754
+ wrapper: 8,
14713
14755
  hooks: 0,
14714
- displayStrategyType: 8
14756
+ displayStrategyType: 9
14715
14757
  },
14716
14758
  add_css
14717
14759
  );
@@ -14735,7 +14777,7 @@ const ModelItemLabelPlugin = (five, params) => {
14735
14777
  app: undefined,
14736
14778
  hooks: new Subscribe(),
14737
14779
  modelOcclusionEnable: (_a = params === null || params === void 0 ? void 0 : params.modelOcclusionEnable) !== null && _a !== void 0 ? _a : true,
14738
- displayStrategyType: (_b = params === null || params === void 0 ? void 0 : params.displayStrategyType) !== null && _b !== void 0 ? _b : DISPLAY_STRATEGY_TYPE.SMALL
14780
+ displayStrategyType: (_b = params === null || params === void 0 ? void 0 : params.displayStrategyType) !== null && _b !== void 0 ? _b : DISPLAY_STRATEGY_TYPE.SMALL,
14739
14781
  };
14740
14782
  pluginState.container.setAttribute('class', 'model-item-label-plugin-container');
14741
14783
  pluginState.container.style.cssText = `
@@ -14744,8 +14786,9 @@ const ModelItemLabelPlugin = (five, params) => {
14744
14786
  top: 0;
14745
14787
  width: 100%;
14746
14788
  height: 100%;
14747
- pointerEvents: none;
14789
+ z-index: 5;
14748
14790
  `;
14791
+ pluginState.container.style.pointerEvents = 'none'; // 写到 cssText 里不生效
14749
14792
  const appendTo = (wrapper) => {
14750
14793
  pluginState.wrapper = wrapper;
14751
14794
  wrapper.appendChild(pluginState.container);
@@ -14753,7 +14796,6 @@ const ModelItemLabelPlugin = (five, params) => {
14753
14796
  return true;
14754
14797
  };
14755
14798
  const load = (data) => {
14756
- console.log('🐶--当前标签总条数: ', data.model_item_labels.length);
14757
14799
  pluginState.itemLabels = parseModelItemLabelPluginData(data);
14758
14800
  render();
14759
14801
  };
@@ -14775,40 +14817,6 @@ const ModelItemLabelPlugin = (five, params) => {
14775
14817
  removeListener4Five();
14776
14818
  pluginState.container.remove();
14777
14819
  };
14778
- const handleRerender = () => {
14779
- if (!pluginState.enabled || !pluginState.fiveModeEnabled)
14780
- return;
14781
- disable();
14782
- };
14783
- const rerender = (a, b, c) => {
14784
- if (!pluginState.fiveModeEnabled)
14785
- return;
14786
- if (!c)
14787
- return;
14788
- enable();
14789
- render();
14790
- };
14791
- const handleInteriaPanRerender = (a, b) => {
14792
- if (!pluginState.fiveModeEnabled)
14793
- return;
14794
- if (!b)
14795
- return;
14796
- enable();
14797
- render();
14798
- };
14799
- const handleWantsPanGesture = (pose, final) => {
14800
- if (pose) {
14801
- handleRerender();
14802
- }
14803
- };
14804
- const handlePanGesture = (pose, final) => {
14805
- if (!pluginState.fiveModeEnabled)
14806
- return;
14807
- if (!final)
14808
- return;
14809
- enable();
14810
- render();
14811
- };
14812
14820
  const render = () => {
14813
14821
  var _a;
14814
14822
  if (!pluginState.wrapper)
@@ -14844,32 +14852,14 @@ const ModelItemLabelPlugin = (five, params) => {
14844
14852
  const addListener4Five = () => {
14845
14853
  five.on('modeChange', onFiveModeChange);
14846
14854
  five.once('dispose', dispose);
14847
- // five.on('wantsGesture', handleRerender)
14848
- // five.on('gesture', rerender)
14849
- five.on('wantsMouseWheel', handleRerender);
14850
- five.on('mouseWheel', rerender);
14851
- five.on('wantsInteriaPan', handleRerender);
14852
- five.on('interiaPan', handleInteriaPanRerender);
14853
- five.on('wantsPanGesture', handleWantsPanGesture);
14854
- five.on('panGesture', handlePanGesture);
14855
- five.on('wantsPinchGesture', handleRerender);
14856
- five.on('pinchGesture', rerender);
14857
14855
  };
14858
14856
  // 取消 five 监听
14859
14857
  const removeListener4Five = () => {
14860
14858
  five.off('modeChange', onFiveModeChange);
14861
- // five.off('wantsGesture', handleRerender)
14862
- // five.off('gesture', rerender)
14863
- five.off('wantsMouseWheel', handleRerender);
14864
- five.off('mouseWheel', rerender);
14865
- five.off('wantsInteriaPan', handleRerender);
14866
- five.off('interiaPan', handleInteriaPanRerender);
14867
- five.off('wantsPanGesture', handleWantsPanGesture);
14868
- five.off('panGesture', handlePanGesture);
14869
- five.off('wantsPinchGesture', handleRerender);
14870
- five.off('pinchGesture', rerender);
14871
14859
  };
14872
14860
  const onFiveModeChange = (mode) => {
14861
+ if (!pluginState.enabled)
14862
+ return;
14873
14863
  if (mode !== Five.Mode.Floorplan) {
14874
14864
  pluginState.fiveModeEnabled = false;
14875
14865
  render();
@@ -14891,4 +14881,277 @@ const ModelItemLabelPlugin = (five, params) => {
14891
14881
  };
14892
14882
  };
14893
14883
 
14894
- export { CSS3DRenderPlugin, CameraMovementPlugin, FLOOR_PLAN_ATTACHED_TO, ModelChassisCompassPlugin, ModelEntryDoorGuidePlugin, ModelFloorplanPlugin, ModelItemLabelPlugin, ModelRoomLabelPlugin, ModelViewPlugin, PanoCompassPlugin, PanoCursorRaycasterPlugin, PanoFloorplanRadarPlugin, PanoMeasurePlugin, PanoRulerPlugin, PanoSpatialTagPlugin, TopviewFloorplanPlugin };
14884
+ var DIRECTION;
14885
+ (function (DIRECTION) {
14886
+ DIRECTION["TOP_LEFT"] = "topLeft";
14887
+ DIRECTION["TOP_RIGHT"] = "topRight";
14888
+ DIRECTION["BOTTOM_LEFT"] = "bottomLeft";
14889
+ DIRECTION["BOTTOM_RIGHT"] = "bottomRight";
14890
+ })(DIRECTION || (DIRECTION = {}));
14891
+
14892
+ function parseModelTVVideoPoints(points) {
14893
+ if (points.length === 0)
14894
+ return [];
14895
+ if (Array.isArray(points[0]))
14896
+ return points;
14897
+ let newPoints = [];
14898
+ points.map(point => {
14899
+ const newPoint = [point[DIRECTION.TOP_LEFT], point[DIRECTION.BOTTOM_LEFT], point[DIRECTION.BOTTOM_RIGHT], point[DIRECTION.TOP_RIGHT]];
14900
+ newPoints.push(newPoint);
14901
+ });
14902
+ return newPoints;
14903
+ }
14904
+
14905
+ const ModelTVVideoPlugin = (five, { videoElement }) => {
14906
+ const state = {
14907
+ videoMeshes: [],
14908
+ videoTextureEnabled: false,
14909
+ videoSource: '',
14910
+ rectPoints: [],
14911
+ enabled: false,
14912
+ videoElement: videoElement,
14913
+ };
14914
+ const setMuted = (muted) => {
14915
+ if (state.videoTexture) {
14916
+ state.videoTexture.image.muted = muted;
14917
+ state.videoTexture.image.play();
14918
+ }
14919
+ };
14920
+ const getMuted = () => {
14921
+ if (state.videoTexture)
14922
+ return state.videoTexture.image.muted;
14923
+ else
14924
+ return true;
14925
+ };
14926
+ const enable = () => {
14927
+ if (state.enabled)
14928
+ return;
14929
+ if (!state.videoTexture)
14930
+ return;
14931
+ state.enabled = true;
14932
+ state.videoMeshes = createPanoVideoMeshes();
14933
+ console.log('state.videoMeshes', state.videoMeshes);
14934
+ state.videoMeshes.forEach((mesh) => five.scene.add(mesh));
14935
+ const play = () => {
14936
+ console.log('play', state.videoTexture);
14937
+ if (!state.videoTexture)
14938
+ return;
14939
+ const timeupdate = () => {
14940
+ var _a;
14941
+ if (!state.videoTexture)
14942
+ return;
14943
+ (_a = state.videoTexture) === null || _a === void 0 ? void 0 : _a.image.removeEventListener('timeupdate', timeupdate);
14944
+ state.videoTextureEnabled = true;
14945
+ state.videoMeshes.forEach((mesh) => {
14946
+ if (mesh.material.map !== state.videoTexture)
14947
+ mesh.material.map = state.videoTexture;
14948
+ });
14949
+ five.needsRender = true;
14950
+ };
14951
+ state.videoTexture.image.addEventListener('timeupdate', timeupdate);
14952
+ if (state.videoTexture && state.videoMeshes.length) {
14953
+ state.videoTexture.image.play();
14954
+ }
14955
+ };
14956
+ if (five.model.loaded)
14957
+ play();
14958
+ else {
14959
+ return five.once('modelLoaded', () => play());
14960
+ }
14961
+ };
14962
+ const disable = () => {
14963
+ if (!state.enabled)
14964
+ return;
14965
+ state.enabled = false;
14966
+ state.videoMeshes.forEach((mesh) => {
14967
+ mesh.geometry.dispose();
14968
+ mesh.material.dispose();
14969
+ five.scene.remove(mesh);
14970
+ if (state.videoTexture)
14971
+ state.videoTexture.image.pause();
14972
+ });
14973
+ state.videoMeshes = [];
14974
+ five.needsRender = true;
14975
+ };
14976
+ const createPanoVideoMeshes = () => {
14977
+ return state.rectPoints.map((points, index) => {
14978
+ const geometry = new THREE.BufferGeometry();
14979
+ const segments = 128;
14980
+ const verticesArray = [];
14981
+ verticesArray.push(points[0].x, points[0].y, points[0].z);
14982
+ for (let i = 1; i < segments; i++) {
14983
+ 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);
14984
+ }
14985
+ verticesArray.push(points[1].x, points[1].y, points[1].z);
14986
+ verticesArray.push(points[2].x, points[2].y, points[2].z);
14987
+ for (let i = 1; i < segments; i++) {
14988
+ 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);
14989
+ }
14990
+ verticesArray.push(points[3].x, points[3].y, points[3].z);
14991
+ const uvArray = [];
14992
+ uvArray.push(0, 1);
14993
+ for (let i = 1; i < segments; i++) {
14994
+ uvArray.push(0, 1 - i / segments);
14995
+ }
14996
+ uvArray.push(0, 0);
14997
+ uvArray.push(1, 0);
14998
+ for (let i = 1; i < segments; i++) {
14999
+ uvArray.push(1, i / segments);
15000
+ }
15001
+ uvArray.push(1, 1);
15002
+ const indicesArray = [];
15003
+ for (let i = 0; i < segments; i++) {
15004
+ indicesArray.push(i, i + 1, segments * 2 - i, i, segments * 2 - i, segments * 2 + 1 - i);
15005
+ }
15006
+ geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(verticesArray), 3));
15007
+ geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvArray), 2));
15008
+ geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(indicesArray), 1));
15009
+ const material = new THREE.MeshBasicMaterial({
15010
+ map: state.videoTextureEnabled ? state.videoTexture : state.imageTexture,
15011
+ side: THREE.DoubleSide,
15012
+ });
15013
+ const mesh = new THREE.Mesh(geometry, material);
15014
+ mesh.renderOrder = 1;
15015
+ mesh.name = `ModelTVVideoPlugin-${index}-${performance.now()}`;
15016
+ return mesh;
15017
+ });
15018
+ };
15019
+ const getImageTexture = (source) => {
15020
+ const texture = new THREE.TextureLoader().load(source);
15021
+ texture.minFilter = THREE.LinearFilter;
15022
+ texture.magFilter = THREE.LinearFilter;
15023
+ texture.format = THREE.RGBFormat;
15024
+ return texture;
15025
+ };
15026
+ const getVideoTexture = (source, video) => {
15027
+ return new Promise((resolve, reject) => {
15028
+ const xhr = new XMLHttpRequest();
15029
+ xhr.onreadystatechange = () => {
15030
+ if (xhr.readyState == 4) {
15031
+ if (xhr.status == 200) {
15032
+ const url = window.URL || window.webkitURL;
15033
+ video = video || document.createElement('video');
15034
+ video.crossOrigin = 'anonymous';
15035
+ video.autoplay = true;
15036
+ video.muted = true;
15037
+ video.loop = true;
15038
+ video.playsInline = true;
15039
+ video.src = url.createObjectURL(xhr.response);
15040
+ const texture = new THREE.VideoTexture(video);
15041
+ texture.minFilter = THREE.LinearFilter;
15042
+ texture.magFilter = THREE.LinearFilter;
15043
+ texture.format = THREE.RGBFormat;
15044
+ resolve(Object.assign(texture, { videoSource: source }));
15045
+ }
15046
+ else {
15047
+ reject(new Error('Video download Error: ' + xhr.status));
15048
+ }
15049
+ }
15050
+ };
15051
+ xhr.onerror = (error) => reject(error);
15052
+ xhr.open('GET', source);
15053
+ xhr.responseType = 'blob';
15054
+ xhr.send();
15055
+ });
15056
+ };
15057
+ const load = (data, videoElement) => __awaiter(void 0, void 0, void 0, function* () {
15058
+ const { video_src, video_poster_src, points } = data;
15059
+ state.videoSource = video_src;
15060
+ // TODO 存疑,先处理多一次遍历 o(2n)
15061
+ state.rectPoints = parseModelTVVideoPoints(points)
15062
+ .map((items) => items.map(({ x, y, z }) => new THREE.Vector3(x, y, z)));
15063
+ state.imageTexture = getImageTexture(video_poster_src);
15064
+ if (videoElement) {
15065
+ state.videoElement = videoElement;
15066
+ }
15067
+ state.videoTexture = yield getVideoTexture(state.videoSource, state.videoElement);
15068
+ state.enabled = !!data.enable;
15069
+ if (state.enabled)
15070
+ enable();
15071
+ });
15072
+ const dispose = () => {
15073
+ disable();
15074
+ state.videoTexture = undefined;
15075
+ five.off('modeChange', () => setMuted(true));
15076
+ five.off('wantsTapGesture', (raycaster) => {
15077
+ if (!state.enabled)
15078
+ return;
15079
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15080
+ if (!!intersect && /^video/.test(intersect.object.name)) {
15081
+ if (state.videoTexture)
15082
+ setMuted(!state.videoTexture.image.muted);
15083
+ return false;
15084
+ }
15085
+ });
15086
+ five.off('panoArrived', () => {
15087
+ if (!state.enabled)
15088
+ return;
15089
+ if (getMuted())
15090
+ return;
15091
+ const cameraPosition = five.camera.position;
15092
+ const visible = state.rectPoints.find((points) => {
15093
+ 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());
15094
+ return (points.map((point) => new THREE.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
15095
+ vector = vector.clone().sub(cameraPosition).normalize();
15096
+ const raycaster = new THREE.Raycaster(cameraPosition, vector);
15097
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15098
+ return !!intersect && /^video/.test(intersect.object.name);
15099
+ }).length >= 2);
15100
+ });
15101
+ if (!visible)
15102
+ setMuted(true);
15103
+ });
15104
+ five.off('renderFrame', () => {
15105
+ // console.log('renderFrame', state.videoMeshes)
15106
+ state.videoMeshes.forEach((meshes) => {
15107
+ if (meshes)
15108
+ //@ts-ignore
15109
+ meshes.needsRender = true;
15110
+ });
15111
+ });
15112
+ };
15113
+ five.on('modeChange', () => setMuted(true));
15114
+ five.on('wantsTapGesture', (raycaster) => {
15115
+ if (!state.enabled)
15116
+ return;
15117
+ const targetMesh = five.scene.children.find(item => /^ModelTVVideoPlugin/.test(item.name));
15118
+ if (!targetMesh)
15119
+ return;
15120
+ const intersectObjects = raycaster.intersectObjects([targetMesh]);
15121
+ if (intersectObjects.length === 0)
15122
+ return;
15123
+ if (state.videoTexture)
15124
+ setMuted(!state.videoTexture.image.muted); // TODO toggle video play
15125
+ return false;
15126
+ });
15127
+ five.on('panoArrived', () => {
15128
+ if (!state.enabled)
15129
+ return;
15130
+ if (getMuted())
15131
+ return;
15132
+ const cameraPosition = five.camera.position;
15133
+ const visible = state.rectPoints.find((points) => {
15134
+ 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());
15135
+ return (points.map((point) => new THREE.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
15136
+ vector = vector.clone().sub(cameraPosition).normalize();
15137
+ const raycaster = new THREE.Raycaster(cameraPosition, vector);
15138
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15139
+ return !!intersect && /^video/.test(intersect.object.name);
15140
+ }).length >= 2);
15141
+ });
15142
+ if (!visible)
15143
+ setMuted(true);
15144
+ });
15145
+ five.on('renderFrame', () => {
15146
+ // console.log('renderFrame', state.videoMeshes)
15147
+ state.videoMeshes.forEach((meshes) => {
15148
+ if (meshes)
15149
+ //@ts-ignore
15150
+ meshes.needsRender = true;
15151
+ });
15152
+ });
15153
+ Object.assign(window, { $state: state });
15154
+ return { enable, disable, load, dispose };
15155
+ };
15156
+
15157
+ export { CSS3DRenderPlugin, CameraMovementPlugin, FLOOR_PLAN_ATTACHED_TO, ModelChassisCompassPlugin, ModelEntryDoorGuidePlugin, ModelFloorplanPlugin, ModelItemLabelPlugin, ModelRoomLabelPlugin, ModelTVVideoPlugin, ModelViewPlugin, PanoCompassPlugin, PanoCursorRaycasterPlugin, PanoFloorplanRadarPlugin, PanoMeasurePlugin, PanoRulerPlugin, PanoSpatialTagPlugin, TopviewFloorplanPlugin };