@realsee/dnalogel 2.0.0-alpha.13 → 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 (58) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +78 -28
  3. package/dist/ModelItemLabelPlugin/index.js +16 -4
  4. package/dist/ModelItemLabelPlugin/typings.d.ts +1 -0
  5. package/dist/ModelTVVideoPlugin/index.d.ts +4 -0
  6. package/dist/ModelTVVideoPlugin/index.js +326 -0
  7. package/dist/ModelTVVideoPlugin/typings.d.ts +25 -0
  8. package/dist/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
  9. package/dist/PanoMeasurePlugin/index.js +2 -2
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.es.js +292 -7
  12. package/dist/index.js +292 -6
  13. package/dist/index.umd.js +292 -6
  14. package/docs/assets/main.js +1 -1
  15. package/docs/assets/search.js +1 -1
  16. package/docs/classes/ModelRoomLabelController.html +6 -6
  17. package/docs/enums/FLOOR_PLAN_ATTACHED_TO.html +1 -1
  18. package/docs/enums/ModelFloorplanErrorType.html +1 -1
  19. package/docs/index.html +78 -33
  20. package/docs/interfaces/LineJson.html +1 -1
  21. package/docs/interfaces/ModelChassisCompassPluginData.html +1 -1
  22. package/docs/interfaces/ModelChassisCompassPluginExportType.html +1 -1
  23. package/docs/interfaces/ModelChassisCompassPluginParameterType.html +1 -1
  24. package/docs/interfaces/ModelEntryDoorGuidePluginData.html +1 -1
  25. package/docs/interfaces/ModelEntryDoorGuidePluginExportType.html +1 -1
  26. package/docs/interfaces/ModelFloorplanParameterType.html +1 -1
  27. package/docs/interfaces/ModelFloorplanViewEvent.html +2 -2
  28. package/docs/interfaces/ModelItemLabelPluginData.html +1 -0
  29. package/docs/interfaces/ModelItemLabelPluginExportReturnsType.html +1 -0
  30. package/docs/interfaces/ModelItemLabelPluginParametersType.html +1 -0
  31. package/docs/interfaces/ModelRoomLabelPluginData.html +1 -1
  32. package/docs/interfaces/ModelTVVideoPluginData.html +1 -0
  33. package/docs/interfaces/ModelTVVideoPluginExportType.html +1 -0
  34. package/docs/interfaces/ModelTVVideoPluginParameterType.html +1 -0
  35. package/docs/interfaces/PanoCompassPluginData.html +1 -1
  36. package/docs/interfaces/PanoCompassPluginParameterType.html +1 -1
  37. package/docs/interfaces/PanoCursorRaycasterPluginExportType.html +6 -6
  38. package/docs/interfaces/PanoRulerPluginExportType.html +1 -1
  39. package/docs/interfaces/PanoRulerPluginOptions.html +1 -1
  40. package/docs/interfaces/PanoRulerPluginParameterType.html +1 -1
  41. package/docs/interfaces/PanoSpatialTagPluginData.html +1 -1
  42. package/docs/interfaces/PanoSpatialTagPluginExportType.html +1 -1
  43. package/docs/interfaces/PanoSpatialTagPluginParameterType.html +1 -1
  44. package/docs/interfaces/PointJson.html +1 -1
  45. package/docs/interfaces/RoomLabel.html +7 -7
  46. package/docs/interfaces/TopviewFloorplanPluginParameterType.html +1 -1
  47. package/docs/modules.html +12 -12
  48. package/libs/ModelItemLabelPlugin/index.js +16 -4
  49. package/libs/ModelItemLabelPlugin/typings.d.ts +1 -0
  50. package/libs/ModelTVVideoPlugin/index.d.ts +4 -0
  51. package/libs/ModelTVVideoPlugin/index.js +263 -0
  52. package/libs/ModelTVVideoPlugin/typings.d.ts +25 -0
  53. package/libs/ModelTVVideoPlugin/typings.js +7 -0
  54. package/libs/ModelTVVideoPlugin/utils/parseData.d.ts +2 -0
  55. package/libs/ModelTVVideoPlugin/utils/parseData.js +13 -0
  56. package/libs/index.d.ts +3 -0
  57. package/libs/index.js +1 -1
  58. package/package.json +1 -1
package/dist/index.es.js CHANGED
@@ -10633,10 +10633,10 @@ if (typeof undefined$1 === 'function' && undefined$1.amd) {
10633
10633
 
10634
10634
  var Hammer = hammer.exports;
10635
10635
 
10636
- var Hammer$1 = /*#__PURE__*/_mergeNamespaces({
10636
+ var Hammer$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/_mergeNamespaces({
10637
10637
  __proto__: null,
10638
10638
  'default': Hammer
10639
- }, [hammer.exports]);
10639
+ }, [hammer.exports]));
10640
10640
 
10641
10641
  // uuid
10642
10642
  function S4() {
@@ -14735,7 +14735,8 @@ const ModelItemLabelPlugin = (five, params) => {
14735
14735
  app: undefined,
14736
14736
  hooks: new Subscribe(),
14737
14737
  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
14738
+ displayStrategyType: (_b = params === null || params === void 0 ? void 0 : params.displayStrategyType) !== null && _b !== void 0 ? _b : DISPLAY_STRATEGY_TYPE.SMALL,
14739
+ pending: false
14739
14740
  };
14740
14741
  pluginState.container.setAttribute('class', 'model-item-label-plugin-container');
14741
14742
  pluginState.container.style.cssText = `
@@ -14744,8 +14745,8 @@ const ModelItemLabelPlugin = (five, params) => {
14744
14745
  top: 0;
14745
14746
  width: 100%;
14746
14747
  height: 100%;
14747
- pointerEvents: none;
14748
14748
  `;
14749
+ pluginState.container.style.pointerEvents = 'none'; // 写到 cssText 里不生效
14749
14750
  const appendTo = (wrapper) => {
14750
14751
  pluginState.wrapper = wrapper;
14751
14752
  wrapper.appendChild(pluginState.container);
@@ -14753,7 +14754,6 @@ const ModelItemLabelPlugin = (five, params) => {
14753
14754
  return true;
14754
14755
  };
14755
14756
  const load = (data) => {
14756
- console.log('🐶--当前标签总条数: ', data.model_item_labels.length);
14757
14757
  pluginState.itemLabels = parseModelItemLabelPluginData(data);
14758
14758
  render();
14759
14759
  };
@@ -14776,23 +14776,30 @@ const ModelItemLabelPlugin = (five, params) => {
14776
14776
  pluginState.container.remove();
14777
14777
  };
14778
14778
  const handleRerender = () => {
14779
- if (!pluginState.enabled || !pluginState.fiveModeEnabled)
14779
+ if (!pluginState.enabled || !pluginState.fiveModeEnabled || pluginState.pending)
14780
14780
  return;
14781
+ pluginState.pending = true;
14781
14782
  disable();
14782
14783
  };
14783
14784
  const rerender = (a, b, c) => {
14785
+ if (!pluginState.pending)
14786
+ return;
14784
14787
  if (!pluginState.fiveModeEnabled)
14785
14788
  return;
14786
14789
  if (!c)
14787
14790
  return;
14791
+ pluginState.pending = false;
14788
14792
  enable();
14789
14793
  render();
14790
14794
  };
14791
14795
  const handleInteriaPanRerender = (a, b) => {
14796
+ if (!pluginState.pending)
14797
+ return;
14792
14798
  if (!pluginState.fiveModeEnabled)
14793
14799
  return;
14794
14800
  if (!b)
14795
14801
  return;
14802
+ pluginState.pending = false;
14796
14803
  enable();
14797
14804
  render();
14798
14805
  };
@@ -14802,10 +14809,13 @@ const ModelItemLabelPlugin = (five, params) => {
14802
14809
  }
14803
14810
  };
14804
14811
  const handlePanGesture = (pose, final) => {
14812
+ if (!pluginState.pending)
14813
+ return;
14805
14814
  if (!pluginState.fiveModeEnabled)
14806
14815
  return;
14807
14816
  if (!final)
14808
14817
  return;
14818
+ pluginState.pending = false;
14809
14819
  enable();
14810
14820
  render();
14811
14821
  };
@@ -14870,6 +14880,8 @@ const ModelItemLabelPlugin = (five, params) => {
14870
14880
  five.off('pinchGesture', rerender);
14871
14881
  };
14872
14882
  const onFiveModeChange = (mode) => {
14883
+ if (!pluginState.enabled || pluginState.pending)
14884
+ return;
14873
14885
  if (mode !== Five.Mode.Floorplan) {
14874
14886
  pluginState.fiveModeEnabled = false;
14875
14887
  render();
@@ -14891,4 +14903,277 @@ const ModelItemLabelPlugin = (five, params) => {
14891
14903
  };
14892
14904
  };
14893
14905
 
14894
- export { CSS3DRenderPlugin, CameraMovementPlugin, FLOOR_PLAN_ATTACHED_TO, ModelChassisCompassPlugin, ModelEntryDoorGuidePlugin, ModelFloorplanPlugin, ModelItemLabelPlugin, ModelRoomLabelPlugin, ModelViewPlugin, PanoCompassPlugin, PanoCursorRaycasterPlugin, PanoFloorplanRadarPlugin, PanoMeasurePlugin, PanoRulerPlugin, PanoSpatialTagPlugin, TopviewFloorplanPlugin };
14906
+ var DIRECTION;
14907
+ (function (DIRECTION) {
14908
+ DIRECTION["TOP_LEFT"] = "topLeft";
14909
+ DIRECTION["TOP_RIGHT"] = "topRight";
14910
+ DIRECTION["BOTTOM_LEFT"] = "bottomLeft";
14911
+ DIRECTION["BOTTOM_RIGHT"] = "bottomRight";
14912
+ })(DIRECTION || (DIRECTION = {}));
14913
+
14914
+ function parseModelTVVideoPoints(points) {
14915
+ if (points.length === 0)
14916
+ return [];
14917
+ if (Array.isArray(points[0]))
14918
+ return points;
14919
+ let newPoints = [];
14920
+ points.map(point => {
14921
+ const newPoint = [point[DIRECTION.TOP_LEFT], point[DIRECTION.BOTTOM_LEFT], point[DIRECTION.BOTTOM_RIGHT], point[DIRECTION.TOP_RIGHT]];
14922
+ newPoints.push(newPoint);
14923
+ });
14924
+ return newPoints;
14925
+ }
14926
+
14927
+ const ModelTVVideoPlugin = (five, { videoElement }) => {
14928
+ const state = {
14929
+ videoMeshes: [],
14930
+ videoTextureEnabled: false,
14931
+ videoSource: '',
14932
+ rectPoints: [],
14933
+ enabled: false,
14934
+ videoElement: videoElement,
14935
+ };
14936
+ const setMuted = (muted) => {
14937
+ if (state.videoTexture) {
14938
+ state.videoTexture.image.muted = muted;
14939
+ state.videoTexture.image.play();
14940
+ }
14941
+ };
14942
+ const getMuted = () => {
14943
+ if (state.videoTexture)
14944
+ return state.videoTexture.image.muted;
14945
+ else
14946
+ return true;
14947
+ };
14948
+ const enable = () => {
14949
+ if (state.enabled)
14950
+ return;
14951
+ if (!state.videoTexture)
14952
+ return;
14953
+ state.enabled = true;
14954
+ state.videoMeshes = createPanoVideoMeshes();
14955
+ console.log('state.videoMeshes', state.videoMeshes);
14956
+ state.videoMeshes.forEach((mesh) => five.scene.add(mesh));
14957
+ const play = () => {
14958
+ console.log('play', state.videoTexture);
14959
+ if (!state.videoTexture)
14960
+ return;
14961
+ const timeupdate = () => {
14962
+ var _a;
14963
+ if (!state.videoTexture)
14964
+ return;
14965
+ (_a = state.videoTexture) === null || _a === void 0 ? void 0 : _a.image.removeEventListener('timeupdate', timeupdate);
14966
+ state.videoTextureEnabled = true;
14967
+ state.videoMeshes.forEach((mesh) => {
14968
+ if (mesh.material.map !== state.videoTexture)
14969
+ mesh.material.map = state.videoTexture;
14970
+ });
14971
+ five.needsRender = true;
14972
+ };
14973
+ state.videoTexture.image.addEventListener('timeupdate', timeupdate);
14974
+ if (state.videoTexture && state.videoMeshes.length) {
14975
+ state.videoTexture.image.play();
14976
+ }
14977
+ };
14978
+ if (five.model.loaded)
14979
+ play();
14980
+ else {
14981
+ return five.once('modelLoaded', () => play());
14982
+ }
14983
+ };
14984
+ const disable = () => {
14985
+ if (!state.enabled)
14986
+ return;
14987
+ state.enabled = false;
14988
+ state.videoMeshes.forEach((mesh) => {
14989
+ mesh.geometry.dispose();
14990
+ mesh.material.dispose();
14991
+ five.scene.remove(mesh);
14992
+ if (state.videoTexture)
14993
+ state.videoTexture.image.pause();
14994
+ });
14995
+ state.videoMeshes = [];
14996
+ five.needsRender = true;
14997
+ };
14998
+ const createPanoVideoMeshes = () => {
14999
+ return state.rectPoints.map((points, index) => {
15000
+ const geometry = new THREE.BufferGeometry();
15001
+ const segments = 128;
15002
+ const verticesArray = [];
15003
+ verticesArray.push(points[0].x, points[0].y, points[0].z);
15004
+ for (let i = 1; i < segments; i++) {
15005
+ 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);
15006
+ }
15007
+ verticesArray.push(points[1].x, points[1].y, points[1].z);
15008
+ verticesArray.push(points[2].x, points[2].y, points[2].z);
15009
+ for (let i = 1; i < segments; i++) {
15010
+ 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);
15011
+ }
15012
+ verticesArray.push(points[3].x, points[3].y, points[3].z);
15013
+ const uvArray = [];
15014
+ uvArray.push(0, 1);
15015
+ for (let i = 1; i < segments; i++) {
15016
+ uvArray.push(0, 1 - i / segments);
15017
+ }
15018
+ uvArray.push(0, 0);
15019
+ uvArray.push(1, 0);
15020
+ for (let i = 1; i < segments; i++) {
15021
+ uvArray.push(1, i / segments);
15022
+ }
15023
+ uvArray.push(1, 1);
15024
+ const indicesArray = [];
15025
+ for (let i = 0; i < segments; i++) {
15026
+ indicesArray.push(i, i + 1, segments * 2 - i, i, segments * 2 - i, segments * 2 + 1 - i);
15027
+ }
15028
+ geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(verticesArray), 3));
15029
+ geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvArray), 2));
15030
+ geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(indicesArray), 1));
15031
+ const material = new THREE.MeshBasicMaterial({
15032
+ map: state.videoTextureEnabled ? state.videoTexture : state.imageTexture,
15033
+ side: THREE.DoubleSide,
15034
+ });
15035
+ const mesh = new THREE.Mesh(geometry, material);
15036
+ mesh.renderOrder = 1;
15037
+ mesh.name = `ModelTVVideoPlugin-${index}-${performance.now()}`;
15038
+ return mesh;
15039
+ });
15040
+ };
15041
+ const getImageTexture = (source) => {
15042
+ const texture = new THREE.TextureLoader().load(source);
15043
+ texture.minFilter = THREE.LinearFilter;
15044
+ texture.magFilter = THREE.LinearFilter;
15045
+ texture.format = THREE.RGBFormat;
15046
+ return texture;
15047
+ };
15048
+ const getVideoTexture = (source, video) => {
15049
+ return new Promise((resolve, reject) => {
15050
+ const xhr = new XMLHttpRequest();
15051
+ xhr.onreadystatechange = () => {
15052
+ if (xhr.readyState == 4) {
15053
+ if (xhr.status == 200) {
15054
+ const url = window.URL || window.webkitURL;
15055
+ video = video || document.createElement('video');
15056
+ video.crossOrigin = 'anonymous';
15057
+ video.autoplay = true;
15058
+ video.muted = true;
15059
+ video.loop = true;
15060
+ video.playsInline = true;
15061
+ video.src = url.createObjectURL(xhr.response);
15062
+ const texture = new THREE.VideoTexture(video);
15063
+ texture.minFilter = THREE.LinearFilter;
15064
+ texture.magFilter = THREE.LinearFilter;
15065
+ texture.format = THREE.RGBFormat;
15066
+ resolve(Object.assign(texture, { videoSource: source }));
15067
+ }
15068
+ else {
15069
+ reject(new Error('Video download Error: ' + xhr.status));
15070
+ }
15071
+ }
15072
+ };
15073
+ xhr.onerror = (error) => reject(error);
15074
+ xhr.open('GET', source);
15075
+ xhr.responseType = 'blob';
15076
+ xhr.send();
15077
+ });
15078
+ };
15079
+ const load = (data, videoElement) => __awaiter(void 0, void 0, void 0, function* () {
15080
+ const { video_src, video_poster_src, points } = data;
15081
+ state.videoSource = video_src;
15082
+ // TODO 存疑,先处理多一次遍历 o(2n)
15083
+ state.rectPoints = parseModelTVVideoPoints(points)
15084
+ .map((items) => items.map(({ x, y, z }) => new THREE.Vector3(x, y, z)));
15085
+ state.imageTexture = getImageTexture(video_poster_src);
15086
+ if (videoElement) {
15087
+ state.videoElement = videoElement;
15088
+ }
15089
+ state.videoTexture = yield getVideoTexture(state.videoSource, state.videoElement);
15090
+ state.enabled = !!data.enable;
15091
+ if (state.enabled)
15092
+ enable();
15093
+ });
15094
+ const dispose = () => {
15095
+ disable();
15096
+ state.videoTexture = undefined;
15097
+ five.off('modeChange', () => setMuted(true));
15098
+ five.off('wantsTapGesture', (raycaster) => {
15099
+ if (!state.enabled)
15100
+ return;
15101
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15102
+ if (!!intersect && /^video/.test(intersect.object.name)) {
15103
+ if (state.videoTexture)
15104
+ setMuted(!state.videoTexture.image.muted);
15105
+ return false;
15106
+ }
15107
+ });
15108
+ five.off('panoArrived', () => {
15109
+ if (!state.enabled)
15110
+ return;
15111
+ if (getMuted())
15112
+ return;
15113
+ const cameraPosition = five.camera.position;
15114
+ const visible = state.rectPoints.find((points) => {
15115
+ 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());
15116
+ return (points.map((point) => new THREE.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
15117
+ vector = vector.clone().sub(cameraPosition).normalize();
15118
+ const raycaster = new THREE.Raycaster(cameraPosition, vector);
15119
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15120
+ return !!intersect && /^video/.test(intersect.object.name);
15121
+ }).length >= 2);
15122
+ });
15123
+ if (!visible)
15124
+ setMuted(true);
15125
+ });
15126
+ five.off('renderFrame', () => {
15127
+ // console.log('renderFrame', state.videoMeshes)
15128
+ state.videoMeshes.forEach((meshes) => {
15129
+ if (meshes)
15130
+ //@ts-ignore
15131
+ meshes.needsRender = true;
15132
+ });
15133
+ });
15134
+ };
15135
+ five.on('modeChange', () => setMuted(true));
15136
+ five.on('wantsTapGesture', (raycaster) => {
15137
+ if (!state.enabled)
15138
+ return;
15139
+ const targetMesh = five.scene.children.find(item => /^ModelTVVideoPlugin/.test(item.name));
15140
+ if (!targetMesh)
15141
+ return;
15142
+ const intersectObjects = raycaster.intersectObjects([targetMesh]);
15143
+ if (intersectObjects.length === 0)
15144
+ return;
15145
+ if (state.videoTexture)
15146
+ setMuted(!state.videoTexture.image.muted); // TODO toggle video play
15147
+ return false;
15148
+ });
15149
+ five.on('panoArrived', () => {
15150
+ if (!state.enabled)
15151
+ return;
15152
+ if (getMuted())
15153
+ return;
15154
+ const cameraPosition = five.camera.position;
15155
+ const visible = state.rectPoints.find((points) => {
15156
+ 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());
15157
+ return (points.map((point) => new THREE.Vector3((point.x + centerVector.x) / 2, (point.y + centerVector.y) / 2, (point.z + centerVector.z) / 2)).filter((vector) => {
15158
+ vector = vector.clone().sub(cameraPosition).normalize();
15159
+ const raycaster = new THREE.Raycaster(cameraPosition, vector);
15160
+ const [intersect] = raycaster.intersectObjects(five.scene.children, true);
15161
+ return !!intersect && /^video/.test(intersect.object.name);
15162
+ }).length >= 2);
15163
+ });
15164
+ if (!visible)
15165
+ setMuted(true);
15166
+ });
15167
+ five.on('renderFrame', () => {
15168
+ // console.log('renderFrame', state.videoMeshes)
15169
+ state.videoMeshes.forEach((meshes) => {
15170
+ if (meshes)
15171
+ //@ts-ignore
15172
+ meshes.needsRender = true;
15173
+ });
15174
+ });
15175
+ Object.assign(window, { $state: state });
15176
+ return { enable, disable, load, dispose };
15177
+ };
15178
+
15179
+ export { CSS3DRenderPlugin, CameraMovementPlugin, FLOOR_PLAN_ATTACHED_TO, ModelChassisCompassPlugin, ModelEntryDoorGuidePlugin, ModelFloorplanPlugin, ModelItemLabelPlugin, ModelRoomLabelPlugin, ModelTVVideoPlugin, ModelViewPlugin, PanoCompassPlugin, PanoCursorRaycasterPlugin, PanoFloorplanRadarPlugin, PanoMeasurePlugin, PanoRulerPlugin, PanoSpatialTagPlugin, TopviewFloorplanPlugin };