@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.umd.js CHANGED
@@ -908,6 +908,7 @@
908
908
  this.container.style.pointerEvents = 'none';
909
909
  this.container.style.left = '0';
910
910
  this.container.style.top = '0';
911
+ this.container.style.zIndex = '5';
911
912
  // five listener
912
913
  this.five.once('dispose', () => this.dispose());
913
914
  this.five.on('modeChange', this.onFiveModeChange);
@@ -10649,10 +10650,10 @@
10649
10650
 
10650
10651
  var Hammer = hammer.exports;
10651
10652
 
10652
- var Hammer$1 = /*#__PURE__*/_mergeNamespaces({
10653
+ var Hammer$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/_mergeNamespaces({
10653
10654
  __proto__: null,
10654
10655
  'default': Hammer
10655
- }, [hammer.exports]);
10656
+ }, [hammer.exports]));
10656
10657
 
10657
10658
  // uuid
10658
10659
  function S4() {
@@ -14268,6 +14269,7 @@
14268
14269
  DISPLAY_STRATEGY_TYPE["SMALL"] = "small";
14269
14270
  DISPLAY_STRATEGY_TYPE["MIDLLE"] = "middle";
14270
14271
  DISPLAY_STRATEGY_TYPE["LARGE"] = "large";
14272
+ DISPLAY_STRATEGY_TYPE["EXTRA_LARGE"] = "x-large";
14271
14273
  })(DISPLAY_STRATEGY_TYPE || (DISPLAY_STRATEGY_TYPE = {}));
14272
14274
 
14273
14275
  /* src/ModelItemLabelPlugin/ItemLabelItem.svelte generated by Svelte v3.47.0 */
@@ -14381,6 +14383,21 @@
14381
14383
  }
14382
14384
  }
14383
14385
 
14386
+ /**
14387
+ * 创建一个防抖动函数,该函数会在 wait 毫秒后调用 func 方法
14388
+ * @param func - 要防抖动的函数
14389
+ * @param [wait=0] - 需要延迟的毫秒数
14390
+ */
14391
+ function debounce(func, wait = 200) {
14392
+ let last;
14393
+ return function (...args) {
14394
+ clearTimeout(last);
14395
+ last = setTimeout(() => {
14396
+ func(...args);
14397
+ }, wait);
14398
+ };
14399
+ }
14400
+
14384
14401
  /* src/ModelItemLabelPlugin/ItemLabelComponent.svelte generated by Svelte v3.47.0 */
14385
14402
 
14386
14403
  function add_css(target) {
@@ -14389,11 +14406,11 @@
14389
14406
 
14390
14407
  function get_each_context(ctx, list, i) {
14391
14408
  const child_ctx = ctx.slice();
14392
- child_ctx[26] = list[i];
14409
+ child_ctx[28] = list[i];
14393
14410
  return child_ctx;
14394
14411
  }
14395
14412
 
14396
- // (179:1) {#each renderItemLabels as itemLabelItem (itemLabelItem.id)}
14413
+ // (162:1) {#each renderItemLabels as itemLabelItem (itemLabelItem.id)}
14397
14414
  function create_each_block(key_1, ctx) {
14398
14415
  let first;
14399
14416
  let itemlabelitem;
@@ -14401,7 +14418,7 @@
14401
14418
 
14402
14419
  itemlabelitem = new ItemLabelItem({
14403
14420
  props: {
14404
- itemLabel: /*itemLabelItem*/ ctx[26],
14421
+ itemLabel: /*itemLabelItem*/ ctx[28],
14405
14422
  hooks: /*hooks*/ ctx[0]
14406
14423
  }
14407
14424
  });
@@ -14422,7 +14439,7 @@
14422
14439
  p(new_ctx, dirty) {
14423
14440
  ctx = new_ctx;
14424
14441
  const itemlabelitem_changes = {};
14425
- if (dirty & /*renderItemLabels*/ 2) itemlabelitem_changes.itemLabel = /*itemLabelItem*/ ctx[26];
14442
+ if (dirty & /*renderItemLabels*/ 2) itemlabelitem_changes.itemLabel = /*itemLabelItem*/ ctx[28];
14426
14443
  if (dirty & /*hooks*/ 1) itemlabelitem_changes.hooks = /*hooks*/ ctx[0];
14427
14444
  itemlabelitem.$set(itemlabelitem_changes);
14428
14445
  },
@@ -14449,7 +14466,7 @@
14449
14466
  let div_resize_listener;
14450
14467
  let current;
14451
14468
  let each_value = /*renderItemLabels*/ ctx[1];
14452
- const get_key = ctx => /*itemLabelItem*/ ctx[26].id;
14469
+ const get_key = ctx => /*itemLabelItem*/ ctx[28].id;
14453
14470
 
14454
14471
  for (let i = 0; i < each_value.length; i += 1) {
14455
14472
  let child_ctx = get_each_context(ctx, each_value, i);
@@ -14466,7 +14483,8 @@
14466
14483
  }
14467
14484
 
14468
14485
  internal.attr(div, "class", "item-labels-container svelte-rmdeb");
14469
- internal.add_render_callback(() => /*div_elementresize_handler*/ ctx[9].call(div));
14486
+ internal.add_render_callback(() => /*div_elementresize_handler*/ ctx[10].call(div));
14487
+ internal.set_style(div, "opacity", /*itemsVisible*/ ctx[4] ? 1 : 0, false);
14470
14488
  },
14471
14489
  m(target, anchor) {
14472
14490
  internal.insert(target, div, anchor);
@@ -14475,7 +14493,7 @@
14475
14493
  each_blocks[i].m(div, null);
14476
14494
  }
14477
14495
 
14478
- div_resize_listener = internal.add_resize_listener(div, /*div_elementresize_handler*/ ctx[9].bind(div));
14496
+ div_resize_listener = internal.add_resize_listener(div, /*div_elementresize_handler*/ ctx[10].bind(div));
14479
14497
  current = true;
14480
14498
  },
14481
14499
  p(ctx, [dirty]) {
@@ -14485,6 +14503,10 @@
14485
14503
  each_blocks = internal.update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div, internal.outro_and_destroy_block, create_each_block, null, get_each_context);
14486
14504
  internal.check_outros();
14487
14505
  }
14506
+
14507
+ if (dirty & /*itemsVisible*/ 16) {
14508
+ internal.set_style(div, "opacity", /*itemsVisible*/ ctx[4] ? 1 : 0, false);
14509
+ }
14488
14510
  },
14489
14511
  i(local) {
14490
14512
  if (current) return;
@@ -14534,6 +14556,14 @@
14534
14556
  // 计算重叠
14535
14557
  let cssOffsetLists = [];
14536
14558
 
14559
+ // 动画过程中 itemsVisible 为 false
14560
+ let itemsVisible = true;
14561
+
14562
+ /**
14563
+ * 可见性策略:
14564
+ * 1、当前楼层(假设先不考虑多楼层)
14565
+ * 2、模型未被遮挡(一个 box 有没有被遮挡的计算? TODO)
14566
+ * */
14537
14567
  const getLabelVisible = (five, itemLabel) => {
14538
14568
  // 虚拟 VR 仅有一层,不考虑楼层信息
14539
14569
  const raycaster = new Raycaster();
@@ -14587,6 +14617,8 @@
14587
14617
  return Math.ceil(-38.9 * itemSpaceHeight + 130);
14588
14618
  case DISPLAY_STRATEGY_TYPE.LARGE:
14589
14619
  return Math.ceil(-44.44 * itemSpaceHeight + 140);
14620
+ case DISPLAY_STRATEGY_TYPE.EXTRA_LARGE:
14621
+ return Math.ceil(-92.59 * itemSpaceHeight + 300);
14590
14622
  }
14591
14623
  }
14592
14624
 
@@ -14633,15 +14665,27 @@
14633
14665
  addDataUpdateListener();
14634
14666
  });
14635
14667
 
14668
+ const handleCameraUpdateCallback = () => {
14669
+ $$invalidate(4, itemsVisible = false);
14670
+ handleCameraUpdate();
14671
+ };
14672
+
14636
14673
  svelte.onMount(() => {
14637
14674
  $$invalidate(1, renderItemLabels = itemLabels);
14638
14675
  curItemLabels = itemLabels;
14639
14676
  onItemLabelUpdate();
14640
-
14641
- // five.on('cameraUpdate', onItemLabelUpdate)
14642
14677
  addResizeListener();
14678
+ five.on('cameraUpdate', handleCameraUpdateCallback);
14643
14679
  });
14644
14680
 
14681
+ const handleCameraUpdate = debounce(
14682
+ () => {
14683
+ $$invalidate(4, itemsVisible = true);
14684
+ onItemLabelUpdate();
14685
+ },
14686
+ 300
14687
+ );
14688
+
14645
14689
  const addResizeListener = () => {
14646
14690
  wrapperSize = {
14647
14691
  width: wrapper.clientWidth,
@@ -14655,7 +14699,6 @@
14655
14699
  if (curItemLabels !== itemLabels) {
14656
14700
  $$invalidate(1, renderItemLabels = itemLabels);
14657
14701
  curItemLabels = itemLabels;
14658
- console.log('--debug--update--');
14659
14702
  onItemLabelUpdate();
14660
14703
  }
14661
14704
  };
@@ -14673,13 +14716,11 @@
14673
14716
  });
14674
14717
 
14675
14718
  svelte.onDestroy(() => {
14676
- // five.off('cameraUpdate', onItemLabelUpdate)
14719
+ five.off('cameraUpdate', handleCameraUpdateCallback);
14677
14720
  resizeObserver.unobserve(wrapper);
14678
-
14679
- curItemLabels = null;
14680
- $$invalidate(1, renderItemLabels = null);
14681
- wrapperSize = { width: 0, height: 0 };
14682
- });
14721
+ }); // curItemLabels = null
14722
+ // renderItemLabels = null
14723
+ // wrapperSize = { width: 0, height: 0 }
14683
14724
 
14684
14725
  function div_elementresize_handler() {
14685
14726
  containerWidth = this.clientWidth;
@@ -14689,12 +14730,12 @@
14689
14730
  }
14690
14731
 
14691
14732
  $$self.$$set = $$props => {
14692
- if ('five' in $$props) $$invalidate(4, five = $$props.five);
14693
- if ('modelOcclusionEnable' in $$props) $$invalidate(5, modelOcclusionEnable = $$props.modelOcclusionEnable);
14694
- if ('itemLabels' in $$props) $$invalidate(6, itemLabels = $$props.itemLabels);
14695
- if ('wrapper' in $$props) $$invalidate(7, wrapper = $$props.wrapper);
14733
+ if ('five' in $$props) $$invalidate(5, five = $$props.five);
14734
+ if ('modelOcclusionEnable' in $$props) $$invalidate(6, modelOcclusionEnable = $$props.modelOcclusionEnable);
14735
+ if ('itemLabels' in $$props) $$invalidate(7, itemLabels = $$props.itemLabels);
14736
+ if ('wrapper' in $$props) $$invalidate(8, wrapper = $$props.wrapper);
14696
14737
  if ('hooks' in $$props) $$invalidate(0, hooks = $$props.hooks);
14697
- if ('displayStrategyType' in $$props) $$invalidate(8, displayStrategyType = $$props.displayStrategyType);
14738
+ if ('displayStrategyType' in $$props) $$invalidate(9, displayStrategyType = $$props.displayStrategyType);
14698
14739
  };
14699
14740
 
14700
14741
  return [
@@ -14702,6 +14743,7 @@
14702
14743
  renderItemLabels,
14703
14744
  containerWidth,
14704
14745
  containerHeight,
14746
+ itemsVisible,
14705
14747
  five,
14706
14748
  modelOcclusionEnable,
14707
14749
  itemLabels,
@@ -14722,12 +14764,12 @@
14722
14764
  create_fragment,
14723
14765
  internal.safe_not_equal,
14724
14766
  {
14725
- five: 4,
14726
- modelOcclusionEnable: 5,
14727
- itemLabels: 6,
14728
- wrapper: 7,
14767
+ five: 5,
14768
+ modelOcclusionEnable: 6,
14769
+ itemLabels: 7,
14770
+ wrapper: 8,
14729
14771
  hooks: 0,
14730
- displayStrategyType: 8
14772
+ displayStrategyType: 9
14731
14773
  },
14732
14774
  add_css
14733
14775
  );
@@ -14751,7 +14793,7 @@
14751
14793
  app: undefined,
14752
14794
  hooks: new five.Subscribe(),
14753
14795
  modelOcclusionEnable: (_a = params === null || params === void 0 ? void 0 : params.modelOcclusionEnable) !== null && _a !== void 0 ? _a : true,
14754
- displayStrategyType: (_b = params === null || params === void 0 ? void 0 : params.displayStrategyType) !== null && _b !== void 0 ? _b : DISPLAY_STRATEGY_TYPE.SMALL
14796
+ displayStrategyType: (_b = params === null || params === void 0 ? void 0 : params.displayStrategyType) !== null && _b !== void 0 ? _b : DISPLAY_STRATEGY_TYPE.SMALL,
14755
14797
  };
14756
14798
  pluginState.container.setAttribute('class', 'model-item-label-plugin-container');
14757
14799
  pluginState.container.style.cssText = `
@@ -14760,8 +14802,9 @@
14760
14802
  top: 0;
14761
14803
  width: 100%;
14762
14804
  height: 100%;
14763
- pointerEvents: none;
14805
+ z-index: 5;
14764
14806
  `;
14807
+ pluginState.container.style.pointerEvents = 'none'; // 写到 cssText 里不生效
14765
14808
  const appendTo = (wrapper) => {
14766
14809
  pluginState.wrapper = wrapper;
14767
14810
  wrapper.appendChild(pluginState.container);
@@ -14769,7 +14812,6 @@
14769
14812
  return true;
14770
14813
  };
14771
14814
  const load = (data) => {
14772
- console.log('🐶--当前标签总条数: ', data.model_item_labels.length);
14773
14815
  pluginState.itemLabels = parseModelItemLabelPluginData(data);
14774
14816
  render();
14775
14817
  };
@@ -14791,40 +14833,6 @@
14791
14833
  removeListener4Five();
14792
14834
  pluginState.container.remove();
14793
14835
  };
14794
- const handleRerender = () => {
14795
- if (!pluginState.enabled || !pluginState.fiveModeEnabled)
14796
- return;
14797
- disable();
14798
- };
14799
- const rerender = (a, b, c) => {
14800
- if (!pluginState.fiveModeEnabled)
14801
- return;
14802
- if (!c)
14803
- return;
14804
- enable();
14805
- render();
14806
- };
14807
- const handleInteriaPanRerender = (a, b) => {
14808
- if (!pluginState.fiveModeEnabled)
14809
- return;
14810
- if (!b)
14811
- return;
14812
- enable();
14813
- render();
14814
- };
14815
- const handleWantsPanGesture = (pose, final) => {
14816
- if (pose) {
14817
- handleRerender();
14818
- }
14819
- };
14820
- const handlePanGesture = (pose, final) => {
14821
- if (!pluginState.fiveModeEnabled)
14822
- return;
14823
- if (!final)
14824
- return;
14825
- enable();
14826
- render();
14827
- };
14828
14836
  const render = () => {
14829
14837
  var _a;
14830
14838
  if (!pluginState.wrapper)
@@ -14860,32 +14868,14 @@
14860
14868
  const addListener4Five = () => {
14861
14869
  five$1.on('modeChange', onFiveModeChange);
14862
14870
  five$1.once('dispose', dispose);
14863
- // five.on('wantsGesture', handleRerender)
14864
- // five.on('gesture', rerender)
14865
- five$1.on('wantsMouseWheel', handleRerender);
14866
- five$1.on('mouseWheel', rerender);
14867
- five$1.on('wantsInteriaPan', handleRerender);
14868
- five$1.on('interiaPan', handleInteriaPanRerender);
14869
- five$1.on('wantsPanGesture', handleWantsPanGesture);
14870
- five$1.on('panGesture', handlePanGesture);
14871
- five$1.on('wantsPinchGesture', handleRerender);
14872
- five$1.on('pinchGesture', rerender);
14873
14871
  };
14874
14872
  // 取消 five 监听
14875
14873
  const removeListener4Five = () => {
14876
14874
  five$1.off('modeChange', onFiveModeChange);
14877
- // five.off('wantsGesture', handleRerender)
14878
- // five.off('gesture', rerender)
14879
- five$1.off('wantsMouseWheel', handleRerender);
14880
- five$1.off('mouseWheel', rerender);
14881
- five$1.off('wantsInteriaPan', handleRerender);
14882
- five$1.off('interiaPan', handleInteriaPanRerender);
14883
- five$1.off('wantsPanGesture', handleWantsPanGesture);
14884
- five$1.off('panGesture', handlePanGesture);
14885
- five$1.off('wantsPinchGesture', handleRerender);
14886
- five$1.off('pinchGesture', rerender);
14887
14875
  };
14888
14876
  const onFiveModeChange = (mode) => {
14877
+ if (!pluginState.enabled)
14878
+ return;
14889
14879
  if (mode !== five.Five.Mode.Floorplan) {
14890
14880
  pluginState.fiveModeEnabled = false;
14891
14881
  render();
@@ -14907,6 +14897,279 @@
14907
14897
  };
14908
14898
  };
14909
14899
 
14900
+ var DIRECTION;
14901
+ (function (DIRECTION) {
14902
+ DIRECTION["TOP_LEFT"] = "topLeft";
14903
+ DIRECTION["TOP_RIGHT"] = "topRight";
14904
+ DIRECTION["BOTTOM_LEFT"] = "bottomLeft";
14905
+ DIRECTION["BOTTOM_RIGHT"] = "bottomRight";
14906
+ })(DIRECTION || (DIRECTION = {}));
14907
+
14908
+ function parseModelTVVideoPoints(points) {
14909
+ if (points.length === 0)
14910
+ return [];
14911
+ if (Array.isArray(points[0]))
14912
+ return points;
14913
+ let newPoints = [];
14914
+ points.map(point => {
14915
+ const newPoint = [point[DIRECTION.TOP_LEFT], point[DIRECTION.BOTTOM_LEFT], point[DIRECTION.BOTTOM_RIGHT], point[DIRECTION.TOP_RIGHT]];
14916
+ newPoints.push(newPoint);
14917
+ });
14918
+ return newPoints;
14919
+ }
14920
+
14921
+ const ModelTVVideoPlugin = (five, { videoElement }) => {
14922
+ const state = {
14923
+ videoMeshes: [],
14924
+ videoTextureEnabled: false,
14925
+ videoSource: '',
14926
+ rectPoints: [],
14927
+ enabled: false,
14928
+ videoElement: videoElement,
14929
+ };
14930
+ const setMuted = (muted) => {
14931
+ if (state.videoTexture) {
14932
+ state.videoTexture.image.muted = muted;
14933
+ state.videoTexture.image.play();
14934
+ }
14935
+ };
14936
+ const getMuted = () => {
14937
+ if (state.videoTexture)
14938
+ return state.videoTexture.image.muted;
14939
+ else
14940
+ return true;
14941
+ };
14942
+ const enable = () => {
14943
+ if (state.enabled)
14944
+ return;
14945
+ if (!state.videoTexture)
14946
+ return;
14947
+ state.enabled = true;
14948
+ state.videoMeshes = createPanoVideoMeshes();
14949
+ console.log('state.videoMeshes', state.videoMeshes);
14950
+ state.videoMeshes.forEach((mesh) => five.scene.add(mesh));
14951
+ const play = () => {
14952
+ console.log('play', state.videoTexture);
14953
+ if (!state.videoTexture)
14954
+ return;
14955
+ const timeupdate = () => {
14956
+ var _a;
14957
+ if (!state.videoTexture)
14958
+ return;
14959
+ (_a = state.videoTexture) === null || _a === void 0 ? void 0 : _a.image.removeEventListener('timeupdate', timeupdate);
14960
+ state.videoTextureEnabled = true;
14961
+ state.videoMeshes.forEach((mesh) => {
14962
+ if (mesh.material.map !== state.videoTexture)
14963
+ mesh.material.map = state.videoTexture;
14964
+ });
14965
+ five.needsRender = true;
14966
+ };
14967
+ state.videoTexture.image.addEventListener('timeupdate', timeupdate);
14968
+ if (state.videoTexture && state.videoMeshes.length) {
14969
+ state.videoTexture.image.play();
14970
+ }
14971
+ };
14972
+ if (five.model.loaded)
14973
+ play();
14974
+ else {
14975
+ return five.once('modelLoaded', () => play());
14976
+ }
14977
+ };
14978
+ const disable = () => {
14979
+ if (!state.enabled)
14980
+ return;
14981
+ state.enabled = false;
14982
+ state.videoMeshes.forEach((mesh) => {
14983
+ mesh.geometry.dispose();
14984
+ mesh.material.dispose();
14985
+ five.scene.remove(mesh);
14986
+ if (state.videoTexture)
14987
+ state.videoTexture.image.pause();
14988
+ });
14989
+ state.videoMeshes = [];
14990
+ five.needsRender = true;
14991
+ };
14992
+ const createPanoVideoMeshes = () => {
14993
+ return state.rectPoints.map((points, index) => {
14994
+ const geometry = new THREE__namespace.BufferGeometry();
14995
+ const segments = 128;
14996
+ const verticesArray = [];
14997
+ verticesArray.push(points[0].x, points[0].y, points[0].z);
14998
+ for (let i = 1; i < segments; i++) {
14999
+ 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);
15000
+ }
15001
+ verticesArray.push(points[1].x, points[1].y, points[1].z);
15002
+ verticesArray.push(points[2].x, points[2].y, points[2].z);
15003
+ for (let i = 1; i < segments; i++) {
15004
+ 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);
15005
+ }
15006
+ verticesArray.push(points[3].x, points[3].y, points[3].z);
15007
+ const uvArray = [];
15008
+ uvArray.push(0, 1);
15009
+ for (let i = 1; i < segments; i++) {
15010
+ uvArray.push(0, 1 - i / segments);
15011
+ }
15012
+ uvArray.push(0, 0);
15013
+ uvArray.push(1, 0);
15014
+ for (let i = 1; i < segments; i++) {
15015
+ uvArray.push(1, i / segments);
15016
+ }
15017
+ uvArray.push(1, 1);
15018
+ const indicesArray = [];
15019
+ for (let i = 0; i < segments; i++) {
15020
+ indicesArray.push(i, i + 1, segments * 2 - i, i, segments * 2 - i, segments * 2 + 1 - i);
15021
+ }
15022
+ geometry.setAttribute('position', new THREE__namespace.BufferAttribute(new Float32Array(verticesArray), 3));
15023
+ geometry.setAttribute('uv', new THREE__namespace.BufferAttribute(new Float32Array(uvArray), 2));
15024
+ geometry.setIndex(new THREE__namespace.BufferAttribute(new Uint32Array(indicesArray), 1));
15025
+ const material = new THREE__namespace.MeshBasicMaterial({
15026
+ map: state.videoTextureEnabled ? state.videoTexture : state.imageTexture,
15027
+ side: THREE__namespace.DoubleSide,
15028
+ });
15029
+ const mesh = new THREE__namespace.Mesh(geometry, material);
15030
+ mesh.renderOrder = 1;
15031
+ mesh.name = `ModelTVVideoPlugin-${index}-${performance.now()}`;
15032
+ return mesh;
15033
+ });
15034
+ };
15035
+ const getImageTexture = (source) => {
15036
+ const texture = new THREE__namespace.TextureLoader().load(source);
15037
+ texture.minFilter = THREE__namespace.LinearFilter;
15038
+ texture.magFilter = THREE__namespace.LinearFilter;
15039
+ texture.format = THREE__namespace.RGBFormat;
15040
+ return texture;
15041
+ };
15042
+ const getVideoTexture = (source, video) => {
15043
+ return new Promise((resolve, reject) => {
15044
+ const xhr = new XMLHttpRequest();
15045
+ xhr.onreadystatechange = () => {
15046
+ if (xhr.readyState == 4) {
15047
+ if (xhr.status == 200) {
15048
+ const url = window.URL || window.webkitURL;
15049
+ video = video || document.createElement('video');
15050
+ video.crossOrigin = 'anonymous';
15051
+ video.autoplay = true;
15052
+ video.muted = true;
15053
+ video.loop = true;
15054
+ video.playsInline = true;
15055
+ video.src = url.createObjectURL(xhr.response);
15056
+ const texture = new THREE__namespace.VideoTexture(video);
15057
+ texture.minFilter = THREE__namespace.LinearFilter;
15058
+ texture.magFilter = THREE__namespace.LinearFilter;
15059
+ texture.format = THREE__namespace.RGBFormat;
15060
+ resolve(Object.assign(texture, { videoSource: source }));
15061
+ }
15062
+ else {
15063
+ reject(new Error('Video download Error: ' + xhr.status));
15064
+ }
15065
+ }
15066
+ };
15067
+ xhr.onerror = (error) => reject(error);
15068
+ xhr.open('GET', source);
15069
+ xhr.responseType = 'blob';
15070
+ xhr.send();
15071
+ });
15072
+ };
15073
+ const load = (data, videoElement) => __awaiter(void 0, void 0, void 0, function* () {
15074
+ const { video_src, video_poster_src, points } = data;
15075
+ state.videoSource = video_src;
15076
+ // TODO 存疑,先处理多一次遍历 o(2n)
15077
+ state.rectPoints = parseModelTVVideoPoints(points)
15078
+ .map((items) => items.map(({ x, y, z }) => new THREE__namespace.Vector3(x, y, z)));
15079
+ state.imageTexture = getImageTexture(video_poster_src);
15080
+ if (videoElement) {
15081
+ state.videoElement = videoElement;
15082
+ }
15083
+ state.videoTexture = yield getVideoTexture(state.videoSource, state.videoElement);
15084
+ state.enabled = !!data.enable;
15085
+ if (state.enabled)
15086
+ enable();
15087
+ });
15088
+ const dispose = () => {
15089
+ disable();
15090
+ state.videoTexture = undefined;
15091
+ five.off('modeChange', () => setMuted(true));
15092
+ five.off('wantsTapGesture', (raycaster) => {
15093
+ if (!state.enabled)
15094
+ return;
15095
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15096
+ if (!!intersect && /^video/.test(intersect.object.name)) {
15097
+ if (state.videoTexture)
15098
+ setMuted(!state.videoTexture.image.muted);
15099
+ return false;
15100
+ }
15101
+ });
15102
+ five.off('panoArrived', () => {
15103
+ if (!state.enabled)
15104
+ return;
15105
+ if (getMuted())
15106
+ return;
15107
+ const cameraPosition = five.camera.position;
15108
+ const visible = state.rectPoints.find((points) => {
15109
+ 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());
15110
+ 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) => {
15111
+ vector = vector.clone().sub(cameraPosition).normalize();
15112
+ const raycaster = new THREE__namespace.Raycaster(cameraPosition, vector);
15113
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15114
+ return !!intersect && /^video/.test(intersect.object.name);
15115
+ }).length >= 2);
15116
+ });
15117
+ if (!visible)
15118
+ setMuted(true);
15119
+ });
15120
+ five.off('renderFrame', () => {
15121
+ // console.log('renderFrame', state.videoMeshes)
15122
+ state.videoMeshes.forEach((meshes) => {
15123
+ if (meshes)
15124
+ //@ts-ignore
15125
+ meshes.needsRender = true;
15126
+ });
15127
+ });
15128
+ };
15129
+ five.on('modeChange', () => setMuted(true));
15130
+ five.on('wantsTapGesture', (raycaster) => {
15131
+ if (!state.enabled)
15132
+ return;
15133
+ const targetMesh = five.scene.children.find(item => /^ModelTVVideoPlugin/.test(item.name));
15134
+ if (!targetMesh)
15135
+ return;
15136
+ const intersectObjects = raycaster.intersectObjects([targetMesh]);
15137
+ if (intersectObjects.length === 0)
15138
+ return;
15139
+ if (state.videoTexture)
15140
+ setMuted(!state.videoTexture.image.muted); // TODO toggle video play
15141
+ return false;
15142
+ });
15143
+ five.on('panoArrived', () => {
15144
+ if (!state.enabled)
15145
+ return;
15146
+ if (getMuted())
15147
+ return;
15148
+ const cameraPosition = five.camera.position;
15149
+ const visible = state.rectPoints.find((points) => {
15150
+ 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());
15151
+ 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) => {
15152
+ vector = vector.clone().sub(cameraPosition).normalize();
15153
+ const raycaster = new THREE__namespace.Raycaster(cameraPosition, vector);
15154
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15155
+ return !!intersect && /^video/.test(intersect.object.name);
15156
+ }).length >= 2);
15157
+ });
15158
+ if (!visible)
15159
+ setMuted(true);
15160
+ });
15161
+ five.on('renderFrame', () => {
15162
+ // console.log('renderFrame', state.videoMeshes)
15163
+ state.videoMeshes.forEach((meshes) => {
15164
+ if (meshes)
15165
+ //@ts-ignore
15166
+ meshes.needsRender = true;
15167
+ });
15168
+ });
15169
+ Object.assign(window, { $state: state });
15170
+ return { enable, disable, load, dispose };
15171
+ };
15172
+
14910
15173
  exports.CSS3DRenderPlugin = CSS3DRenderPlugin;
14911
15174
  exports.CameraMovementPlugin = CameraMovementPlugin;
14912
15175
  exports.ModelChassisCompassPlugin = ModelChassisCompassPlugin;
@@ -14914,6 +15177,7 @@
14914
15177
  exports.ModelFloorplanPlugin = ModelFloorplanPlugin;
14915
15178
  exports.ModelItemLabelPlugin = ModelItemLabelPlugin;
14916
15179
  exports.ModelRoomLabelPlugin = ModelRoomLabelPlugin;
15180
+ exports.ModelTVVideoPlugin = ModelTVVideoPlugin;
14917
15181
  exports.ModelViewPlugin = ModelViewPlugin;
14918
15182
  exports.PanoCompassPlugin = PanoCompassPlugin;
14919
15183
  exports.PanoCursorRaycasterPlugin = PanoCursorRaycasterPlugin;