@realsee/dnalogel 4.0.0-webgpu.3 → 4.0.0-webgpu.4
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 +6 -0
- package/dist/floorplan.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +270 -35
- package/dist/index.js.map +1 -0
- package/dist/internal/{BasePlugin-CT5K8m36.js → BasePlugin-DC5m72La.js} +3 -3
- package/dist/internal/{BasePlugin-CT5K8m36.js.map → BasePlugin-DC5m72La.js.map} +1 -1
- package/dist/internal/BasePluginWithData-D_0W46_q.js +7 -0
- package/dist/internal/{BasePluginWithData-9z4tpAT4.js.map → BasePluginWithData-D_0W46_q.js.map} +1 -1
- package/dist/internal/{BetterTween-BX0aTvP1.js → BetterTween-DmptqE8m.js} +2 -2
- package/dist/internal/{BetterTween-BX0aTvP1.js.map → BetterTween-DmptqE8m.js.map} +1 -1
- package/dist/internal/{CSS3DRenderPlugin-ccSpcvwd.js → CSS3DRenderPlugin-CEatgl0m.js} +3 -3
- package/dist/internal/CSS3DRenderPlugin-CEatgl0m.js.map +1 -0
- package/dist/internal/{Controller-Csut_kcH.js → Controller-D6o4OGWJ.js} +8 -8
- package/dist/internal/{Controller-Csut_kcH.js.map → Controller-D6o4OGWJ.js.map} +1 -1
- package/dist/internal/{FiveDomEvents-3H9NvDOz.js → FiveDomEvents-BUBLFzti.js} +2 -2
- package/dist/internal/{FiveDomEvents-3H9NvDOz.js.map → FiveDomEvents-BUBLFzti.js.map} +1 -1
- package/dist/internal/FivePuppet-C6QmVY70.js +67 -0
- package/dist/internal/FivePuppet-C6QmVY70.js.map +1 -0
- package/dist/internal/{PointHelper-D565h9b_.js → PointHelper-DIhgdjY2.js} +48 -48
- package/dist/internal/{PointHelper-D565h9b_.js.map → PointHelper-DIhgdjY2.js.map} +1 -1
- package/dist/internal/{Polygon-CBGvYUfJ.js → Polygon-D3xIL1Pl.js} +30 -30
- package/dist/internal/{Polygon-CBGvYUfJ.js.map → Polygon-D3xIL1Pl.js.map} +1 -1
- package/dist/internal/{Prism-Dm5ESkgg.js → Prism-CJlyAEAU.js} +13 -13
- package/dist/internal/{Prism-Dm5ESkgg.js.map → Prism-CJlyAEAU.js.map} +1 -1
- package/dist/internal/{Rectangle-D-zkDycu.js → Rectangle-BpL9lNKU.js} +118 -129
- package/dist/internal/Rectangle-BpL9lNKU.js.map +1 -0
- package/dist/internal/{Work-DF8j5GnL.js → Work-BE4AgdwH.js} +9 -9
- package/dist/internal/{Work-DF8j5GnL.js.map → Work-BE4AgdwH.js.map} +1 -1
- package/dist/internal/{animationFrame-XGKHIeQK.js → animationFrame-CacKXN8l.js} +14 -3
- package/dist/internal/animationFrame-CacKXN8l.js.map +1 -0
- package/dist/internal/{area-maker-Bd9l2pIp.js → area-maker-Bnhx4SkH.js} +4 -4
- package/dist/internal/{area-maker-Bd9l2pIp.js.map → area-maker-Bnhx4SkH.js.map} +1 -1
- package/dist/internal/{boundingBox-DvCor5Hd.js → boundingBox-CIqXgNXW.js} +2 -2
- package/dist/internal/{boundingBox-DvCor5Hd.js.map → boundingBox-CIqXgNXW.js.map} +1 -1
- package/dist/internal/{camera-movement-CwI7UqUk.js → camera-movement-C1pwfMk_.js} +2 -2
- package/dist/internal/camera-movement-C1pwfMk_.js.map +1 -0
- package/dist/internal/{changeMode-BVGYCoqu.js → changeMode-D_I2AOjH.js} +2 -2
- package/dist/internal/{changeMode-BVGYCoqu.js.map → changeMode-D_I2AOjH.js.map} +1 -1
- package/dist/internal/{controller-BWkZT0l1.js → controller-DIDtFrBE.js} +1991 -2050
- package/dist/internal/controller-DIDtFrBE.js.map +1 -0
- package/dist/internal/{cruise-C3F0eNQ-.js → cruise-B50Tcq66.js} +2 -2
- package/dist/internal/{cruise-C3F0eNQ-.js.map → cruise-B50Tcq66.js.map} +1 -1
- package/dist/internal/{current-pano-image-DKUWluR-.js → current-pano-image-BCFr6njt.js} +4 -4
- package/dist/internal/{current-pano-image-DKUWluR-.js.map → current-pano-image-BCFr6njt.js.map} +1 -1
- package/dist/internal/{defaultUrls-CjKkS9k9.js → defaultUrls-CfMtGzqM.js} +14 -3
- package/dist/internal/defaultUrls-CfMtGzqM.js.map +1 -0
- package/dist/internal/{fire-scene-CczaBz2_.js → fire-scene-BzZGvyh_.js} +9 -4
- package/dist/internal/fire-scene-BzZGvyh_.js.map +1 -0
- package/dist/internal/{fiveModelLoad-mg-TnpnM.js → fiveModelLoad-BUIBYxzp.js} +2 -2
- package/dist/internal/{fiveModelLoad-mg-TnpnM.js.map → fiveModelLoad-BUIBYxzp.js.map} +1 -1
- package/dist/internal/{floorplan-KWlIsTvO.js → floorplan-C8BGw87S.js} +5 -5
- package/dist/internal/{floorplan-KWlIsTvO.js.map → floorplan-C8BGw87S.js.map} +1 -1
- package/dist/internal/{generatePolygonGeometry-B_5JFq8y.js → generatePolygonGeometry-BOnzdCaG.js} +181 -178
- package/dist/internal/generatePolygonGeometry-BOnzdCaG.js.map +1 -0
- package/dist/internal/{lookObject-wesf8xt6.js → lookObject-DuRab5wf.js} +2 -2
- package/dist/internal/{lookObject-wesf8xt6.js.map → lookObject-DuRab5wf.js.map} +1 -1
- package/dist/internal/{measure-BX6boAC7.js → measure-B4jFwdQ6.js} +5 -5
- package/dist/internal/{measure-BX6boAC7.js.map → measure-B4jFwdQ6.js.map} +1 -1
- package/dist/internal/{model-chassis-compass-InVNmOAQ.js → model-chassis-compass-C6NTVMLo.js} +2 -2
- package/dist/internal/{model-chassis-compass-InVNmOAQ.js.map → model-chassis-compass-C6NTVMLo.js.map} +1 -1
- package/dist/internal/{model-entry-door-guide-wZbyY77a.js → model-entry-door-guide-DnGTLY2s.js} +2 -2
- package/dist/internal/{model-entry-door-guide-wZbyY77a.js.map → model-entry-door-guide-DnGTLY2s.js.map} +1 -1
- package/dist/internal/{model-maker-uO8xlTuO.js → model-maker-B1mnDdKY.js} +15 -15
- package/dist/internal/{model-maker-uO8xlTuO.js.map → model-maker-B1mnDdKY.js.map} +1 -1
- package/dist/internal/{model-tv-video-DzXb2JRf.js → model-tv-video-BP-7HoDC.js} +2 -2
- package/dist/internal/{model-tv-video-DzXb2JRf.js.map → model-tv-video-BP-7HoDC.js.map} +1 -1
- package/dist/internal/{model-view-CBeeMM98.js → model-view-BWUU0-uq.js} +2 -2
- package/dist/internal/{model-view-CBeeMM98.js.map → model-view-BWUU0-uq.js.map} +1 -1
- package/dist/internal/object3d-helper-CbRRhnLV.js +7 -0
- package/dist/internal/{object3d-helper-DDYsVPN6.js.map → object3d-helper-CbRRhnLV.js.map} +1 -1
- package/dist/internal/{pano-compass-jSr629BP.js → pano-compass-BRTM0dCc.js} +7 -7
- package/dist/internal/{pano-compass-jSr629BP.js.map → pano-compass-BRTM0dCc.js.map} +1 -1
- package/dist/internal/{pano-door-label-DKoYIKLa.js → pano-door-label-BLjYGZrr.js} +3 -3
- package/dist/internal/{pano-door-label-DKoYIKLa.js.map → pano-door-label-BLjYGZrr.js.map} +1 -1
- package/dist/internal/{pano-measure-DW9mdx1O.js → pano-measure-BIgCWkVJ.js} +14 -14
- package/dist/internal/{pano-measure-DW9mdx1O.js.map → pano-measure-BIgCWkVJ.js.map} +1 -1
- package/dist/internal/{pano-ruler-pro-D7q0Ob21.js → pano-ruler-pro-D9yTbHJz.js} +2 -2
- package/dist/internal/{pano-ruler-pro-D7q0Ob21.js.map → pano-ruler-pro-D9yTbHJz.js.map} +1 -1
- package/dist/internal/{pano-spatial-tag-D0qn-__S.js → pano-spatial-tag-B7Gxn3BS.js} +3 -3
- package/dist/internal/{pano-spatial-tag-D0qn-__S.js.map → pano-spatial-tag-B7Gxn3BS.js.map} +1 -1
- package/dist/internal/{pano-tag-BW5MXXws.js → pano-tag-Bchz-jED.js} +2 -2
- package/dist/internal/{pano-tag-BW5MXXws.js.map → pano-tag-Bchz-jED.js.map} +1 -1
- package/dist/internal/{pano-video-Bmud_CAn.js → pano-video-BufYQMqo.js} +3 -3
- package/dist/internal/{pano-video-Bmud_CAn.js.map → pano-video-BufYQMqo.js.map} +1 -1
- package/dist/internal/{pipeline-DDqgb1gw.js → pipeline-t_3IMXKB.js} +4 -4
- package/dist/internal/{pipeline-DDqgb1gw.js.map → pipeline-t_3IMXKB.js.map} +1 -1
- package/dist/internal/{sculpt-BNkLJR6p.js → sculpt-BCK4PMwL.js} +64 -63
- package/dist/internal/{sculpt-BNkLJR6p.js.map → sculpt-BCK4PMwL.js.map} +1 -1
- package/dist/internal/tagPosition-DA9YguT8.js +176 -0
- package/dist/internal/tagPosition-DA9YguT8.js.map +1 -0
- package/dist/internal/withResolvers-DVr4bnnk.js +15 -0
- package/dist/internal/withResolvers-DVr4bnnk.js.map +1 -0
- package/dist/plugins/area-maker.js +1 -1
- package/dist/plugins/camera-movement.js +1 -1
- package/dist/plugins/cruise.js +2 -2
- package/dist/plugins/css3d-render.js +1 -1
- package/dist/plugins/current-pano-image.js +1 -1
- package/dist/plugins/digital-performance.d.ts +1 -1
- package/dist/plugins/digital-performance.js +1 -1
- package/dist/plugins/fire-scene.d.ts +1 -1
- package/dist/plugins/fire-scene.js +1 -1
- package/dist/plugins/guide-line.js +1 -1
- package/dist/plugins/measure.js +1 -1
- package/dist/plugins/model-chassis-compass.js +1 -1
- package/dist/plugins/model-entry-door-guide.js +1 -1
- package/dist/plugins/model-maker.d.ts +1 -1
- package/dist/plugins/model-maker.js +1 -1
- package/dist/plugins/model-tv-video.js +1 -1
- package/dist/plugins/model-view.js +1 -1
- package/dist/plugins/object3d-helper.d.ts +1 -1
- package/dist/plugins/object3d-helper.js +3 -1
- package/dist/plugins/pano-compass.js +1 -1
- package/dist/plugins/pano-door-label.js +1 -1
- package/dist/plugins/pano-measure.js +1 -1
- package/dist/plugins/pano-ruler-pro.js +1 -1
- package/dist/plugins/pano-spatial-tag.js +1 -1
- package/dist/plugins/pano-tag.d.ts +1 -1
- package/dist/plugins/pano-tag.js +4 -1
- package/dist/plugins/pano-video.js +1 -1
- package/dist/plugins/pipeline.js +1 -1
- package/dist/plugins/sculpt.d.ts +1 -1
- package/dist/plugins/sculpt.js +7 -1
- package/dist/types/public/index.d.ts +2 -0
- package/dist/types/public/plugins/digital-performance.d.ts +1 -0
- package/dist/types/public/plugins/fire-scene.d.ts +1 -0
- package/dist/types/public/plugins/model-maker.d.ts +1 -0
- package/dist/types/public/plugins/object3d-helper.d.ts +1 -0
- package/dist/types/public/plugins/pano-tag.d.ts +2 -0
- package/dist/types/public/plugins/sculpt.d.ts +8 -0
- package/dist/types/public/utils.d.ts +5 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +16 -50
- package/package.json +1 -1
- package/dist/internal/BasePluginWithData-9z4tpAT4.js +0 -7
- package/dist/internal/CSS3DRenderPlugin-ccSpcvwd.js.map +0 -1
- package/dist/internal/Rectangle-D-zkDycu.js.map +0 -1
- package/dist/internal/animationFrame-XGKHIeQK.js.map +0 -1
- package/dist/internal/blink-DD_0mH-m.js +0 -113
- package/dist/internal/blink-DD_0mH-m.js.map +0 -1
- package/dist/internal/camera-movement-CwI7UqUk.js.map +0 -1
- package/dist/internal/controller-BWkZT0l1.js.map +0 -1
- package/dist/internal/defaultUrls-CjKkS9k9.js.map +0 -1
- package/dist/internal/fire-scene-CczaBz2_.js.map +0 -1
- package/dist/internal/generatePolygonGeometry-B_5JFq8y.js.map +0 -1
- package/dist/internal/object3d-helper-DDYsVPN6.js +0 -7
- package/dist/utils.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Work-DF8j5GnL.js","names":["getNormals","$.from_html","$.mutable_source","$.prop","$.deep_read_state","$.get","$.sibling","$.child","$.only_child","$.set_style","objectAssignDeep","CustomTag","PLUGIN","BasePlugin.Controller","objectAssignDeep","objectAssignDeep","BasePluginWithData.Controller","CruisePluginController","objectAssignDeep","coordinates1","coordinates2","__toESM","transformPosition","Subscribe","waitFiveModelLoaded","anyPositionToVector3","isPanoramaLike","isModelLike","blink","vectorToCoordinates","notNil","uuid","GUIDELINE_DEFAULT_ARROW_TEXTURE","GUIDELINE_WHITE_ARROW_TEXTURE","replaceStaticPrefix","to","changeMode","BetterTween","equal","PanoTagPluginController","Controller$1","Controller$2","template_effect","only_child","child","append","from_html","set","deep_read_state","legacy_pre_effect","legacy_pre_effect_reset","mutable_source","sibling","push","set_text","prop","init","next","set_style","pop","reset","mountComponent","get","px2rem","getCurrentFontSize","getGlobalResponsiveFontSize","FONT_SIZE_MAP","require_objectAssignDeep","sleep","THREE","GuideLineMaterial","sourceUv","image","imageColor","imageAlpha","insideBorder","isBorder","backgroundAlpha","borderAlpha","imageDisplayAlpha","mixedColor","mixedAlpha","finalColor","finalAlpha","gradient","logError","name","msg","require_add","add","a","b","out","require_set","x","y","require_normalize","normalize","len","require_subtract","subtract","require_dot","dot","require_polyline_miter_util","tmp","tangent","lineA","lineB","miter","halfThick","dir","require_polyline_normals","util","curNormal","closed","points","total","i","last","cur","addNext","last2","cur2","next2","miterLen2","normal","length","lineIsIntersecting","a1","line1","a2","b1","line2","b2","ua_t","ub_t","u_b","ua","ub","findIntersectingOfLines","j","import_polyline_normals","TRIANGLE_NUMBER_OF_RECTANGLE","VERTEX_NUMBER_OF_TRIANGLE","AXIS_NUMBER_OF_VERTEX","UV_NUMBER_OF_VERTEX","createLineGeometry","unitWidth","options","unitLength","halfUnitWidth","path","curvePath","curve","createCurve","pathData","divisions","curvePoints","curvePointsLength","normals","p","indexNumber","verticesNumber","positionNumber","uvNumber","index","positions","uv","totalLength","maxV","nx","nz","curvePointX","curvePointY","curvePointZ","vertices2i","Vector3","vertices2i1","end","center","skipPosition","intersectingIndex","lastHandleIndex","animationWillError","ni","p1","p2","p3","p4","intersecting","d1","d2","jStart","jEnd","kStart","kEnd","k","result","intersectingX","intersectingY","line1Index","line1RelativeIndex","line2Index","line2RelativeIndex","l","jStartY","line1IndexY","line2IndexY","kEndY","centerY","t","animationWillErrorAttribute","errorIndex","geometry","isCatmullRomCurve3Data","item","point","data","root","root_1","root_2","root_3","Tag","$$props","fontConfig","nameSize","padding","paddingStyle","distancePadding","distancePaddingStyle","lineHeight","lineHeightStyle","text","icon_url","distance","opacity","fontSize","div","styles","div_1","div_2","styles_1","node","consequent","div_3","styles_2","text_1","$$anchor","$$render","node_1","consequent_2","div_4","styles_3","node_2","consequent_1","span","styles_4","text_2","div_5","span_1","styles_5","text_3","span_2","styles_6","text_4","if_block","filterAdjacentDistinct","array","createPath","panoIndexList","fixedPositionInfo","position","panoIndex","work","lastPanoIndex","transform","import_objectAssignDeep","GuideLineModeItem","five","material","visible","width","scale","panoGroup","_panoGroup","currState","workCode","fallbackUrl","nextMaterialStyle","translateVector","applyTagTranslate","nextMeshStyle","tagContainer","tagPositionVector","translate","tagPosition","offset","color","backgroundClip","url","loadTexture","texture","floorIndexes","tag","curveLength","divisionLength","curveLengths","lengths","observerGroupIndex","currentCurvePoint","standingPosition","_tag","type","isModelTag","distanceInMeter","i18n","v","formattedDistance","props","app","container","mode","floor","progress","PLUGIN$1","CruiseController","config","state","prevState","play","enabled","wantsChangeModeHandler","interrupt","handleGesture","duration","longitude","id","func","getFiveStateOnCurve","curveOffset","MoveController","defaultState","defaultConfig","vectors","baseMoveSpeed","GuideLinePlugin","speed","playedProgress","lastProgress","disposer","reject","onRenderFrame","resolve","GuideLineItem","style","geometryStyle","materialStyle","meshStyle","skipPanoGroup","walkData","error","walk","move","plugin","fiveCurrentState","WalkController","onFivePanoArrived","onFiveModeChange","onReject","wantedPanoIndex","onResolve","removeListeners","PLUGIN_NAME","PLUGIN","Controller","generation","prevData","serverData","isV1Data","arrowTextureUrl","baseData","v1Data","v2Data","combineData","prevItem","newItem","processedItem","defaultTextureUrl","textureUrl","fn","enabledTagContainers","isNumberArray","value","isNear","position1","position2","getTagEnable","enabledTagContainer","startTagContainer","endTagContainer","startTagEnable","endTagEnable","coordinatesToVector","coordinates","coordinatesAngle","vector1","coordinates1","vector2","coordinates2","coordinatesRotation","deltaLon","deltaLat","angle","signed","safeCall","waitFiveLoaded","guideLinePanoIndex","tempFloorIndex","hasPanoIndexKeyframes","keyframe","floorIndex","route","_serverData","nextKeyframe","stay","keyframes","moveToFirstPanoEffect","moveToFirstPanoDuration","lookatNextPanoIndex","nextPanoIndex","vectorFrom","vectorTo","vector","privateState","hasAudio","session","currentPlayId","pauseData","target","selectedFrame","hooks","firstKeyframeWasPlayed","playFromIndex","pausedKeyframe","audio","playId","wasPlaying","fromManager","currentPlayKeyframe","params","promise","settled","removeInterrupt","cancel","settle","failed","current","speedConfig","speedValue","currentState","PI_2","targetLongitude","_duration","pending","willChangeMode","postion1","postion2","resolveMove","rejectMove","request","onPanoArrived","onPanoCancelled","arrivedState","event","onReturned","_audio","operations","started","cleanup","onPlaying","onError","onEnded","fail"],"sources":["../../src/GuideLinePlugin/utils/GuideLineMaterial.ts","../../src/shared-utils/log.ts","../../../node_modules/gl-vec2/add.js","../../../node_modules/gl-vec2/set.js","../../../node_modules/gl-vec2/normalize.js","../../../node_modules/gl-vec2/subtract.js","../../../node_modules/gl-vec2/dot.js","../../../node_modules/polyline-miter-util/index.js","../../../node_modules/polyline-normals/index.js","../../src/shared-utils/math/intersecting.ts","../../src/GuideLinePlugin/utils/createLineGeometry.ts","../../src/GuideLinePlugin/Components/Tag.svelte","../../src/GuideLinePlugin/utils/index.ts","../../src/GuideLinePlugin/utils/createPath.ts","../../src/GuideLinePlugin/GuideLineModeItem.ts","../../src/CruisePlugin/BaseController.ts","../../src/CruisePlugin/utils/getFiveStateOnCurve.ts","../../src/CruisePlugin/Move.ts","../../src/GuideLinePlugin/GuideLineItem.ts","../../src/GuideLinePlugin/Controller.ts","../../src/GuideLinePlugin/index.ts","../../src/CruisePlugin/utils/coordinatesToVector.ts","../../src/CruisePlugin/utils/coordinatesAngle.ts","../../src/CruisePlugin/utils/safeCall.ts","../../src/shared-utils/five/fiveLoaded.ts","../../src/CruisePlugin/Work.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\n\nexport class GuideLineMaterial extends THREE.MeshBasicNodeMaterial {\n public readonly mapNode: ReturnType<typeof THREE.TSL.texture>\n public readonly useMapColor = THREE.TSL.uniform(0)\n public readonly mapColor = THREE.TSL.uniform(new THREE.Color())\n public readonly mapOpacity = THREE.TSL.uniform(1)\n public readonly backgroundColor = THREE.TSL.uniform(new THREE.Color())\n public readonly backgroundOpacity = THREE.TSL.uniform(0)\n public readonly borderColor = THREE.TSL.uniform(new THREE.Color())\n public readonly borderOpacity = THREE.TSL.uniform(0)\n public readonly backgroundClip = THREE.TSL.uniform(0)\n public readonly borderWidth = THREE.TSL.uniform(0.05)\n public readonly flickerValue = THREE.TSL.uniform(1)\n public readonly maxV = THREE.TSL.uniform(0)\n public readonly vOffset = THREE.TSL.uniform(0)\n\n public constructor() {\n super({ transparent: true })\n\n const sourceUv = THREE.TSL.uv()\n const image = THREE.TSL.texture(new THREE.Texture(), THREE.TSL.vec2(sourceUv.x, sourceUv.y.sub(this.vOffset)))\n this.mapNode = image\n const imageColor = THREE.TSL.select(\n this.useMapColor.greaterThan(0.5),\n THREE.TSL.mix(image.rgb, this.mapColor, image.a),\n image.rgb,\n )\n const imageAlpha = image.a.mul(this.mapOpacity)\n const insideBorder = sourceUv.x.greaterThan(this.borderWidth).and(\n sourceUv.x.lessThan(THREE.TSL.float(1).sub(this.borderWidth)),\n )\n const isBorder = sourceUv.x.lessThanEqual(this.borderWidth).or(\n sourceUv.x.greaterThanEqual(THREE.TSL.float(1).sub(this.borderWidth)),\n )\n const backgroundAlpha = THREE.TSL.select(\n this.backgroundClip.lessThan(0.5),\n this.backgroundOpacity,\n THREE.TSL.select(insideBorder, this.backgroundOpacity, 0),\n )\n const borderAlpha = THREE.TSL.select(isBorder, this.borderOpacity, 0)\n const imageDisplayAlpha = imageAlpha.mul(0.4).add(0.6)\n const mixedColor = THREE.TSL.mix(this.backgroundColor, imageColor, imageAlpha)\n const mixedAlpha = THREE.TSL.mix(backgroundAlpha, imageDisplayAlpha, imageAlpha)\n const finalColor = THREE.TSL.mix(mixedColor, this.borderColor, borderAlpha)\n const finalAlpha = THREE.TSL.mix(mixedAlpha, borderAlpha, borderAlpha)\n const gradient = THREE.TSL.select(\n sourceUv.y.lessThanEqual(1),\n sourceUv.y,\n THREE.TSL.select(sourceUv.y.lessThanEqual(this.maxV.sub(1)), 1, this.maxV.sub(sourceUv.y)),\n )\n\n this.colorNode = THREE.TSL.vec4(finalColor, finalAlpha.mul(gradient).mul(this.flickerValue))\n }\n}\n","export function logWarning(name: string, msg: string) {\n console.warn(`⛔ ==> [${name}]: ${msg}`)\n}\n\nexport function logError(name: string, msg: string) {\n console.warn(`🚫 ==> [${name}]: ${msg}`)\n}\n","module.exports = add\n\n/**\n * Adds two vec2's\n *\n * @param {vec2} out the receiving vector\n * @param {vec2} a the first operand\n * @param {vec2} b the second operand\n * @returns {vec2} out\n */\nfunction add(out, a, b) {\n out[0] = a[0] + b[0]\n out[1] = a[1] + b[1]\n return out\n}","module.exports = set\n\n/**\n * Set the components of a vec2 to the given values\n *\n * @param {vec2} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @returns {vec2} out\n */\nfunction set(out, x, y) {\n out[0] = x\n out[1] = y\n return out\n}","module.exports = normalize\n\n/**\n * Normalize a vec2\n *\n * @param {vec2} out the receiving vector\n * @param {vec2} a vector to normalize\n * @returns {vec2} out\n */\nfunction normalize(out, a) {\n var x = a[0],\n y = a[1]\n var len = x*x + y*y\n if (len > 0) {\n //TODO: evaluate use of glm_invsqrt here?\n len = 1 / Math.sqrt(len)\n out[0] = a[0] * len\n out[1] = a[1] * len\n }\n return out\n}","module.exports = subtract\n\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec2} out the receiving vector\n * @param {vec2} a the first operand\n * @param {vec2} b the second operand\n * @returns {vec2} out\n */\nfunction subtract(out, a, b) {\n out[0] = a[0] - b[0]\n out[1] = a[1] - b[1]\n return out\n}","module.exports = dot\n\n/**\n * Calculates the dot product of two vec2's\n *\n * @param {vec2} a the first operand\n * @param {vec2} b the second operand\n * @returns {Number} dot product of a and b\n */\nfunction dot(a, b) {\n return a[0] * b[0] + a[1] * b[1]\n}","var add = require('gl-vec2/add')\nvar set = require('gl-vec2/set')\nvar normalize = require('gl-vec2/normalize')\nvar subtract = require('gl-vec2/subtract')\nvar dot = require('gl-vec2/dot')\n\nvar tmp = [0, 0]\n\nmodule.exports.computeMiter = function computeMiter(tangent, miter, lineA, lineB, halfThick) {\n //get tangent line\n add(tangent, lineA, lineB)\n normalize(tangent, tangent)\n\n //get miter as a unit vector\n set(miter, -tangent[1], tangent[0])\n set(tmp, -lineA[1], lineA[0])\n\n //get the necessary length of our miter\n return halfThick / dot(miter, tmp)\n}\n\nmodule.exports.normal = function normal(out, dir) {\n //get perpendicular\n set(out, -dir[1], dir[0])\n return out\n}\n\nmodule.exports.direction = function direction(out, a, b) {\n //get unit dir of two lines\n subtract(out, a, b)\n normalize(out, out)\n return out\n}","var util = require('polyline-miter-util')\n\nvar lineA = [0, 0]\nvar lineB = [0, 0]\nvar tangent = [0, 0]\nvar miter = [0, 0]\n\nmodule.exports = function(points, closed) {\n var curNormal = null\n var out = []\n if (closed) {\n points = points.slice()\n points.push(points[0])\n }\n\n var total = points.length\n for (var i=1; i<total; i++) {\n var last = points[i-1]\n var cur = points[i]\n var next = i<points.length-1 ? points[i+1] : null\n\n util.direction(lineA, cur, last)\n if (!curNormal) {\n curNormal = [0, 0]\n util.normal(curNormal, lineA)\n }\n\n if (i === 1) //add initial normals\n addNext(out, curNormal, 1)\n\n if (!next) { //no miter, simple segment\n util.normal(curNormal, lineA) //reset normal\n addNext(out, curNormal, 1)\n } else { //miter with last\n //get unit dir of next line\n util.direction(lineB, next, cur)\n\n //stores tangent & miter\n var miterLen = util.computeMiter(tangent, miter, lineA, lineB, 1)\n addNext(out, miter, miterLen)\n }\n }\n\n //if the polyline is a closed loop, clean up the last normal\n if (points.length > 2 && closed) {\n var last2 = points[total-2]\n var cur2 = points[0]\n var next2 = points[1]\n\n util.direction(lineA, cur2, last2)\n util.direction(lineB, next2, cur2)\n util.normal(curNormal, lineA)\n \n var miterLen2 = util.computeMiter(tangent, miter, lineA, lineB, 1)\n out[0][0] = miter.slice()\n out[total-1][0] = miter.slice()\n out[0][1] = miterLen2\n out[total-1][1] = miterLen2\n out.pop()\n }\n\n return out\n}\n\nfunction addNext(out, normal, length) {\n out.push([[normal[0], normal[1]], length])\n}","/**\n * @description 两条二维线段是否相交,不考虑端点重合的情况\n */\nexport function lineIsIntersecting(line1: { x: number; y: number }[], line2: { x: number; y: number }[]) {\n const a1 = line1[0]\n const a2 = line1[1]\n const b1 = line2[0]\n const b2 = line2[1]\n var ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x)\n var ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x)\n var u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y)\n if (u_b !== 0) {\n var ua = ua_t / u_b\n var ub = ub_t / u_b\n if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n return true\n }\n }\n return false\n}\n\n/**\n * @description 两条二维折线段的交点,不考虑端点重合的情况\n */\nexport function findIntersectingOfLines(line1: { x: number; y: number }[], line2: { x: number; y: number }[]) {\n for (let i = 0; i < line1.length - 1; i++) {\n for (let j = 0; j < line2.length - 1; j++) {\n if (lineIsIntersecting([line1[i], line1[i + 1]], [line2[j], line2[j + 1]])) {\n return {\n x: (line1[i].x + line1[i + 1].x) / 2,\n y: (line1[i].y + line1[i + 1].y) / 2,\n line1RelativeIndex: i,\n line2RelativeIndex: j,\n }\n }\n }\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { Vector3 } from 'three/webgpu'\nimport getNormals from 'polyline-normals'\nimport type * as PluginType from '../typing'\nimport { findIntersectingOfLines, lineIsIntersecting } from '../../shared-utils/math/intersecting'\n\n/** 生成曲线参数 */\ninterface LineGeometryOption {\n /** 路径 */\n path: PluginType.PathItem[]\n /** 线宽,默认是 0.5 */\n width: number\n /** 每一段的长度,默认是 0.5 */\n unitLength: number\n skipPositions?: THREE.Vector3[] | null\n useAutoDepthTest?: boolean\n}\n\n// 定义常量\nconst TRIANGLE_NUMBER_OF_RECTANGLE = 2 // 每个矩形有两个三角形\nconst VERTEX_NUMBER_OF_TRIANGLE = 3 // 每个三角形有三个顶点\nconst AXIS_NUMBER_OF_VERTEX = 3 // 每个顶点有三个轴坐标\nconst UV_NUMBER_OF_VERTEX = 2 // 每个顶点有两个 UV 轴坐标\n\n/** 创建路线的几何体\n * @param curvePoints 三维点位\n * @param unitWidth 线段宽度\n * @param unitLength 每一段的长度\n * @returns THREE BufferGeometry\n */\n\nexport function createLineGeometry(options: LineGeometryOption) {\n const unitWidth = options.width\n const unitLength = options.unitLength\n const halfUnitWidth = unitWidth / 2\n\n const path = options.path\n if (path.length === 0) return { geometry: new THREE.BufferGeometry(), maxV: 0, curvePath: null, curvePoints: null }\n\n const curvePath = new THREE.CurvePath<THREE.Vector3>()\n path.forEach((pathData) => {\n const curve = createCurve(pathData)\n curve && curvePath.add(curve)\n })\n\n // 切片数\n const divisions = Math.ceil(curvePath.getLength() * 100)\n curvePath.arcLengthDivisions = divisions\n // 切点,length = divisions + 1\n const curvePoints = curvePath.getPoints(divisions)\n\n // 切点数量\n const curvePointsLength = curvePoints.length\n if (curvePointsLength <= 2) return { geometry: new THREE.BufferGeometry(), maxV: 0, curvePath: null, curvePoints: null }\n // 每个切点在曲线上的切线\n const normals = getNormals(curvePoints.map((p) => [p.x, p.z])) // curvePoints:每个点切线的向量「二维」\n\n const rectangleNumber = curvePointsLength - 1 // N 个切线点,构成了 N - 1 个矩形\n const indexNumber = rectangleNumber * TRIANGLE_NUMBER_OF_RECTANGLE * VERTEX_NUMBER_OF_TRIANGLE\n const verticesNumber = 2 * curvePointsLength // 顶点数量(包含公用):每个切点对应两个顶点,N 个 切点有 2N 个顶点\n const positionNumber = verticesNumber * AXIS_NUMBER_OF_VERTEX // 坐标点数量\n const uvNumber = verticesNumber * UV_NUMBER_OF_VERTEX // uv 数量\n\n const index = new Uint32Array(indexNumber)\n const positions = new Float32Array(positionNumber)\n const uv = new Float32Array(uvNumber)\n\n let totalLength = 0\n let maxV = 0\n\n // 每次循环设置两个顶点\n for (let i = 0; i < curvePointsLength; i++) {\n const [nx, nz] = normals[i]![0]!\n const curvePoint = curvePoints[i]!\n const { x: curvePointX, y: curvePointY, z: curvePointZ } = curvePoint\n\n // 顶点1 vertices[2i]\n const vertices2i = new Vector3(curvePointX + nx * halfUnitWidth, curvePointY + 0.05, curvePointZ + nz * halfUnitWidth)\n positions[i * 6 + 0] = vertices2i.x\n positions[i * 6 + 1] = vertices2i.y\n positions[i * 6 + 2] = vertices2i.z\n\n // 顶点2 vertices[2i + 1]\n const vertices2i1 = new Vector3(curvePointX - nx * halfUnitWidth, curvePointY + 0.05, curvePointZ - nz * halfUnitWidth)\n positions[i * 6 + 3] = vertices2i1.x\n positions[i * 6 + 4] = vertices2i1.y\n positions[i * 6 + 5] = vertices2i1.z\n\n // 计算总长度\n totalLength += i > 0 ? curvePoints[i - 1]!.clone().sub(curvePoints[i]!).length() : 0\n\n // 设置 uv\n // uv.y 表示路线的长度点,可以用于在 glsl 中控制颜色展示\n // 前两个顶点的 uv.y 为 0,最后两个顶点的 uv.y 为 end\n const end = totalLength / unitLength\n maxV = end\n // 顶点1的uv\n uv[i * 4 + 0] = 0 // uv.x\n uv[i * 4 + 1] = end // uv.y\n // 顶点2的uv\n uv[i * 4 + 2] = 1 // uv.x\n uv[i * 4 + 3] = end // uv.y\n\n // 目前 skip 时只会把面片跳过去,如果希望图像是连续的,需要跳过的面片的 uv 也要跳过\n const center = new THREE.Vector3().lerpVectors(vertices2i, vertices2i1, 0.5)\n if (options.skipPositions) {\n const shouldSkip = options.skipPositions.some((skipPosition) => skipPosition.distanceTo(center) < 0.26)\n if (shouldSkip) continue\n }\n\n if (i === curvePointsLength - 1) continue\n index[i * 6 + 0] = i * 2 + 0\n index[i * 6 + 1] = i * 2 + 2\n index[i * 6 + 2] = i * 2 + 1\n index[i * 6 + 3] = i * 2 + 2\n index[i * 6 + 4] = i * 2 + 3\n index[i * 6 + 5] = i * 2 + 1\n }\n\n // 后处理,消除转弯处的重叠\n const intersectingIndex: number[] = [] // 参与重叠的i值\n let lastHandleIndex: number // 上一个处理的结束的i值(不包含y值处理的部分,只包含重叠部分计算的)\n const animationWillError: { start: number; end: number }[] = [] // 动画会出错的i值\n for (let i = 0; i < curvePointsLength - 1; i++) {\n if (lastHandleIndex !== undefined) {\n if (i <= lastHandleIndex) continue\n }\n const ni /** next i */ = i + 1\n const p1 = {\n x: positions[i * 6 + 0],\n y: positions[i * 6 + 2],\n }\n const p2 = {\n x: positions[i * 6 + 3],\n y: positions[i * 6 + 5],\n }\n const p3 = {\n x: positions[ni * 6 + 0],\n y: positions[ni * 6 + 2],\n }\n const p4 = {\n x: positions[ni * 6 + 3],\n y: positions[ni * 6 + 5],\n }\n const intersecting = lineIsIntersecting([p1, p2], [p3, p4])\n if (intersecting) intersectingIndex.push(i)\n /** ============ !intersecting 表示重叠部分结束,接下来开始处理重叠部分的positions ============ */\n if (!intersecting && intersectingIndex.length) {\n intersectingIndex.push(i)\n // 求 求交点时应该用哪一侧的线\n const d1 = new THREE.Vector2(p1.x, p1.y).distanceTo(new THREE.Vector2(p3.x, p3.y))\n const d2 = new THREE.Vector2(p2.x, p2.y).distanceTo(new THREE.Vector2(p4.x, p4.y))\n // 前后找一定数量的点组成线,求交点\n const x = 300 // 延伸的长度\n const line1: { x: number; y: number }[] = []\n const line2: { x: number; y: number }[] = []\n\n // 取重叠部分前面的一段点\n const jStart = Math.max(0, intersectingIndex[0] - unitLength * x)\n const jEnd = intersectingIndex[0]\n for (let j = jStart; j < jEnd; j++) {\n if (d1 < d2) {\n line1.push({ x: positions[j * 6 + 0], y: positions[j * 6 + 2] })\n } else {\n line1.push({ x: positions[j * 6 + 3], y: positions[j * 6 + 5] })\n }\n }\n\n // 取重叠部分后面的一段点\n const kStart = intersectingIndex[intersectingIndex.length - 1]\n const kEnd = Math.min(curvePointsLength - 1, intersectingIndex[intersectingIndex.length - 1] + unitLength * x)\n for (let k = kStart; k < kEnd; k++) {\n if (d1 < d2) {\n line2.push({ x: positions[k * 6 + 0], y: positions[k * 6 + 2] })\n } else {\n line2.push({ x: positions[k * 6 + 3], y: positions[k * 6 + 5] })\n }\n }\n const result = findIntersectingOfLines(line1, line2)\n\n if (result) {\n const {\n line1RelativeIndex /** line1的交点的相对index */,\n line2RelativeIndex /** line2的交点的相对index */,\n x: intersectingX,\n y: intersectingY,\n } = result\n const line1Index /** line1的交点的index */ = jStart + line1RelativeIndex\n const line2Index /** line2的交点的index */ = kStart + line2RelativeIndex + 2\n // 需要重新计算的顶点\n for (let l = line1Index; l < line2Index; l++) {\n // 替换xz\n if (d1 < d2) {\n positions[l * 6 + 0] = intersectingX\n positions[l * 6 + 2] = intersectingY\n } else {\n positions[l * 6 + 3] = intersectingX\n positions[l * 6 + 5] = intersectingY\n }\n lastHandleIndex = l\n }\n // 平均一下交点前一段部分的y值, 和交点后一段部分的y值,同时使重叠部分(两个交点之间)内侧的y值保持一致\n let jStartY: number\n let line1IndexY: number\n let line2IndexY: number\n let kEndY: number\n let centerY: number\n if (d1 < d2) {\n jStartY = positions[jStart * 6 + 1]\n line1IndexY = positions[line1Index * 6 + 1]\n line2IndexY = positions[line2Index * 6 + 1]\n kEndY = positions[kEnd * 6 + 1]\n centerY = (line1IndexY + line2IndexY) / 2\n } else {\n jStartY = positions[jStart * 6 + 4]\n line1IndexY = positions[line1Index * 6 + 4]\n line2IndexY = positions[line2Index * 6 + 4]\n kEndY = positions[kEnd * 6 + 4]\n centerY = (line1IndexY + line2IndexY) / 2\n }\n // 修改 jStart(含) ~ line1Index(不含) 的 y 值, y 值为 jSTartY ~ centerY\n for (let l = jStart; l < line1Index; l++) {\n const length = line1Index - jStart // 这里长度故意要加一,因为不希望结尾的y完全等于 centerY,也就是说结尾的t值不是1,要小一点\n const t = (l - jStart) / length\n if (d1 < d2) {\n positions[l * 6 + 1] = jStartY + (centerY - jStartY) * t\n } else {\n positions[l * 6 + 4] = jStartY + (centerY - jStartY) * t\n }\n }\n // 修改 line1Index(含) ~ line2Index(不含) 的 y 值,y 值为 centerY\n for (let l = line1Index; l < line2Index; l++) {\n if (d1 < d2) {\n positions[l * 6 + 1] = centerY\n } else {\n positions[l * 6 + 4] = centerY\n }\n }\n // 修改 line2Index(含) ~ kEnd(不含) 的 y 值,y 值为 centerY ~ kEndY\n for (let l = line2Index; l < kEnd; l++) {\n const length = kEnd - line2Index // 这里长度故意要加一,因为不希望结尾的y完全等于 kEnd 处的Y值,也就是说结尾的t值不是1,要小一点\n const t = (l - line2Index + 1) / length // 这里不希望初始的y完全等于 centerY,也就是说初始的t值不是0,要大一点\n if (d1 < d2) {\n positions[l * 6 + 1] = centerY + (kEndY - centerY) * t\n } else {\n positions[l * 6 + 4] = centerY + (kEndY - centerY) * t\n }\n }\n animationWillError.push({\n start: line1Index,\n end: line2Index,\n })\n }\n\n intersectingIndex.length = 0\n }\n }\n\n const animationWillErrorAttribute = new Float32Array(verticesNumber)\n animationWillError.forEach((errorIndex) => {\n for (let i = 0; i < curvePointsLength - 1; i++) {\n if (i >= errorIndex.start && i <= errorIndex.end) {\n animationWillErrorAttribute[i * 2 + 0] = 1\n animationWillErrorAttribute[i * 2 + 1] = 1\n } else if (animationWillErrorAttribute[i] !== 1) {\n animationWillErrorAttribute[i * 2 + 0] = 0\n animationWillErrorAttribute[i * 2 + 1] = 0\n }\n }\n })\n\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geometry.setAttribute('uv', new THREE.BufferAttribute(uv, 2))\n // 白杰说先不加这个过滤\n // geometry.setAttribute('animationWillError', new THREE.BufferAttribute(animationWillErrorAttribute, 1))\n geometry.setIndex(new THREE.BufferAttribute(index, 1))\n\n return { geometry, maxV, animationWillError, curvePath, curvePoints }\n}\n\nfunction createCurve(item: PluginType.PathItem) {\n if (isCatmullRomCurve3Data(item)) {\n const positions = item.points.map((point) => new THREE.Vector3().fromArray(point))\n const curve = new THREE.CatmullRomCurve3(positions, item.closed ?? false, (item.curve_type ?? 'centripetal') as THREE.CurveType, item.tension)\n return curve\n }\n}\n\nfunction isCatmullRomCurve3Data(data: any): data is PluginType.CatmullRomCurve3 {\n return data.type === 'CatmullRomCurve3'\n}\n","<script lang=\"ts\">\n import { FONT_SIZE_MAP, type FontSizeType } from '../../shared-utils/fontSize'\n import px2rem from '../../shared-utils/px2rem'\n\n export let text = ''\n export let icon_url = ''\n export let distance = ''\n export let opacity = 1\n export let name = ''\n export let fontSize: FontSizeType = 'md'\n const text_background_url =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHUAAAA2CAMAAADOFiZMAAACEFBMVEUAAACIiIheXl5oaGh6enpsbG' +\n 'xiYmJ9fX1wcHBXV1eBgYFzc3NSUlKNjY2Dg4NOTk51dXVXV1dmZmZTU1N3d3dcXFyMjIyEhIRNTU2QkJC0tLS5ubnHx8fOzs6np6' +\n 'exsbHKysqoqKi9vb3U1NTPz8/Nzc2vr6/Dw8OysrK/v7/X19fS0tKurq62traqqqrJycmurq64uLifn5/Dw8O6urqQkJC6urro6O' +\n 'jt7e3o6OjU1NS3t7fBwcGjo6Ozs7Orq6u1tbXAwMCurq6rq6vy8vLx8fHr6+vp6enZ2dnd3d3a2trX19fV1dW/v7/IyMihoaGamp' +\n 'qVlZWLi4uCgoK+vr6urq7m5ubw8PDk5OTu7u7i4uLg4ODe3t7q6urS0tLi4uLOzs7e3t7Hx8fa2tqrq6vExMTAwMCnp6efn5+Wlp' +\n 'aHh4ezs7OoqKiJiYm6urqZmZmurq59fX29vb23t7e4uLipqanp6enc3Nza2trW1tbT09Pm5ubj4+PQ0NDg4ODExMTCwsK7u7vBwc' +\n 'G8vLy5ubm8vLy+vr64uLiysrKdnZ3CwsJoaGisrKzHx8ekpKTExMTv7+/i4uLa2trm5ubk5OTLy8vKysrExMTQ0NDX19ecnJzT09' +\n 'N/f3+dnZ12dnaQkJCXl5etra3Pz8+4uLiXl5fGxsaqqqrr6+vQ0NDKysrNzc3W1takpKShoaGsrKysrKyduRZkAAAAsHRSTlMATE' +\n '1NTExMTUxNTExMTExNTExMTU1MTU1MTICFc313fnl0iIWAe3h3aYqIgXx7eXZzcnFwaGggxLiog4J0dG9mZF82FMfEtK2pkYqKh3' +\n 'x4cm1rZmEmH8G/vry6trOxoZ2clpKOe3ptbWZjYmFgXFpaVlFPSDYlx7CspaSjoJ6akY6HfXt4bGpmY1xUU0g2LSzCuK6lopiWho' +\n 'F3YmFaVlZUUU5KPyEJCcl/fXNdXFxZUIUrIQsAAAV6SURBVFjDvZj3VxNBEMePBBIOQgmEQGghISSASSBBUQFBVIpUEaR3aVJExN' +\n '4F6fbee6//opPN2507E3P7fD4+b54z+935zt7lvPsBYbZ5lyXT7R5xms2ppaVpV615eVeuXL48PPzw4YPBwYsX+/vPnT1bW1t75u' +\n '7p0729PT13urs7O9vbt2/ffurUp1OQ2ts7O7u77/T09PaevnvmTG3t2XPn+vsvDg4+GH5UVjl/SAjGe29La2vr5EFgm4+WlpYDgN' +\n 'frbW7etQuuKDPTPTIy4nSa4bJ8lKYBV69arXmA1WpN81FamgqYzU6n0+12ZwI+qzPtyvDlR0dPCoGsecW4FEZcShwEyUDIGvtD+D' +\n 'cOZlrzFvcE3qylFXZ1cTqIgGk0K1xRSL84abaWtwl/8KM5kTiok04B2BpAPUWXAoGnQK3gn0xNW90ryDhpafXvJsYlJuoSdRCyTJ' +\n 'HqBOxR9IvbUl1/PN5pL9tFR4gTJJmi7N+wl8qf7k33S+YQE0VRJwZz42RogDZcAxx+sTn1jSDho6VFBKAbp9K1XqfXi3oRgmSqQ2' +\n 'AGePziNpfs2GN2lV5Pp+IJkkwIrDFz+Y+Y90h/Yvtz+f0o1YGnc/lVXvshASk8IHUm6ZMIYhI6YAEyqyHkE/n8Kkuh5AX6ZVdBly' +\n 'pJpRJVIgTJ0IluEGCb1BDYCzWFx79h/yl5ZV3PVUSVAQIDFhCyLO/h9E9KfuOPriOqzUFjmRYYueOqTWLGfhPfHZcGrkOlgcAGsk' +\n 'ZdAV7/eIVA2eN6qZGA3Yhcxxozn3+mkD3ZQ64Z3EnQJEBouMB+Xr+68LpAuTZBOokDoPXfNIK85vZP5AqUreNqdYI6AUINkBrAtU' +\n 'atgaA67mEft38GvxRThWopOAFrBbj9kYXsa3z0mnrTsLAHe3yRzxGhjoBQ0BT848foqfONkT6FAAWrce3PeEpA5vZPsDf23aIhgp' +\n 'fIiEiIiH/mKftPfKJxTjaNv8bM6zlSzk5dmIsMDk7EGrMEbj+e+q5xLjoyOrQbGiCCaZh5/PgLzy8YiIrgNPmaZtQovP6J3ezNaf' +\n 'TvxEfHQ2An8v/2K47hV4J0ExVBDbNCD4e/nH0lKj1+1RBvMEQboiEMUJI1BOmmGq0pVOP1z3nYF3G53EAIN4SHx4djNyxAkutQA1' +\n 'QnGeD2z3rY199RIZ+EtVxDPaDm9VdspYcWj65pteFaonIDBghpzeXyzNNTbyy8CpgCyCehjnvYx+uf9RTTU9cbo7SbRPmKQBnzaK' +\n 'MI2igthD8jVAvIuM/rXytjfyz4MFqBDgLWPGuA05/sqRQobaOzsBMbFQsRhaAWco/A6Z92FAuU446wWL+aHJWcHJtMOzEDwWrU+P' +\n 'yvHEcFRlkutELInT4NFiCRGqA6yQDWfH5jWdFegXLL8V3qDIsNIySHoRsWIGMN/wBY8/mXRosFxrrDCE20EwJzCGQ9XP7crBN46A' +\n 'dHbthmkPvluICccLzgchnDjBD/eqaxKOOtIKGyiEzDqSFOCt7D4X/dlHFDkNCWPu3fjTHGQBgpbI06TkeIpuQ37bbltAlSKstM/g' +\n '6EdYcEr0jJv2rLfrZXkFKcPhVjMsWY0GGSrTn00H7TakbD11sChd7qa+gCSKdJVitpyvWLlab6uifsieKtLk1N7QZWtvpYXl4aGx' +\n 'srAtIJBQVNWVlZOTkZGRm2z7bHW0q2lJRkZ2c3NOTn19fV19fn5zfAsmQL8Nhmg66cHOhvKigoSC/Iysk+vH9//jd2n8g6TG7yjb' +\n 'XZYCAMq6s7fBiah4aGLl0aGLhw4f758zuBmpq+vurq6h07dnR1dXTcrqqq2uejqup2R0dXF8jV1X19NTU1O3feu3f+/oWBgUtD++' +\n 'uePHtbLAThNzRClbi+VnseAAAAAElFTkSuQmCC'\n\n $: fontConfig = FONT_SIZE_MAP[fontSize]\n $: nameSize = px2rem(fontConfig?.name || 12)\n $: padding = fontConfig?.padding?.guide || [8, 2]\n $: paddingStyle = `${px2rem(padding[1])} ${px2rem(padding[0])}`\n $: distancePadding = fontConfig?.padding?.distance || [4, 2]\n $: distancePaddingStyle = `${px2rem(distancePadding[1])} ${px2rem(distancePadding[0])}`\n $: lineHeight = fontConfig?.lineHeight || 14\n $: lineHeightStyle = px2rem(lineHeight)\n</script>\n\n<div class=\"guide-line__tag\" style:opacity>\n <div class=\"guide-line__tag-point\" />\n <div class=\"guide-line__tag-line\" />\n <div class=\"guide-line__tag-content\">\n <div class=\"guide-line__tag-icon\" style:background-image={`url(${icon_url})`} />\n {#if text && !distance}\n <div class=\"guide-line__tag-text\" style:font-size={nameSize} style:padding={paddingStyle} style:border-image-source={`url(${text_background_url})`}>{text}</div>\n {/if}\n {#if distance}\n <div class=\"text-with-distance\" style:padding={distancePaddingStyle}>\n {#if name} <span class=\"line-name\" style:line-height={lineHeightStyle} style:font-size={nameSize}>{name}</span> {/if}\n <div class=\"distance-and-name\">\n <span class=\"distance\" style:line-height={lineHeightStyle} style:font-size={nameSize}>\n {distance}\n </span>\n <span class=\"name\" style:line-height={lineHeightStyle} style:font-size={nameSize}>{text}</span>\n </div>\n <div class=\"border\" />\n </div>\n {/if}\n </div>\n</div>\n\n<style>\n .guide-line__tag {\n position: relative;\n }\n\n .text-with-distance {\n display: flex;\n flex-direction: column;\n position: relative;\n padding: 2px 4px;\n border-radius: 2px;\n background: linear-gradient(to top, rgba(147, 147, 147, 0.3), rgba(74, 74, 74, 0.3));\n box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);\n }\n\n .text-with-distance .border {\n position: absolute;\n top: -50%;\n right: -50%;\n bottom: -50%;\n left: -50%;\n padding: 1px;\n border-radius: 4px;\n background: linear-gradient(to right, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.2));\n mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n mask-composite: exclude;\n -webkit-mask-composite: xor;\n transform: scale(0.5);\n }\n\n .distance-and-name {\n display: flex;\n gap: 3px;\n }\n\n .distance {\n white-space: nowrap;\n font-size: 10px;\n line-height: 14px;\n color: #66afff;\n }\n\n .name {\n opacity: 0.6;\n font-size: 10px;\n line-height: 14px;\n white-space: nowrap;\n color: #ffffff;\n }\n\n .line-name {\n color: #fff;\n white-space: nowrap;\n font-size: 10px;\n line-height: 14px;\n }\n\n .guide-line__tag-point {\n position: absolute;\n left: 50%;\n bottom: 1px;\n width: 7px;\n height: 2px;\n transform: translateX(-50%);\n background: #fff;\n border-radius: 50%;\n opacity: 0.5;\n }\n\n .guide-line__tag-line {\n position: absolute;\n left: 50%;\n bottom: 1px;\n width: 1px;\n height: 30px;\n transform: translateX(-50%);\n background: linear-gradient(to top, #fff, rgba(255, 255, 255, 0));\n }\n\n .guide-line__tag-content {\n position: absolute;\n left: -15px;\n bottom: 31px;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n\n .guide-line__tag-icon {\n width: 30px;\n height: 30px;\n background-size: 100%;\n }\n\n .guide-line__tag-text {\n box-sizing: content-box;\n width: max-content;\n transform: translateX(-3px);\n white-space: nowrap;\n font-size: 10px;\n line-height: 14px;\n border: solid transparent;\n border-width: 2px 8px 2px 6px;\n border-image-slice: 6 25 6 18 fill;\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n</style>\n","/**\n * 筛选出给定数组中,相邻元素不能重复的元素组成的新数组\n * @param array 要筛选的数组\n * @returns 筛选后的新数组\n */\nexport function filterAdjacentDistinct<T>(array: T[]): T[] {\n if (array.length === 0) return []\n\n return array.filter((item, index) => item !== array[index - 1])\n}\n","import type { Work } from '@realsee/five-webgpu'\nimport type { CatmullRomCurve3, ExtraRouteData } from '../typing'\nimport * as THREE from 'three/webgpu'\nimport { transformPosition } from '../../shared-utils/five/transformPosition'\n\nexport function createPath(\n panoIndexList: number[],\n work: Work,\n options?: Omit<CatmullRomCurve3, 'type' | 'points'> & ExtraRouteData,\n): CatmullRomCurve3[] {\n if (panoIndexList.length < 2) return []\n\n const fixedPositionInfo: number[][] = []\n panoIndexList.forEach((panoIndex, i) => {\n let position = options?.route_standing_positions?.[panoIndex]\n if (!position) position = work.observers[panoIndex]?.standingPosition?.toArray()\n\n if (!position) return\n const lastPanoIndex = panoIndexList[i - 1]\n\n // 插值\n const routePoints =\n options?.node_pair_to_route_points?.[`${lastPanoIndex}:${panoIndex}`]?.slice() ??\n options?.node_pair_to_route_points?.[`${panoIndex}:${lastPanoIndex}`]?.slice().reverse()\n\n routePoints?.forEach((point) => {\n fixedPositionInfo.push(point)\n })\n\n fixedPositionInfo.push(position)\n })\n\n const transform = work.transform\n const positions = fixedPositionInfo.map((position) => transformPosition(new THREE.Vector3().fromArray(position), transform).toArray())\n\n return [{ ...options, type: 'CatmullRomCurve3', points: positions }]\n}\n","import { GuideLineMaterial } from './utils/GuideLineMaterial'\nimport type GuideLinePlugin from './Controller'\nimport type { Five, Mode, Work } from '@realsee/five-webgpu'\nimport type { Tag } from '../PanoTagPlugin'\nimport type * as PluginType from './typing'\nimport type { GuideLineItem } from './GuideLineItem'\nimport * as THREE from 'three/webgpu'\nimport { logError, logWarning } from '../shared-utils/log'\nimport { createLineGeometry } from './utils/createLineGeometry'\nimport { BetterTween, blink, GUIDELINE_DEFAULT_ARROW_TEXTURE, isModelLike, isPanoramaLike, notNil, replaceStaticPrefix, tweenProgress } from '../shared-utils'\nimport { loadTexture } from '../shared-utils/three/loadTexture'\nimport { PanoTagPluginController } from '../PanoTagPlugin'\nimport CustomTag from './Components/Tag.svelte'\nimport { filterAdjacentDistinct } from './utils'\nimport objectAssignDeep from 'object-assign-deep'\nimport { createPath } from './utils/createPath'\nimport { getCurrentFontSize, getGlobalResponsiveFontSize } from '../shared-utils/fontSize'\n\nimport { mountComponent, type MountedComponent } from '../shared-utils/svelte/component.svelte'\n/** @link https://threejs.org/docs/index.html#api/en/extras/curves/CatmullRomCurve3 */\ntype CatmullRomCurve3RestParams = Omit<PluginType.CatmullRomCurve3, 'type' | 'points'>\n\nexport interface GuideLineTagContainer {\n tag: Tag<'Custom', '2DPoint'> | null\n plugin: PanoTagPluginController\n app?: MountedComponent<any>\n}\n\n/** 在不同模态下的 GuideLine */\nclass GuideLineModeItem {\n public get panoGroup() {\n return this._panoGroup\n }\n /** 可展示的楼层 */\n public get visibleFloorIndexes() {\n return this._visibleFloorIndexes\n }\n /** THREE Curve 路径 */\n public get curvePath() {\n return this._curvePath\n }\n /** THREE Curve 路径上的点 */\n public get curvePoints() {\n return this._curvePoints\n }\n\n public name = ''\n public startTagContainer?: GuideLineTagContainer\n public endTagContainer?: GuideLineTagContainer\n public path: PluginType.PathItem[] = []\n public geometryStyle: PluginType.GuideLineGeometryStyle = {}\n public materialStyle: PluginType.GuideLineMaterialStyle = {}\n public meshStyle: PluginType.GuideLineMeshStyle = {}\n public readonly group: THREE.Group = new THREE.Group()\n public readonly mesh: THREE.Mesh<THREE.BufferGeometry, GuideLineMaterial>\n public visible: boolean | null = null\n /** 保存原始的 tag 数据,用于更新距离显示 */\n private startTagData: Tag | PluginType.ModelGuideLineTagData | null = null\n private endTagData: Tag | PluginType.ModelGuideLineTagData | null = null\n private five: Five\n private mode: PluginType.GuideLineModeItemMode\n private _curvePath: THREE.CurvePath<THREE.Vector3> | null = null\n private _curvePoints: THREE.Vector3[] | null = null\n private _panoGroup: number[] = []\n private skippedPositions: null | THREE.Vector3[] = null\n private textureUrl = ''\n private scale = 1\n private width = 0.5\n private unitLength = 0.5\n private _visibleFloorIndexes: null | number[] = null\n /** Five Mode 是否满足 */\n private modeVisible = false\n /** 楼层是否满足展示条件 */\n private floorVisible = true\n /** 默认是否展示 */\n private defaultVisible = false\n /** 走点动画 */\n private inWalkAnimation = false\n private customVisible: boolean | null = null\n private parent: GuideLineItem\n private plugin: GuideLinePlugin\n private textureHasLoaded = false\n private disposed = false\n private flowAnime = new BetterTween<{ progress: number }>({ progress: 0 }).to({ progress: 1 }).duration(1500).repeat(Infinity)\n /** 缓存 panoGroup 中每个点距离起点的长度 */\n private cacheLengths: number[] = []\n /** 为了让多条路线在高度上错开,每个路线都需要有个额外的 offset */\n private heightOffset = 0\n /** 响应式字体大小管理器 */\n private fontSizeManager = getGlobalResponsiveFontSize()\n /** 当前字体大小 */\n private currentFontSize = getCurrentFontSize()\n /** 字体大小订阅取消函数 */\n private unsubscribeFontSize: (() => void) | null = null\n\n public constructor(five: Five, options: { mode: PluginType.GuideLineModeItemMode; plugin: GuideLinePlugin; parent: GuideLineItem }) {\n this.five = five\n this.mode = options.mode\n this.plugin = options.plugin\n this.parent = options.parent\n this.group.name = 'GuideLineModeItem'\n\n const geometry = new THREE.BufferGeometry()\n // Keep the initial node material layout valid until path geometry arrives.\n geometry.setAttribute('position', new THREE.Float32BufferAttribute(new Float32Array(9), 3))\n geometry.setAttribute('uv', new THREE.Float32BufferAttribute(new Float32Array(6), 2))\n geometry.setDrawRange(0, 0)\n const material = new GuideLineMaterial()\n this.mesh = new THREE.Mesh(geometry, material)\n\n this.mesh.name = 'GuideLineModeItem'\n\n this.group.add(this.mesh)\n\n if (this.mode === 'panorama') {\n this.parent.hooks.on('walkStart', this.onWalkAnimationStart)\n this.parent.hooks.on('walkEnded', this.onWalkAnimationEnd)\n }\n\n this.updateVisible()\n this.onFiveModeChange(this.five.getCurrentState().mode)\n this.onFiveModelShownFloorChange(this.five.model?.shownFloor ?? null)\n\n this.flowAnime.onUpdate(this.onFlowAnimeUpdate)\n\n this.parent.hooks.on('show', this.updateVisible)\n this.parent.hooks.on('hide', this.updateVisible)\n this.plugin.hooks.on('show', this.updateVisible)\n this.plugin.hooks.on('hide', this.updateVisible)\n this.plugin.hooks.on('enable', this.updateVisible)\n this.plugin.hooks.on('disable', this.updateVisible)\n this.plugin.hooks.on('dispose', this.dispose)\n this.five.on('modeChange', this.onFiveModeChange)\n this.five.on('modelShownFloorChange', this.onFiveModelShownFloorChange)\n\n // 监听字体大小变化\n if (typeof this.fontSizeManager === 'object' && 'subscribe' in this.fontSizeManager) {\n this.unsubscribeFontSize = this.fontSizeManager.subscribe((fontSize) => {\n this.currentFontSize = fontSize\n this.updateTagFontSize()\n })\n }\n\n this.five.needsRender = true\n }\n\n /** 自定义展示 */\n public setCustomVisible(visible: boolean | null) {\n if (this.disposed) return this.logError('disposed')\n if (this.customVisible === visible) return\n this.customVisible = visible\n this.updateVisible()\n }\n\n /** 设置默认展示 */\n public setDefaultVisible(visible: boolean) {\n if (this.disposed) return this.logError('disposed')\n if (this.defaultVisible === visible) return\n this.defaultVisible = visible\n this.updateVisible()\n }\n\n public dispose = () => {\n if (this.disposed) return\n this.disposed = true\n this.parent.hooks.off('show', this.updateVisible)\n this.parent.hooks.off('hide', this.updateVisible)\n this.plugin.hooks.off('show', this.updateVisible)\n this.plugin.hooks.off('hide', this.updateVisible)\n this.plugin.hooks.off('enable', this.updateVisible)\n this.plugin.hooks.off('disable', this.updateVisible)\n this.five.off('modeChange', this.onFiveModeChange)\n this.five.off('modelShownFloorChange', this.onFiveModelShownFloorChange)\n // 取消字体大小订阅\n this.unsubscribeFontSize?.()\n this.doHide()\n this.startTagContainer?.plugin.dispose()\n this.endTagContainer?.plugin.dispose()\n }\n\n /** 基础宽、长 */\n public setUnitSize(width: number, length: number) {\n if (this.disposed) return this.logError('disposed')\n this.width = width\n this.unitLength = length\n this.setGeometryByPath(this.path, { width, unit_length: length })\n }\n\n /** 设置缩放 */\n public setScale(scale: number) {\n if (this.disposed) return this.logError('disposed')\n this.scale = scale\n this.setGeometryByPath(this.path, { scale })\n }\n\n /** 通过点位设置线条形状 */\n public setGeometryByPanoGroup(\n _panoGroup: number[],\n options?: CatmullRomCurve3RestParams & PluginType.ExtraRouteData & PluginType.GuideLineGeometryStyle & { skipPanoGroup?: boolean },\n ) {\n if (this.disposed) return this.logError('disposed')\n if (!this.five.work) return this.logError('setPathByPanoGroup: work is not ready')\n const panoGroup = filterAdjacentDistinct(_panoGroup)\n this._panoGroup = panoGroup\n if (options?.skipPanoGroup !== undefined) {\n const positions = options.skipPanoGroup\n ? panoGroup.map((panoIndex) => this.plugin.workUtil.getObserverStandingPosition(panoIndex)).filter(notNil)\n : null\n this.skippedPositions = positions\n }\n const currState = this.five.getCurrentState()\n // 当前的workCode 可能不是沙盘中对应的workCode, 所以需要在使用workCode之前设置一下workUtil中的workCode, 否则沙盘会报错\n const workCode = this.plugin.workUtil.workCode || currState.workCode\n const work = this.five.works.getWork(workCode)\n const path = createPath(panoGroup, work, options)\n this.path = path\n this.setGeometryByPath(path, options)\n }\n\n /** 通过路径设置线条形状 */\n public setGeometryByPath(path: PluginType.PathItem[], options?: PluginType.GuideLineGeometryStyle) {\n if (this.disposed) return this.logError('disposed')\n\n const scale = options?.scale ?? this.scale\n const width = options?.width ?? this.width\n const unitLength = options?.unit_length ?? this.unitLength\n this.scale = scale\n this.width = width\n this.unitLength = unitLength\n const { geometry, maxV, curvePath, curvePoints } = createLineGeometry({\n path,\n width: width * scale,\n unitLength: unitLength * scale,\n skipPositions: this.skippedPositions,\n })\n this._curvePath = curvePath\n this._curvePoints = curvePoints\n this.mesh.geometry.copy(geometry)\n this.mesh.material.needsUpdate = true\n this.mesh.material.maxV.value = maxV\n\n this.five.needsRender = true\n\n this.path = path\n this.geometryStyle = { ...this.geometryStyle, ...options }\n }\n\n /** 设置线条材质 */\n public setMartial(options?: PluginType.GuideLineMaterialStyle) {\n if (this.disposed) return this.logError('disposed')\n this.setDefaultVisible(options?.visible ?? false)\n this.setColor(options?.color ?? '#ffffff')\n this.setOpacity(options?.opacity ?? 0.5)\n const fallbackUrl = replaceStaticPrefix(this.plugin.staticPrefix, GUIDELINE_DEFAULT_ARROW_TEXTURE)\n this.setTextureUrl(options?.texture?.url ?? fallbackUrl)\n if (options?.background_color !== undefined) this.setBackgroundColor(options.background_color)\n if (options?.background_opacity !== undefined) this.setBackgroundOpacity(options.background_opacity)\n if (options?.border_color !== undefined) this.setBorderColor(options.border_color)\n if (options?.border_opacity !== undefined) this.setBorderOpacity(options.border_opacity)\n if (options?.border_width !== undefined) this.setBorderWidth(options.border_width)\n if (options?.background_clip !== undefined) this.setBackgroundClip(options.background_clip)\n\n const nextMaterialStyle = { ...this.materialStyle, ...options }\n this.materialStyle = nextMaterialStyle\n }\n\n /** 设置模型状态 */\n public setMeshStyle(options?: PluginType.GuideLineMeshStyle) {\n if (options?.translate) {\n const position = new THREE.Vector3()\n const translateVector = new THREE.Vector3().fromArray(options.translate)\n translateVector.y += this.heightOffset\n position.add(translateVector)\n this.group.position.copy(position)\n applyTagTranslate(this.startTagContainer, translateVector)\n applyTagTranslate(this.endTagContainer, translateVector)\n }\n const nextMeshStyle = { ...this.meshStyle, ...options }\n this.meshStyle = nextMeshStyle\n\n function applyTagTranslate(tagContainer: GuideLineTagContainer | undefined, translate: THREE.Vector3) {\n if (!tagContainer?.tag) return\n const tagPositionVector = new THREE.Vector3().fromArray(tagContainer.tag.position)\n tagPositionVector.add(translate)\n const tagPosition = tagPositionVector.toArray()\n tagContainer.plugin.changeTagById(tagContainer.tag.id, { position: tagPosition })\n }\n }\n\n /** 设置 Y 轴上的偏移量,为了让多条路线在高度上错开,每个路线都需要有个额外的 offset */\n public setHeightOffset(offset: number) {\n const position = new THREE.Vector3()\n if (this.meshStyle.translate) position.add(new THREE.Vector3().fromArray(this.meshStyle.translate))\n position.setY(position.y + offset)\n this.group.position.copy(position)\n this.heightOffset = offset\n this.five.needsRender = true\n }\n\n /** 设置贴图颜色 */\n public setColor(color: null | string) {\n if (this.disposed) return this.logError('disposed')\n if (color) {\n this.mesh.material.mapColor.value.set(color)\n }\n this.mesh.material.useMapColor.value = color ? 1 : 0\n this.five.needsRender = true\n }\n\n /** 设置边框 */\n public setBorderColor(color: string) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.borderColor.value.set(color)\n this.five.needsRender = true\n }\n\n /** 设置边框透明度 */\n public setBorderOpacity(opacity: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.borderOpacity.value = opacity\n this.five.needsRender = true\n }\n\n public setBackgroundClip(backgroundClip: PluginType.GuideLineMaterialStyle['background_clip']) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.backgroundClip.value = backgroundClip === 'border-box' ? 0 : 1\n this.five.needsRender = true\n }\n\n /**\n * @description: 设置边框宽度\n */\n public setBorderWidth(width: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.borderWidth.value = width\n this.five.needsRender = true\n }\n\n /** 设置背景颜色 */\n public setBackgroundColor(color: string) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.backgroundColor.value.set(color)\n this.five.needsRender = true\n }\n\n /** 设置背景透明度 */\n public setBackgroundOpacity(opacity: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.backgroundOpacity.value = opacity\n this.five.needsRender = true\n }\n\n /** 设置整体透明度 */\n public setOpacity(opacity: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.opacity = opacity\n this.five.needsRender = true\n }\n\n /** 设置贴图透明度 */\n public setMapOpacity(opacity: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.mapOpacity.value = opacity\n this.five.needsRender = true\n }\n\n /** 设置贴图 */\n public setTextureUrl(url: string) {\n if (this.disposed) return this.logError('disposed')\n this.textureUrl = url\n loadTexture(url).then((texture) => {\n if (this.disposed) return\n if (this.textureUrl !== url) return\n texture.wrapT = THREE.RepeatWrapping\n this.textureHasLoaded = true\n this.mesh.material.mapNode.value = texture\n this.mesh.material.needsUpdate = true\n this.five.needsRender = true\n this.updateVisible()\n })\n }\n\n public setVisibleFloorIndexes(floorIndexes: number[]) {\n if (this.disposed) return this.logError('disposed')\n this._visibleFloorIndexes = floorIndexes\n this.onFiveModelShownFloorChange(this.five.model?.shownFloor ?? null)\n }\n\n public setStartTag(tag: Tag | PluginType.ModelGuideLineTagData | null) {\n this.startTagData = tag\n this.setTag('start', tag)\n }\n\n public setEndTag(tag: Tag | PluginType.ModelGuideLineTagData | null) {\n this.endTagData = tag\n this.setTag('end', tag)\n }\n\n /** 更新 tag 的距离显示(当 formatDistance 函数改变时调用) */\n public updateTagDistance() {\n if (!this.curvePath) return\n if (this.startTagData) this.setTag('start', this.startTagData)\n if (this.endTagData) this.setTag('end', this.endTagData)\n }\n\n /** 闪烁 */\n public flicker() {\n if (this.disposed) return this.logError('disposed')\n blink([this.group, this.startTagContainer?.plugin?.tags[0]?.dom, this.endTagContainer?.plugin?.tags[0]?.dom].filter(Boolean), {\n loop: 6,\n updateRender: () => {\n this.five.needsRender = true\n },\n })\n }\n\n /** 求起点到 panoIndex 曲线长度\n * @param index panoIndex 在 panoGroup 中的索引\n *\n * @description 为什么不使用 panoIndex 作为参数?\n * - panoIndex 在一个曲线中可能出现多次,无法确定是哪一个。\n */\n public getLengthByPanoGroupIndex(index: number) {\n if (this.disposed) return this.logError('disposed')\n // 优先使用缓存\n if (this.cacheLengths.length !== 0) return this.cacheLengths[index]\n\n this.cacheLengths = this.getPanoGroupLengths()\n return this.cacheLengths[index]\n }\n\n private getPanoGroupLengths() {\n if (!this.curvePoints || !this.curvePath) return []\n const curvePointsLength = this.curvePoints.length\n const curveLength = this.curvePath?.getLength() ?? 0\n const divisions = curvePointsLength - 1\n const divisionLength = curveLength / divisions\n const curveLengths = this.curvePath?.getLengths(divisions) ?? []\n\n const lengths: number[] = []\n let observerGroupIndex = 0\n\n for (let i = 0; i < curvePointsLength; i++) {\n const currentCurvePoint = this.curvePoints[i]\n const standingPosition = this.plugin.workUtil.getObserverStandingPosition(observerGroupIndex)\n if (!standingPosition) break\n // Y 值都设置成 0,消除 Y 轴影响\n const distance = standingPosition.clone().setY(0).distanceTo(currentCurvePoint.clone().setY(0))\n if (distance < divisionLength) {\n lengths.push(curveLengths[i])\n observerGroupIndex += 1\n }\n }\n\n return lengths\n }\n\n private setTag(type: 'start' | 'end', _tag: Tag | PluginType.ModelGuideLineTagData | null) {\n const curvePath = this.curvePath\n if (!_tag?.data) {\n return\n }\n const tagContainer =\n type === 'start'\n ? this.startTagContainer ??\n (() => {\n this.startTagContainer = { tag: null, plugin: new PanoTagPluginController(this.five, { containerZIndex: 10 }) }\n return this.startTagContainer\n })()\n : this.endTagContainer ??\n (() => {\n this.endTagContainer = { tag: null, plugin: new PanoTagPluginController(this.five, { containerZIndex: 10 }) }\n return this.endTagContainer\n })()\n const baseTag: Omit<Tag<'Custom', '2DPoint'>, 'id' | 'position'> = {\n contentType: 'Custom',\n stickType: '2DPoint',\n config: { visibleConfig: { visibleFiveMode: ['Floorplan', 'Mapview'], followModelVisibility: false } },\n style: { point: { enabled: false } },\n data: {},\n }\n const tag = objectAssignDeep({}, baseTag, _tag) as Tag<'Custom', '2DPoint'>\n tagContainer.tag = tag\n if (isModelTag(tag)) {\n tagContainer.tag.element = (container) => {\n tagContainer.app?.destroy()\n const distanceInMeter = curvePath?.getLength() ?? 0\n const i18n = this.plugin.config.i18n ?? ((v: string) => v)\n const formattedDistance = this.plugin.config.formatDistance\n ? this.plugin.config.formatDistance(distanceInMeter)\n : `${i18n('全程')}${Math.round(distanceInMeter)}${i18n('米')}`\n const props =\n type === 'start' ? { ...tag.data, name: this.name, distance: formattedDistance } : tag.data\n const app = mountComponent(CustomTag, container, { fontSize: this.currentFontSize, ...props })\n tagContainer.app = app\n return () => app.destroy()\n }\n }\n tagContainer.plugin.load({ tagList: [tagContainer.tag] })\n const translate = this.meshStyle.translate\n if (translate && tag.position) {\n const position = new THREE.Vector3().fromArray(tag.position)\n const translateVector = new THREE.Vector3().fromArray(translate)\n position.add(translateVector)\n position.y += this.heightOffset\n const tagPosition = position.toArray()\n tagContainer.plugin.changeTagById(tagContainer.tag.id, { position: tagPosition })\n }\n }\n\n /** 开始走点动画 */\n private onWalkAnimationStart = () => {\n this.inWalkAnimation = true\n this.updateVisible()\n }\n\n /** 结束走点动画 */\n private onWalkAnimationEnd = () => {\n this.inWalkAnimation = false\n this.updateVisible()\n }\n\n /** 模型状态变更 */\n private onFiveModeChange = (mode: Mode) => {\n this.modeVisible = this.mode === 'panorama' ? isPanoramaLike(mode) : isModelLike(mode)\n this.updateVisible()\n }\n\n private onFiveModelShownFloorChange = (floor: number | null) => {\n this.floorVisible = floor === null || this.visibleFloorIndexes === null || this.visibleFloorIndexes.includes(floor)\n this.updateVisible()\n }\n\n /** 更新可见性 */\n private updateVisible = () => {\n const visible = (() => {\n if (!this.parent.visible) return false\n if (!this.plugin.state.enabled) return false\n if (!this.plugin.state.visible) return false\n if (this.customVisible !== null) return this.customVisible\n if (this.inWalkAnimation) return true\n return this.modeVisible && this.defaultVisible && this.floorVisible\n })()\n\n this.visible = visible\n\n visible && this.textureHasLoaded ? this.doShow() : this.doHide()\n }\n\n private doShow() {\n if (this.mode === 'model' && !this.flowAnime.isPlaying()) {\n this.flowAnime.play()\n }\n this.five.scene.add(this.group)\n this.startTagContainer?.plugin.show()\n this.endTagContainer?.plugin.show()\n this.five.needsRender = true\n }\n\n private doHide() {\n if (this.mode === 'model') {\n this.flowAnime.stop()\n }\n this.five.scene.remove(this.group)\n this.startTagContainer?.plugin.hide()\n this.endTagContainer?.plugin.hide()\n this.five.needsRender = true\n }\n\n private onFlowAnimeUpdate = (options: { progress: number }) => {\n const { progress } = options\n this.mesh.material.vOffset.value = progress\n this.five.needsRender = true\n }\n\n private logError = (msg: string) => logError('GuideLineModeItem: ', msg)\n\n /** 更新标签字体大小 */\n private updateTagFontSize = () => {\n // 更新开始标签\n if (this.startTagContainer?.app) {\n this.startTagContainer.app.update({ fontSize: this.currentFontSize })\n }\n // 更新结束标签\n if (this.endTagContainer?.app) {\n this.endTagContainer.app.update({ fontSize: this.currentFontSize })\n }\n }\n}\n\nfunction isModelTag(tag: Tag<any, any>): tag is PluginType.ModelGuideLineTag {\n return tag.contentType === 'Custom'\n}\n\nexport { GuideLineModeItem }\n","import type { Five, State } from '@realsee/five-webgpu'\nimport type { BaseOptions } from '../base/BasePlugin'\nimport type { GuideLinePluginExportType } from '../GuideLinePlugin'\nimport * as BasePlugin from '../base/BasePlugin'\nimport type { PluginState, EventMap, MoveEffect } from './typing'\nimport { equal } from '../shared-utils'\nimport type { PartialDeep } from 'type-fest'\nimport objectAssignDeep from 'object-assign-deep'\nimport { FiveUtil } from '../shared-utils/Utils/FiveUtil'\n\nconst PLUGIN_NAME = 'CruisePlugin'\n\nconst PLUGIN = `${PLUGIN_NAME}`\n\nexport const pluginFlag = (name: string) => `${PLUGIN}--${name}`\n\nexport default abstract class CruiseController<PluginData, Config = unknown> extends BasePlugin.Controller<PluginState, EventMap> {\n public state: PluginState = {\n visible: true,\n enabled: true,\n disposed: false,\n playing: false,\n speed: 1,\n }\n\n protected data?: PluginData & { id: string | number }\n\n protected config?: Config\n\n protected pauseDataMap = new Map<\n string | number,\n { fiveState: Partial<State>; id?: string | number; playedProgress: number; duration?: number }\n >()\n\n protected privateState: {\n /**\n * privateState.playing 和 state.playing 的区别:\n * state.playing 先为true,然后才 handleplay,handleplay方法内会检查privateState.playing,如果已经开始(privateState.playing === true),就不执行操作,如果为false,就执行操作\n * 其实就是加了一个不允许重复执行handleplay的逻辑\n */\n playing: boolean\n broke: boolean\n playId?: string\n moveToFirstPanoEffect?: MoveEffect\n moveToFirstPanoDuration?: number\n modeChanging?: boolean\n } = {\n playing: false,\n broke: false,\n modeChanging: false,\n }\n\n protected GuideLine?: GuideLinePluginExportType\n\n public constructor(five: Five, config?: Config) {\n super(five, config)\n this.config = config\n }\n\n /**\n * @description Play | Continue play. if have been paused, continue play from the pause position; if playing, do nothing\n */\n public play(options?: { userAction?: boolean }): void {\n this.setState({ playing: true }, options)\n }\n\n /**\n * @description Pause\n */\n public pause(options?: { userAction?: boolean }) {\n this.setState({ playing: false }, options)\n }\n\n /**\n * @description Show guide line\n */\n public async show(options?: { userAction?: boolean }) {\n this.setState({ visible: true }, options)\n }\n\n /**\n * @description Hide guide line\n */\n public async hide(options?: { userAction?: boolean }) {\n this.setState({ visible: false }, options)\n }\n\n /**\n * @description Enable\n */\n public enable(options?: { userAction?: boolean }) {\n this.setState({ enabled: true }, options)\n }\n\n /**\n * @description Disable\n */\n public disable(options?: { userAction?: boolean }) {\n this.setState({ enabled: false }, options)\n }\n\n /**\n * @description Dispose\n */\n public dispose() {\n if (this.state.disposed) return\n this.setState({ disposed: true })\n }\n\n /**\n * @description Set state\n */\n public setState(state: PartialDeep<PluginState>, options?: BaseOptions & Record<string, any>): void {\n if (this.state.disposed) return this.disposedErrorLog()\n if (!this.state.enabled) {\n // when plugin is disabled, only can change enabled or disposed to true\n if (state.enabled !== true && state.disposed !== true) return this.disableErrorLog()\n }\n const prevState = { ...this.state }\n this.state = objectAssignDeep({}, this.state, state)\n if (state.disposed !== undefined && state.disposed !== prevState.disposed) {\n if (state.disposed) this.handleDispose()\n }\n if (state.visible !== undefined && state.visible !== prevState.visible) {\n this.handleVisible(state.visible, options?.userAction)\n }\n if (state.enabled !== undefined && state.enabled !== prevState.enabled) {\n this.handleEnable(state.enabled, options?.userAction)\n }\n if (state.playing !== undefined && state.playing !== prevState.playing) {\n this.changePlayState(state.playing, options)\n }\n if (state.speed !== undefined && state.speed !== prevState.speed) {\n this.changeSpeed(state.speed)\n }\n\n if (!equal(prevState, this.state, { deep: true })) {\n this.hooks.emit('stateChange', { state: this.state, prevState, userAction: options?.userAction ?? true })\n }\n }\n\n /**\n * @description Clear pause data\n */\n protected clearPauseData() {\n if (this.data?.id) return this.pauseDataMap.delete(this.data?.id)\n }\n\n protected changePlayState(play: boolean, options?: { userAction?: boolean; playFromIndex?: number; playFromId?: string }) {\n this.actionIfStateIsEnabled(() =>\n this.hooks.emit('playStateChange', play ? 'playing' : 'pause', { userAction: options?.userAction ?? true }),\n )\n this.state.playing = play\n play ? this.handlePlay(options) : this.handlePause(options)\n }\n\n protected handleEnable(enabled: boolean, userAction = true) {\n if (enabled) {\n this.GuideLine?.enable()\n this.hooks.emit('enable', { userAction })\n } else {\n this.GuideLine?.disable()\n this.changePlayState(false, { userAction })\n this.hooks.emit('disable', { userAction })\n }\n this.state.enabled = enabled\n }\n\n protected handleVisible(visible: boolean, userAction = true) {\n if (visible) {\n this.GuideLine?.show()\n this.actionIfStateIsEnabled(() => this.hooks.emit('show', { userAction }))\n } else {\n this.GuideLine?.hide()\n this.actionIfStateIsEnabled(() => this.hooks.emit('hide', { userAction }))\n }\n this.state.visible = visible\n }\n\n /**\n * @description: listen interupted by five gesture\n */\n protected addInterruptListener(interrupt: () => void) {\n const wantsChangeModeHandler = () => {\n if (!this.privateState.modeChanging) interrupt()\n }\n\n const handleGesture = (type: string) => {\n if (type !== 'mouseMove') {\n interrupt()\n this.five.off('gesture', handleGesture)\n }\n }\n\n this.five.on('gesture', handleGesture)\n this.five.once('wantsChangeMode', wantsChangeModeHandler)\n return () => {\n this.five.off('gesture', handleGesture)\n this.five.off('wantsChangeMode', wantsChangeModeHandler)\n }\n }\n\n /**\n * @description Get duration by speed\n */\n protected getSpeededDuration(duration: number) {\n return duration / this.state.speed\n }\n\n /**\n * @description Force interupt five updateCamera\n */\n protected forceInteruptUpdateCamera() {\n const longitude = this.five.getCurrentState().longitude + 0.005\n this.five.updateCamera(\n {\n longitude: longitude,\n },\n 0,\n true,\n )\n }\n\n protected getPauseData() {\n if (this.data?.id) return this.pauseDataMap.get(this.data.id)\n }\n\n /**\n * @description Set pause data\n */\n protected setPauseData() {\n const id = this.data?.id\n if (id)\n return this.pauseDataMap.set(id, {\n fiveState: this.five.getCurrentState(),\n playedProgress: this.getProgress(),\n })\n }\n\n /**\n * @description: Restore state that before loaded\n */\n protected clear() {\n this.clearPauseData()\n }\n\n // TODO\n protected handleDispose() {\n this.state.playing = false\n this.clearPauseData()\n this.clear()\n this.GuideLine?.dispose()\n this.GuideLine = undefined\n }\n\n /**\n * @description Action function if plugin is enable\n */\n protected actionIfStateIsEnabled<T = any>(func: () => T, options?: { warnLog?: true }) {\n if (this.state.enabled) return func()\n else {\n if (options?.warnLog) this.disableWarnLog()\n }\n }\n\n protected disposedErrorLog = () => {\n console.error(`${PLUGIN} is disposed`)\n }\n\n protected disableWarnLog = () => {\n console.warn(`${PLUGIN} is disabled`)\n }\n\n protected disableErrorLog = () => {\n console.error(`${PLUGIN} is disabled`)\n }\n\n /**\n * @description Load Data and State\n */\n public abstract load(serverData: unknown, state?: PluginState, userAction?: boolean): Promise<void>\n\n /**\n * @description Play from first keyframe\n */\n public abstract playFromStart(): void\n\n /**\n * @description Play | Continue play. if have been paused, continue play from the pause position; if playing, do nothing\n * @param {number} options.playFromIndex play from keyframes index\n * @param {string} options.playFromId play from keyframes id\n */\n protected abstract handlePlay(options?: {\n userAction?: boolean\n playFromIndex?: number\n playFromId?: string\n notEmitEvent?: true\n }): Promise<string>\n\n /**\n * @description: Change play speed\n */\n protected abstract changeSpeed(speed: number): void\n\n /**\n * @description Get ratate progress\n */\n protected abstract getProgress(): number\n\n /**\n * @description: Pause and record pause state\n */\n protected abstract handlePause(options?: { userAction?: boolean; notEmitEvent?: true }): void\n}\n","import * as THREE from 'three/webgpu'\nimport { vectorToCoordinates } from '../../shared-utils/vectorToCoordinate'\n\n\nexport function getFiveStateOnCurve(\n curve: THREE.Curve<THREE.Vector3>,\n progress: number,\n curveOffset: Partial<{ x: number; y: number; z: number }>,\n) {\n const offset = new THREE.Vector3().fromArray([curveOffset.x ?? 0, curveOffset.y ?? 0, curveOffset.z ?? 0])\n const position = curve.getPointAt(progress).clone().add(offset)\n const tangent = curve.getTangentAt(progress)\n const { longitude, latitude } = vectorToCoordinates(tangent)\n return { offset: position.clone(), longitude, latitude, distance: 0 }\n}\n","import type { Five } from '@realsee/five-webgpu'\nimport CruiseController from './BaseController'\nimport objectAssignDeep from 'object-assign-deep'\nimport type { Config, GuideLineConfig, PluginState } from './typing'\nimport type { PartialDeep } from 'type-fest'\nimport * as THREE from 'three/webgpu'\nimport { uuid } from '../shared-utils'\nimport { getFiveStateOnCurve } from './utils/getFiveStateOnCurve'\nimport { anyPositionToVector3, type AnyPosition } from '../shared-utils/positionToVector3'\nimport GuideLinePlugin from '../GuideLinePlugin'\n\ninterface Data extends GuideLineConfig {\n /**\n * @description: 组成路径的空间坐标点\n */\n path: THREE.CurvePath<THREE.Vector3> | AnyPosition[]\n /**\n * @description: 漫游镜头偏移量,注意会与插件初始化时的 config.offset 叠加\n * @default: { x: 0, y: 0, z: 0 }\n */\n offset?: Partial<{ x: number; y: number; z: number }>\n}\n\nexport interface MoveConfig extends Config {\n /**\n * @description: 漫游时镜头基于路径的偏移量\n * @default: { x: 0, y: 2, z: 0 }\n */\n offset?: Partial<{ x: number; y: number; z: number }>\n /**\n * @description: 滑动屏幕时允许打断漫游\n * @default: true\n */\n allowBroke?: boolean\n}\n\nexport default class MoveController extends CruiseController<Data, MoveConfig> {\n private curve: THREE.Curve<THREE.Vector3>\n private baseCurveOffset: { x: number; y: number; z: number }\n private curveOffset: Partial<{ x: number; y: number; z: number }>\n private playStartedTime = performance.now()\n private duration: number | null\n\n public constructor(five: Five, config?: MoveConfig) {\n super(five, config)\n\n const defaultState: PartialDeep<PluginState> = {\n config: {\n speedConfig: {\n moveSpeed: 2,\n moveSpeedUnit: 'm/s',\n },\n },\n }\n\n const defaultConfig: PartialDeep<MoveConfig> = {\n allowBroke: true,\n }\n\n this.state = objectAssignDeep({}, defaultState, this.state)\n this.config = objectAssignDeep({}, defaultConfig, this.config)\n this.baseCurveOffset = objectAssignDeep({ x: 0, y: 0, z: 0 }, { y: 2 }, this.config?.offset)\n }\n\n public load(data: Data, state?: PartialDeep<PluginState>): Promise<void> {\n // 暂停\n this.handlePause()\n // 清空数据\n this.clear()\n\n this.data = { id: uuid(), ...data }\n\n const curve = (() => {\n if (this.data.path instanceof THREE.Curve) {\n return this.data.path.curves[0]\n } else {\n if (this.data.path.length < 2) return null\n const vectors = this.data.path.map(anyPositionToVector3)\n return new THREE.CatmullRomCurve3(vectors, undefined, 'catmullrom', 0.5)\n }\n })()\n\n if (!curve) return\n\n this.curve = curve\n this.curveOffset = {\n x: this.baseCurveOffset.x + (this.data.offset?.x ?? 0),\n y: this.baseCurveOffset.y + (this.data.offset?.y ?? 0),\n z: this.baseCurveOffset.z + (this.data.offset?.z ?? 0),\n }\n if (!this.curve) {\n throw new Error('curve is not defined')\n }\n const curveLength = this.curve.getLength()\n const baseMoveSpeed = this.state.config.speedConfig.moveSpeedUnit === 'm/ms' ? 1 : 1000\n this.duration = curveLength / (this.state.config.speedConfig.moveSpeed / baseMoveSpeed)\n\n if (Array.isArray(this.data.path)) {\n const points = this.data.path.map(anyPositionToVector3).map((point) => point.toArray())\n // initialize GuideLinePlugin\n if (\n !this.GuideLine &&\n ((this.config?.useGuideLine !== false && data.useGuildLine) || (this.config?.useGuideLine && data.useGuildLine !== false))\n )\n this.GuideLine = GuideLinePlugin(this.five, this.config)\n\n // load GuideLine\n this.GuideLine?.load({\n lines: [\n {\n id: uuid(),\n path: [{ type: 'CatmullRomCurve3', points: points }],\n model_style: { visible: true },\n },\n ],\n })\n }\n\n // initialize plugin state\n if (state) {\n this.setState(state)\n } else {\n // first pause\n this.setState({ playing: false })\n\n // set state\n this.handleVisible(this.state.visible)\n this.handleEnable(this.state.enabled)\n this.changePlayState(this.state.playing)\n this.changeSpeed(this.state.speed)\n }\n\n return Promise.resolve()\n }\n\n public changeSpeed = (speed: number, userAction = true) => {\n this.state.speed = speed\n this.hooks.emit('speedChange', speed, { userAction })\n }\n\n public moveToStart = () => {\n this.five.setState({ ...getFiveStateOnCurve(this.curve, 0, this.curveOffset), mode: 'Model' })\n }\n\n public playFromStart = () => {\n this.clearPauseData()\n this.setState({ playing: true })\n }\n\n protected getDuration = () => {\n return this.getSpeededDuration(this.duration)\n }\n\n protected getProgress = () => {\n const pauseData = this.getPauseData()\n let playedProgress = pauseData?.playedProgress ?? 0\n if (playedProgress < 0 || playedProgress >= 1) {\n playedProgress = 0\n }\n const lastProgress = 1 - playedProgress // 剩余的进度\n\n const duration = this.getDuration()\n const currentTime = performance.now()\n const progress = (currentTime - this.playStartedTime) / duration\n return 1 - lastProgress + progress\n }\n\n protected handlePlay(): Promise<string> {\n\n return new Promise(async (resolve, reject) => {\n this.hooks.emit('play', { userAction: true })\n // 恢复暂停状态\n const pauseData = this.getPauseData()\n let progress = pauseData?.playedProgress ?? 0\n if (progress < 0 || progress >= 1) {\n progress = 0\n }\n const state = getFiveStateOnCurve(this.curve, progress, this.curveOffset)\n\n this.hooks.emit('progressChange', progress)\n this.five.setState({ ...state, mode: 'Model' })\n await this.five.ready()\n\n this.playStartedTime = performance.now()\n\n // 是否允许中断\n if (this.config.allowBroke) {\n const disposer = this.addInterruptListener(() => {\n if (this.state.playing) {\n this.hooks.emit('broke')\n this.handlePause()\n disposer()\n reject(new Error('broke'))\n }\n })\n }\n\n const onRenderFrame = () => {\n const progress = this.getProgress()\n if (progress >= 1) {\n this.five.off('renderFrame', onRenderFrame)\n this.setState({ playing: false }, { userAction: false })\n this.hooks.emit('end')\n this.hooks.emit('progressChange', 1)\n resolve('end')\n } else if (this.state.playing === false) {\n this.five.off('renderFrame', onRenderFrame)\n } else if (progress >= 0) {\n const state = getFiveStateOnCurve(this.curve, progress, this.curveOffset)\n this.hooks.emit('progressChange', progress)\n this.five.setState(state, true)\n }\n }\n\n this.five.on('renderFrame', onRenderFrame)\n })\n }\n\n protected handlePause(options?: { userAction?: boolean }) {\n this.state.playing = false\n this.hooks.emit('pause', { userAction: options?.userAction ?? true })\n this.setPauseData()\n }\n}\n","import type { Five, Mode } from '@realsee/five-webgpu'\nimport type GuideLinePlugin from './Controller'\nimport type * as PluginType from './typing'\nimport { GuideLineModeItem } from './GuideLineModeItem'\nimport type { CruisePluginTypes } from '../CruisePlugin'\nimport { logError } from '../shared-utils/log'\nimport to from '../shared-utils/to'\nimport changeMode from '../shared-utils/five/changeMode'\nimport MoveController from '../CruisePlugin/Move'\nimport WalkController from '../CruisePlugin/Work'\nimport { Subscribe } from '../shared-utils/Subscribe'\n\n/** 路线引导实例。\n * - 路线包括两个部分:全景路线和模型路线。\n * - Five 切换模态时,路线会自动切换。\n * - GuideLineItem P\n */\nclass GuideLineItem {\n public readonly id: string | number\n public readonly renderID?: string\n public readonly isGuideLine = true\n public readonly panoramaItem: GuideLineModeItem\n public readonly modelItem: GuideLineModeItem\n public readonly hooks = new Subscribe<PluginType.GuideLineItemEventMap>()\n public get visible() {\n return this._visible\n }\n private _visible = true\n private plugin: GuideLinePlugin\n private five: Five\n\n public constructor(options: { five: Five; id: string | number; plugin: GuideLinePlugin }) {\n this.id = options.id\n this.five = options.five\n this.plugin = options.plugin\n this.panoramaItem = new GuideLineModeItem(this.five, { mode: 'panorama', plugin: this.plugin, parent: this })\n this.modelItem = new GuideLineModeItem(this.five, { mode: 'model', plugin: this.plugin, parent: this })\n }\n\n public setData(data: PluginType.GuideLineItem) {\n this.setDataByMode('panorama', data)\n this.setDataByMode('model', data)\n }\n\n public setDataByMode(mode: PluginType.GuideLineModeItemMode, data: PluginType.GuideLineItem) {\n const item = mode === 'panorama' ? this.panoramaItem : this.modelItem\n const style = mode === 'panorama' ? data.panorama_style : data.model_style\n const path = data.path\n const geometryStyle: PluginType.GuideLineGeometryStyle = style\n const materialStyle: PluginType.GuideLineMaterialStyle = style\n const meshStyle: PluginType.GuideLineMeshStyle = style\n if (data.pano_group) {\n const skipPanoGroup = mode === 'panorama' && data.panorama_style.skip_group === true\n item.setGeometryByPanoGroup(data.pano_group, { ...data, skipPanoGroup, ...geometryStyle })\n } else if (data.path) {\n item.setGeometryByPath(path, { ...geometryStyle })\n }\n item.name = data.name\n item.setMeshStyle(meshStyle)\n item.setMartial(materialStyle)\n item.setVisibleFloorIndexes(data.visible_floor_indexes ?? null)\n item.setStartTag(style?.start_tag)\n item.setEndTag(style?.end_tag)\n }\n\n public show() {\n this._visible = true\n this.hooks.emit('show', { userAction: true })\n }\n\n public hide() {\n this._visible = false\n this.hooks.emit('hide', { userAction: true })\n }\n\n public dispose() {\n this.panoramaItem.dispose()\n this.modelItem.dispose()\n }\n\n public async walk(options?: CruisePluginTypes.MoveAction) {\n this.hooks.emit('walkStart', { userAction: true })\n if (this.panoramaItem.panoGroup.length) {\n const walkData = { panoIndexList: this.panoramaItem.panoGroup, ...options }\n const [error] = await to(walk(this.five, walkData))\n if (error) return this.logError(error.message)\n } else {\n const walkData = { path: this.panoramaItem.curvePath }\n const [error] = await to(move(this.five, walkData))\n if (error) return this.logError(error.message)\n }\n this.hooks.emit('walkEnded', { userAction: true })\n }\n\n private logError = (msg: string) => logError('GuideLineItem: ', msg)\n}\n\nasync function move(five: Five, data: any) {\n const plugin = new MoveController(five)\n await plugin.load(data)\n plugin.playFromStart()\n}\n\nasync function walk(five: Five, data: CruisePluginTypes.MoveWithPanoIndexAction) {\n if (data.panoIndexList.length === 0) return\n const fiveCurrentState = five.getCurrentState()\n if (fiveCurrentState.mode !== 'Panorama') {\n await changeMode(five, ['Panorama', { longitude: fiveCurrentState.longitude, latitude: 0, panoIndex: data.panoIndexList[0] }])\n }\n const plugin = new WalkController(five)\n await plugin.load(data)\n await new Promise<void>((resolve, reject) => {\n const fiveCurrentState = five.getCurrentState()\n let panoIndexList = data.panoIndexList.slice()\n if (fiveCurrentState.panoIndex === panoIndexList[0]) onFivePanoArrived(fiveCurrentState.panoIndex)\n\n plugin.playFromStart()\n\n function onFiveModeChange(mode: Mode) {\n if (mode !== 'Panorama') return onReject(new Error('mode not match'))\n }\n\n function onFivePanoArrived(panoIndex: number) {\n const wantedPanoIndex = panoIndexList[0]\n panoIndexList = panoIndexList.slice(1)\n if (panoIndex !== wantedPanoIndex)\n return onReject(new Error('panoIndex not match, wanted: ' + wantedPanoIndex + ', got: ' + panoIndex))\n if (panoIndexList.length === 0) return onResolve()\n }\n\n function removeListeners() {\n five.off('modeChange', onFiveModeChange)\n five.off('panoArrived', onFivePanoArrived)\n }\n\n function onReject(error: Error) {\n removeListeners()\n reject(error)\n }\n\n function onResolve() {\n removeListeners()\n resolve()\n }\n\n five.on('modeChange', onFiveModeChange)\n five.on('panoArrived', onFivePanoArrived)\n })\n}\n\nexport { GuideLineItem }\n","import * as BasePluginWithData from '../base/BasePluginWithData'\nimport type { Five } from '@realsee/five-webgpu'\nimport type { EventMap, PluginData, PluginServerData, PluginState } from './typing'\nimport type * as PluginType from './typing'\nimport { equal, replaceStaticPrefix } from '../shared-utils'\nimport type { Config as BaseConfig } from '../base/BasePlugin'\nimport { GuideLineItem } from './GuideLineItem'\nimport CruisePluginController from '../CruisePlugin/Work'\nimport objectAssignDeep from 'object-assign-deep'\nimport * as THREE from 'three/webgpu'\nimport type { GuideLineTagContainer } from './GuideLineModeItem'\nimport { uuid } from '../shared-utils'\nimport { waitFiveModelLoaded } from '../shared-utils/five/fiveModelLoad'\nimport { GUIDELINE_DEFAULT_ARROW_TEXTURE, GUIDELINE_WHITE_ARROW_TEXTURE } from '../shared-utils'\n\nconst PLUGIN_NAME = 'GuideLinePlugin'\n\nconst PLUGIN = `${PLUGIN_NAME}`\n\nexport const pluginFlag = (name: string) => `${PLUGIN}--${name}`\n\ntype Config = BaseConfig & {\n /**\n * @description 格式化距离函数,用于将米转换为显示文本(包含单位)\n * @param distanceInMeter 距离(单位:米)\n * @returns 格式化后的距离字符串,例如 \"10m\" 或 \"32'10\"\"\n */\n formatDistance?: (distanceInMeter: number) => string\n}\n\nexport default class Controller extends BasePluginWithData.Controller<PluginState, EventMap, PluginServerData, PluginData> {\n public readonly name = PLUGIN_NAME\n public readonly cruisePlugin: CruisePluginController\n\n /** GuideLineItem 索引 */\n public readonly itemMap = new Map<string | number, GuideLineItem>()\n public get config() {\n return this._config\n }\n\n public state = {\n visible: false,\n enabled: true,\n }\n\n protected data?: PluginData\n\n /** 当新增一根线时,整体高度的偏移值 */\n private heightOffset = 0\n\n public get disposed() {\n return this._disposed\n }\n\n private _config: Config\n\n private _disposed = false\n private loadGeneration = 0\n\n public constructor(five: Five, config?: Config) {\n super(five, config)\n this._config = config ?? {}\n this.cruisePlugin = new CruisePluginController(five)\n }\n\n public async load(serverData: PluginServerData | PluginData, state?: PluginState, userAction = true): Promise<void> {\n if (this.disposed) return\n const generation = ++this.loadGeneration\n const prevData = this.data ? JSON.parse(JSON.stringify(this.data)) : undefined\n\n // format server data to plugin data\n const data = await this.formatData(serverData)\n if (this.disposed || generation !== this.loadGeneration) return\n\n const config = data.config\n const isV1Data = !data.lines && data.routes\n\n // 转换配置中的箭头贴图 URL\n const arrowTextureUrl = config?.arrowTextureUrl ?? replaceStaticPrefix(this.staticPrefix, GUIDELINE_WHITE_ARROW_TEXTURE)\n\n const baseData: Omit<PluginType.GuideLineItem, 'id'> = {\n ...config,\n model_style: {\n texture: { url: arrowTextureUrl },\n },\n panorama_style: {\n visible: isV1Data ? true : false,\n unit_length: config?.unitHeight ?? 0.4,\n width: config?.unitWidth ?? 0.6,\n texture: { url: arrowTextureUrl },\n },\n }\n\n const v1Data =\n data.routes?.map((item) => objectAssignDeep({}, baseData, { id: item.id ?? uuid(), pano_group: item.panoIndexList })) ?? []\n const v2Data = data.lines?.map((item) => objectAssignDeep({}, baseData, item)) ?? []\n const combineData: PluginType.GuideLineItem[] = [...v1Data, ...v2Data]\n\n // wait for five model loaded\n await waitFiveModelLoaded(this.five)\n\n if (this.disposed || generation !== this.loadGeneration) return\n this.clearItems()\n this.data = data\n this.hooks.emit('dataChange', data, prevData)\n combineData.forEach((item) => {\n this.addGuideLineItem(item)\n })\n this.updateTagsEnable()\n\n // set state\n this.handleVisible(this.state.visible)\n this.handleEnable(this.state.enabled)\n\n // initialize plugin state\n if (state) this.setState(state, { userAction })\n\n this.hooks.emit('dataLoaded', data)\n console.debug(`${PLUGIN} loaded`, data)\n }\n\n public async formatData(serverData: any): Promise<PluginType.PluginData> {\n const dataWithoutVersion = this.getDataWithoutVersion(serverData)\n return dataWithoutVersion\n }\n\n /** 展示插件 */\n public async show(options?: { userAction?: boolean }) {\n this.setState({ visible: true }, options)\n }\n\n /** 隐藏插件 */\n public async hide(options?: { userAction?: boolean }) {\n this.setState({ visible: false }, options)\n }\n\n /** 开启插件 */\n public enable(options?: { userAction?: boolean }) {\n this.setState({ enabled: true }, options)\n }\n\n /** 关闭插件 */\n public disable(options?: { userAction?: boolean }) {\n this.setState({ enabled: false }, options)\n }\n\n /** 销毁插件 */\n public dispose() {\n if (this.disposed) return\n this._disposed = true\n this.clear()\n this.cruisePlugin.dispose()\n this.data = undefined\n this.hooks.emit('dispose')\n }\n\n public setState(state: Partial<PluginState>, options?: { userAction?: boolean }) {\n if (this.disposed) return this.disposedErrorLog()\n const prevState = { ...this.state }\n this.state = { ...this.state, ...state }\n if (state.visible !== undefined && state.visible !== prevState.visible) {\n this.handleVisible(state.visible, options?.userAction)\n }\n if (state.enabled !== undefined && state.enabled !== prevState.enabled) {\n this.handleEnable(state.enabled, options?.userAction)\n }\n\n if (!equal(prevState, this.state, { deep: true })) {\n this.hooks.emit('stateChange', { state: this.state, prevState, userAction: options?.userAction ?? true })\n this.five.needsRender = true\n }\n }\n\n /** 添加一个 GuideLineItem */\n public addGuideLineItem(data?: PluginType.GuideLineItem): GuideLineItem {\n const id = data.render_id || data.id\n // remove prev item\n const prevItem = this.itemMap.get(id)\n if (prevItem) this.removeGuideLineItem(prevItem)\n\n const newItem = new GuideLineItem({ five: this.five, id, plugin: this })\n this.itemMap.set(id, newItem)\n if (data) {\n newItem.setData(this.processItemUrls(data))\n }\n // set height offset\n this.heightOffset += 0.0001\n newItem.modelItem.setHeightOffset(this.heightOffset)\n newItem.panoramaItem.setHeightOffset(this.heightOffset)\n\n return newItem\n }\n\n private processItemUrls(item: PluginType.GuideLineItem): PluginType.GuideLineItem {\n const processedItem = { ...item }\n\n // 默认贴图URL\n const defaultTextureUrl = GUIDELINE_DEFAULT_ARROW_TEXTURE\n\n // 处理panorama_style中的贴图URL\n if (processedItem.panorama_style) {\n const textureUrl = processedItem.panorama_style.texture?.url ?? defaultTextureUrl\n processedItem.panorama_style = {\n ...processedItem.panorama_style,\n texture: {\n ...processedItem.panorama_style.texture,\n url: replaceStaticPrefix(this.staticPrefix, textureUrl),\n },\n }\n }\n\n // 处理model_style中的贴图URL\n if (processedItem.model_style) {\n const textureUrl = processedItem.model_style.texture?.url ?? defaultTextureUrl\n processedItem.model_style = {\n ...processedItem.model_style,\n texture: {\n ...processedItem.model_style.texture,\n url: replaceStaticPrefix(this.staticPrefix, textureUrl),\n },\n }\n }\n\n return processedItem\n }\n\n /** 获取 Plugin 内的 GuideLineItem */\n public getGuideLineItemByID(id: string | number) {\n return this.itemMap.get(id)\n }\n\n /** 移除一个 GuideLineItem */\n public removeGuideLineItem(item: GuideLineItem) {\n this.itemMap.delete(item.id)\n\n item.panoramaItem.dispose()\n item.modelItem.dispose()\n }\n\n /**\n * 动态更新距离格式化函数,立即刷新所有路线标签的距离显示。\n * 不传参时恢复为默认格式(i18n('全程') + 距离 + i18n('米'))。\n * @param fn 格式化函数,输入米数,返回带单位的完整字符串\n * @example\n * // 室内英制:英尺 + 英寸(如 \"5'10\"\")\n * plugin.setDistanceFormatter((m) => {\n * const totalInches = Math.round(m * 39.3701)\n * const feet = Math.floor(totalInches / 12)\n * const inches = totalInches % 12\n * return `${feet}'${inches}\"`\n * })\n * // 室外英制:英里(如 \"1.24 mi\")\n * plugin.setDistanceFormatter((m) => `${(m * 0.000621371).toFixed(2)} mi`)\n * // 自动切换:近距离用英尺,远距离用英里\n * plugin.setDistanceFormatter((m) => {\n * if (m < 300) return `${Math.round(m * 3.28084)} ft`\n * return `${(m * 0.000621371).toFixed(2)} mi`\n * })\n * // 恢复默认(i18n '米')\n * plugin.setDistanceFormatter()\n */\n public setDistanceFormatter(fn?: (distanceInMeter: number) => string): void {\n this._config.formatDistance = fn\n this.updateTagDistances()\n }\n\n /** 更新所有 tag 的距离显示(当 formatDistance 函数改变时调用) */\n private updateTagDistances() {\n this.itemMap.forEach((item) => {\n item.panoramaItem.updateTagDistance()\n item.modelItem.updateTagDistance()\n })\n }\n\n /** 全量更新 tag */\n public updateTagsEnable() {\n const enabledTagContainers: GuideLineTagContainer[] = []\n\n function isNumberArray(value: any): value is number[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'number')\n }\n\n function isNear(position1: number[], position2: number[]) {\n return new THREE.Vector3().fromArray(position1).distanceTo(new THREE.Vector3().fromArray(position2)) < 0.01\n }\n\n function getTagEnable(tagContainer: GuideLineTagContainer) {\n const position = tagContainer?.tag?.position\n if (!isNumberArray(position)) return false\n\n return enabledTagContainers.every((enabledTagContainer) => {\n if (!isNumberArray(enabledTagContainer.tag?.position)) return true\n if (isNear(position, enabledTagContainer.tag.position)) return false\n return true\n })\n }\n\n this.itemMap.forEach((item) => {\n const startTagContainer = item.modelItem.startTagContainer\n const endTagContainer = item.modelItem.endTagContainer\n\n if (!startTagContainer && !endTagContainer) return\n\n const startTagEnable = getTagEnable(startTagContainer)\n if (startTagEnable && startTagContainer) enabledTagContainers.push(startTagContainer)\n startTagContainer?.plugin.setState({ enabled: startTagEnable }, {})\n\n const endTagEnable = getTagEnable(endTagContainer)\n if (endTagEnable && endTagContainer) enabledTagContainers.push(endTagContainer)\n endTagContainer?.plugin.setState({ enabled: endTagEnable }, {})\n })\n }\n\n /** 清空所有 GuideLineItem */\n public clear() {\n this.loadGeneration += 1\n this.clearItems()\n }\n\n private clearItems() {\n this.heightOffset = 0\n this.itemMap.forEach((item) => {\n this.removeGuideLineItem(item)\n })\n }\n\n private handleEnable(enabled: boolean, userAction = true): void {\n this.hooks.emit(enabled ? 'enable' : 'disable', { userAction })\n }\n\n private handleVisible(visible: boolean, userAction = true): void {\n if (!this.state.enabled) return\n this.hooks.emit(visible ? 'show' : 'hide', { userAction })\n }\n\n private disposedErrorLog = () => {\n console.error(`${PLUGIN} is disposed`)\n }\n\n private getDataWithoutVersion(data: any) {\n if (typeof data === 'object' && data !== null && data.data) {\n return data.data as PluginData\n }\n return data\n }\n}\n","import type { Five } from '@realsee/five-webgpu'\nimport Controller from './Controller'\nimport type * as GuideLinePluginType from './typing'\nimport * as GuideLineItem from './GuideLineItem'\nimport * as GuideLineModeItem from './GuideLineModeItem'\n\nexport const GuideLinePlugin = (five: Five, config?: ConstructorParameters<typeof Controller>[1]) => new Controller(five, config)\n\nexport type { GuideLinePluginExportType } from './typing'\nexport type { GuideLinePluginType }\n\nexport default GuideLinePlugin\nexport { GuideLineItem, GuideLineModeItem }\n","import * as THREE from 'three/webgpu'\n\n/** 坐标转换成单位向量 */\nfunction coordinatesToVector(coordinates: { longitude: number; latitude: number }): THREE.Vector3 {\n const distance = Math.abs(Math.cos(coordinates.latitude))\n return new THREE.Vector3(\n /* x */ -Math.sin(coordinates.longitude) * distance,\n /* y */ -Math.sin(coordinates.latitude),\n /* z */ -Math.cos(coordinates.longitude) * distance,\n )\n}\n\nexport { coordinatesToVector }\n","import { coordinatesToVector } from './coordinatesToVector'\n\n/**\n * @description: 获取coordinates间的夹角(两个方向向量之间的最小夹角)\n * @return {number} 夹角角度(0 到 π)\n */\nfunction coordinatesAngle(\n coordinates1: { longitude: number; latitude: number },\n coordinates2: { longitude: number; latitude: number },\n): number {\n const vector1 = coordinatesToVector(coordinates1)\n const vector2 = coordinatesToVector(coordinates2)\n const angle = vector1.angleTo(vector2)\n return angle\n}\n\n/**\n * @description: 获取coordinates间的实际旋转角度(基于 longitude/latitude 差值)\n * @param coordinates1 起始坐标\n * @param coordinates2 目标坐标\n * @param signed 是否返回有符号角度(默认 false)\n * - true: 返回有符号角度(以主要旋转方向的符号为准)\n * - false: 返回无符号角度(绝对值)\n * @return {number} 旋转角度(弧度),可以超过 π\n */\nfunction coordinatesRotation(\n coordinates1: { longitude: number; latitude: number },\n coordinates2: { longitude: number; latitude: number },\n signed: boolean = false,\n): number {\n // 直接计算 longitude 和 latitude 的差值\n const deltaLon = coordinates2.longitude - coordinates1.longitude\n const deltaLat = coordinates2.latitude - coordinates1.latitude\n\n // 使用欧几里得距离计算总旋转角度\n const angle = Math.sqrt(deltaLon * deltaLon + deltaLat * deltaLat)\n\n if (!signed) {\n return angle\n }\n\n // 对于有符号角度,返回主要旋转方向\n if (Math.abs(deltaLon) >= Math.abs(deltaLat)) {\n return deltaLon >= 0 ? angle : -angle\n } else {\n return deltaLat >= 0 ? angle : -angle\n }\n}\n\nexport { coordinatesAngle, coordinatesRotation }\n","export const safeCall = async (fn: () => Promise<any>) => {\n try {\n fn().then(() => {},() => {}).catch(() => {})\n } catch (e) {}\n}\n","import type { Five } from '@realsee/five-webgpu'\n\nexport async function waitFiveLoaded(five: Five) {\n return new Promise<void>((resolve) => {\n if (five.work) {\n resolve()\n return\n }\n five.once('loaded', () => resolve())\n })\n}\n","import type { PlaybackController, PlaybackSession } from '../shared-utils/playback'\nimport type { Five, Pose, State } from '@realsee/five-webgpu'\nimport { GuideLinePlugin } from '../GuideLinePlugin'\nimport uuid from '../shared-utils/uuid'\nimport type { PluginState, PluginServerData, PluginData, CruiseData, CruiseKeyframe, MoveEffect, Config } from './typing'\nimport { coordinatesAngle, coordinatesRotation } from './utils/coordinatesAngle'\nimport { safeCall } from './utils/safeCall'\nimport * as THREE from 'three/webgpu'\nimport { sleep } from './utils/sleep'\nimport { waitFiveLoaded } from '../shared-utils/five/fiveLoaded'\nimport { vectorToCoordinates } from '../shared-utils/vectorToCoordinate'\nimport CruiseController from './BaseController'\nimport { notNil } from '../shared-utils'\n\nexport default class WalkController extends CruiseController<PluginData, Config> {\n private playbackController?: PlaybackController\n private session?: PlaybackSession\n private playbackWorkCode?: string\n private pendingKeyframes = new Set<() => void>()\n private cancelAudio?: () => void\n private pendingPanoMove?: {\n workCode: string\n panoIndex: number\n playId?: string\n session?: PlaybackSession\n promise: Promise<void>\n }\n public state: PluginState = {\n visible: true,\n enabled: true,\n disposed: false,\n playing: false,\n speed: 1,\n config: {\n speedConfig: {\n rotateSpeed: 0.001,\n rotateSpeedUnit: 'rad/ms',\n moveSpeed: 0.002,\n moveSpeedUnit: 'm/ms',\n },\n },\n }\n\n protected privateState: {\n /**\n * privateState.playing 和 state.playing 的区别:\n * state.playing 先为true,然后才 handleplay,handleplay方法内会检查privateState.playing,如果已经开始(privateState.playing === true),就不执行操作,如果为false,就执行操作\n * 其实就是加了一个不允许重复执行handleplay的逻辑\n */\n playing: boolean\n currentPlayKeyframe: {\n keyframe: CruiseKeyframe\n originDuration?: number\n } | null\n currentPlayQueue: Promise<any>[]\n broke: boolean\n playId?: string\n moveToFirstPanoEffect?: MoveEffect\n moveToFirstPanoDuration?: number\n modeChanging?: boolean\n audio?: HTMLAudioElement\n audioCache?: Map<string, HTMLAudioElement>\n } = {\n playing: false,\n currentPlayQueue: [],\n currentPlayKeyframe: null,\n broke: false,\n modeChanging: false,\n }\n\n public constructor(five: Five, config?: Config) {\n super(five, config)\n this.playbackController = config?.mediaManager?.createController({ label: 'cruise', onCancel: () => this.handlePause({ userAction: false }, true) })\n this.config = config\n }\n\n protected handleDispose() {\n this.handlePause({ userAction: false })\n this.playbackController?.dispose()\n super.handleDispose()\n }\n\n protected onWorkCodeChange() {\n if (this.playbackWorkCode !== undefined && this.playbackWorkCode !== this.workUtil.workCode) {\n this.handlePause({ userAction: false })\n }\n }\n\n /**\n * @description Load Data and State\n */\n public async load(serverData: PluginServerData | PluginServerData['data'], state?: PluginState, userAction?: boolean): Promise<void> {\n this.handlePause({ userAction: false })\n this.clear()\n\n // copy this.data\n const prevData = this.data ? JSON.parse(JSON.stringify(this.data)) : undefined\n\n // format server data to plugin data\n const data = await this.formatData(serverData)\n this.data = { id: data.keyframesId, ...data }\n this.hooks.emit('dataChange', data, prevData)\n\n let guideLinePanoIndex: number[][] = []\n let tempFloorIndex: number | undefined\n // filter panoIndex list Data\n const hasPanoIndexKeyframes = this.data.keyframes.filter((keyframe) => keyframe.data.panoIndex !== undefined)\n hasPanoIndexKeyframes\n .filter((keyframe, index) => keyframe.data.panoIndex !== hasPanoIndexKeyframes[index - 1]?.data.panoIndex) // filter repeat panoIndex\n .map((keyframe) => keyframe.data.panoIndex!)\n .forEach((panoIndex) => {\n const floorIndex = this.workUtil.getObserver(panoIndex)?.floorIndex\n if (floorIndex === undefined) return\n if (tempFloorIndex === floorIndex) {\n const index = guideLinePanoIndex.length - 1\n guideLinePanoIndex[index] = [...(guideLinePanoIndex[index] ?? []), panoIndex]\n } else {\n tempFloorIndex = floorIndex\n const index = guideLinePanoIndex.length\n guideLinePanoIndex[index] = [panoIndex]\n }\n })\n\n // initialize GuideLinePlugin\n if (!this.GuideLine && this.config?.useGuideLine !== false && data.useGuildLine !== false)\n this.GuideLine = GuideLinePlugin(this.five, this.config)\n\n // load GuideLine\n this.GuideLine?.load({ routes: guideLinePanoIndex.map((route) => ({ panoIndexList: route })), config: data.guildPluginOptions })\n\n // initialize plugin state\n if (state) {\n this.setState(state, { userAction })\n } else {\n // first pause\n this.setState({ playing: false }, { userAction: false })\n\n // set state\n this.handleVisible(this.state.visible)\n this.handleEnable(this.state.enabled)\n this.changePlayState(this.state.playing, { userAction: false })\n this.changeSpeed(this.state.speed)\n }\n\n this.clearPauseData()\n\n // load end\n console.debug(`WORKPLUGIN loaded`, data)\n this.hooks.emit('dataLoaded', data)\n }\n\n /**\n * @description If playing, first pause, then play from keyframes index/id\n * @param {number} options.index play from keyframes index\n * @param {string} options.id play from keyframes id\n */\n public playFrom(options: { userAction?: boolean; index?: number; id?: string }) {\n const { index, id, userAction } = options\n if (this.state.playing) this.setState({ playing: false }, { userAction })\n this.setState({ playing: true }, { userAction, playFromIndex: index, playFromId: id })\n }\n\n /**\n * @description Play from first keyframe\n */\n public playFromStart(options?: { userAction?: boolean }) {\n return this.playFrom({ ...options, index: 0 })\n }\n\n /**\n * @description Format data\n */\n protected async formatData(serverData: PluginServerData | PluginServerData['data']): Promise<PluginData> {\n if (!this.five.work) await waitFiveLoaded(this.five)\n\n const data = (() => {\n const _serverData = serverData as any\n if (typeof _serverData === 'object' && _serverData !== null && notNil(_serverData.version) && _serverData.data) {\n return _serverData.data as PluginServerData['data']\n }\n return _serverData as PluginServerData['data']\n })()\n if (data.keyframes) {\n return {\n keyframesId: uuid(),\n keyframes: data.keyframes.map((keyframe, index) => {\n const nextKeyframe = data.keyframes[index + 1]\n const stay = (() => {\n if (!nextKeyframe) return 0\n if (nextKeyframe.start === undefined || keyframe.end === undefined) return 0\n return nextKeyframe.start - keyframe.end\n })()\n return { id: keyframe.uuid ?? uuid(), moveIndex: index, stay, index, ...keyframe, guildPluginOptions: data.guildPluginOptions }\n }),\n }\n } else if (data.panoIndexList) {\n let keyframes: Omit<CruiseKeyframe, 'index' | 'id'>[] = []\n const { moveEffect, moveToFirstPanoEffect, moveToFirstPanoDuration } = data\n this.privateState.moveToFirstPanoEffect = moveToFirstPanoEffect\n this.privateState.moveToFirstPanoDuration = moveToFirstPanoDuration\n data.panoIndexList\n // .filter((panoIndex, index) => panoIndex !== data.panoIndexList[index - 1]) // remove the repeat panoIndex\n .forEach((panoIndex, index) => {\n const lookatNextPanoIndex = (() => {\n const nextPanoIndex = data.panoIndexList.slice(index).find((p) => p !== panoIndex) // find next different panoIndex\n if (nextPanoIndex === undefined) return\n const vectorFrom = this.workUtil.getObserverPosition(panoIndex)\n const vectorTo = this.workUtil.getObserverPosition(nextPanoIndex)\n if (!vectorTo || !vectorFrom) return\n // if panoIndex and next panoIndex isn't in same floor, return\n if (this.workUtil.getObserver(panoIndex)?.floorIndex !== this.workUtil.getObserver(nextPanoIndex)?.floorIndex) return\n const vector = new THREE.Vector3().subVectors(vectorTo, vectorFrom)\n return vectorToCoordinates(vector.normalize())\n })()\n if (data.moveType === undefined || data.moveType === 'justMove') {\n // move to panoIndex, latitude, longitude\n keyframes.push({\n moveIndex: index,\n stay: data.stay,\n data: { effect: 'Move', panoIndex, moveEffect, ...(lookatNextPanoIndex ?? {}) },\n })\n } else if (data.moveType === 'moveAndRotate') {\n // move to panoIndex, then rotate to latitude and longitude\n keyframes.push({ moveIndex: index, stay: data.stay, data: { effect: 'Move', panoIndex, moveEffect } })\n if (lookatNextPanoIndex)\n keyframes.push({ moveIndex: index, stay: data.stay, data: { effect: 'Rotate', panoIndex, ...lookatNextPanoIndex } })\n }\n })\n return {\n keyframesId: uuid(),\n keyframes: keyframes.map((keyframe, index) => ({ id: uuid(), index, ...keyframe })),\n guildPluginOptions: data.guildPluginOptions,\n useGuildLine: data.useGuildLine,\n }\n } else {\n throw new Error('format error: data no keyframes or no panoIndexList')\n }\n }\n\n /**\n * @description Play | Continue play. if have been paused, continue play from the pause position; if playing, do nothing\n * @param {number} options.playFromIndex play from keyframes index\n * @param {string} options.playFromId play from keyframes id\n */\n\n protected async handlePlay(options?: { userAction?: boolean; playFromIndex?: number; playFromId?: string; notEmitEvent?: true }) {\n const { data, state, privateState, hooks } = this\n\n // check whether keyframes can be played\n if (privateState.playing) return\n if (!data?.keyframes || data?.keyframes.length === 0) return\n\n const hasAudio = data.keyframes.some((keyframe) => !!keyframe.data.audio?.url)\n const session = this.playbackController?.begin({ userAction: options?.userAction === true, audible: hasAudio })\n if (this.playbackController && !session) { state.playing = false; return }\n this.session = session\n this.playbackWorkCode = this.workUtil.workCode\n\n // set current play id\n const currentPlayId = uuid()\n // if handlePlay function is called again before play end, currentPlayId isn't equal to privateState.playId\n privateState.playId = currentPlayId\n\n try {\n // A selected observer may start with Rotate + audio on the same panorama.\n // Only continuation frames without a new audio track resume the paused one.\n if (privateState.audio && privateState.audio.paused) {\n const pauseData = this.getPauseData()\n const target = options?.playFromIndex !== undefined\n ? data.keyframes[options.playFromIndex]\n : options?.playFromId !== undefined\n ? data.keyframes.find(keyframe => keyframe.id === options.playFromId)\n : data.keyframes.find(keyframe => keyframe.id === pauseData?.id)\n const selectedFrame = options?.playFromIndex !== undefined || options?.playFromId !== undefined\n if (target?.data.effect === 'Move' || (selectedFrame && target?.data.audio)) {\n this.cancelAudio?.()\n privateState.audio.pause()\n privateState.audio.currentTime = 0\n privateState.audio = undefined\n } else {\n await this.playAudio()\n if (session?.signal.aborted || currentPlayId !== privateState.playId) return\n }\n }\n // set state\n privateState.playing = true\n privateState.broke = false\n\n const keyframes = data.keyframes\n const pauseData = this.getPauseData()\n\n if (options?.notEmitEvent !== true) {\n hooks.emit('play', { userAction: options?.userAction ?? true })\n }\n\n let firstKeyframeWasPlayed = false\n\n const getPlayFromIndex = async () => {\n // play from index\n if (options?.playFromIndex !== undefined) return options.playFromIndex\n // play from id\n else if (options?.playFromId !== undefined) return this.data?.keyframes.findIndex((keyframe) => keyframe.id === options.playFromId)\n // play from pause position\n else if (pauseData?.id) {\n const pausedKeyframe = this.data?.keyframes.find((keyframe) => keyframe.id === pauseData.id)\n // restore paused state\n if (pauseData?.fiveState)\n await this.move(pauseData.fiveState, {\n moveEffect: privateState.moveToFirstPanoEffect,\n duration: privateState.moveToFirstPanoDuration,\n })\n if (pausedKeyframe) {\n if (pausedKeyframe.data.effect === 'Move') return pausedKeyframe.index\n else if (pausedKeyframe.data.effect === 'Rotate') {\n const duration = pauseData.duration !== undefined ? pauseData.duration * (1 - pauseData.playedProgress) : undefined\n await this.playKeyframe(pausedKeyframe, { duration })\n firstKeyframeWasPlayed = true\n // playFromIndex += 1 cause played last part of paused keyframe\n return pausedKeyframe.index + 1\n }\n }\n }\n }\n\n const playFromIndex = await getPlayFromIndex()\n if (currentPlayId !== privateState.playId || session?.signal.aborted) return\n\n // 如果是用户操作,在用户手势上下文中预加载所有需要的音频对象\n // 关键:必须在同步代码中创建 Audio 对象,而不是在异步操作之后\n const isUserAction = options?.userAction === true\n if (isUserAction) {\n // 遍历所有 keyframes,预加载所有 Move 类型的音频\n if (!this.privateState.audioCache) {\n this.privateState.audioCache = new Map()\n }\n for (let i = playFromIndex; i < keyframes.length; i++) {\n const keyframe = keyframes[i]\n if (keyframe?.data?.audio && !this.privateState.audioCache.has(keyframe.data.audio.url)) {\n // 在用户手势上下文中同步创建 Audio 对象\n const audio = new Audio(keyframe.data.audio.url)\n audio.preload = 'auto'\n // 存储音频对象,后续复用(使用 URL 作为 key)\n this.privateState.audioCache.set(keyframe.data.audio.url, audio)\n }\n }\n }\n\n this.clearPauseData()\n\n // play keyframes\n for (const keyframe of keyframes) {\n if (privateState.broke || !state.playing || !privateState.playing) return\n if (currentPlayId !== privateState.playId) return\n // jump to start keyframe\n if (playFromIndex !== undefined && keyframe.index < playFromIndex) continue\n // play single keyframe\n try {\n\n hooks.emit('playIndexChange', keyframe.index, keyframe)\n await this.playKeyframe(keyframe, {\n moveEffect: firstKeyframeWasPlayed === false ? privateState.moveToFirstPanoEffect : undefined,\n duration:\n firstKeyframeWasPlayed === false && typeof privateState.moveToFirstPanoDuration === 'number'\n ? privateState.moveToFirstPanoDuration\n : undefined,\n })\n if (keyframe.stay) await sleep(keyframe.stay)\n if (firstKeyframeWasPlayed === false) firstKeyframeWasPlayed = true\n } catch (error) {\n if (currentPlayId !== privateState.playId) return Promise.resolve('broke')\n throw error\n }\n }\n if (state.playing && currentPlayId === privateState.playId) {\n this.setState({ playing: false }, { userAction: false })\n this.session?.finish()\n this.session = undefined\n hooks.emit('end')\n this.clearPauseData()\n }\n } catch (error) {\n this.failPlayback(error, currentPlayId, session)\n }\n }\n\n private failPlayback(error: unknown, playId: string, session?: PlaybackSession) {\n if (this.state.disposed || playId !== this.privateState.playId || session?.signal.aborted) return\n this.handlePause({ userAction: false })\n if (this.state.disposed || this.state.playing) return\n this.hooks.emit('error', error instanceof Error || error instanceof DOMException ? error : new Error(String(error)))\n }\n\n /**\n * @description: Pause and record pause state\n */\n protected handlePause(options?: { userAction?: boolean; notEmitEvent?: true }, fromManager = false) {\n const { state, privateState, hooks } = this\n const wasPlaying = privateState.playing\n privateState.playing = false\n this.session = undefined\n if (!fromManager) this.playbackController?.cancel()\n privateState.playId = uuid()\n this.cancelPendingKeyframes()\n this.cancelAudio?.()\n state.playing = false\n // A pending native play may fail before privateState.playing becomes true.\n privateState.audio?.pause()\n if (!wasPlaying) return\n if (options?.userAction !== false) this.setPauseData()\n if (!privateState.broke) this.forceInteruptUpdateCamera()\n\n if (options?.notEmitEvent !== true) {\n hooks.emit('pause', { userAction: options?.userAction ?? true })\n }\n }\n\n /**\n * @description: Change play speed\n */\n protected changeSpeed(speed: number, userAction = true) {\n const { state, privateState, hooks } = this\n const { currentPlayKeyframe } = privateState\n hooks.emit('speedChange', speed, { userAction })\n\n if (state.playing && currentPlayKeyframe) {\n try {\n const duration =\n currentPlayKeyframe.originDuration !== undefined ? currentPlayKeyframe.originDuration * (1 - this.getProgress()) : undefined\n\n // this.playFeyframe(currentPlayKeyframe.keyframe, { duration })\n // 避免 promise 的互相依赖导致的死锁,手动抄一下 playKeyframe 的逻辑\n const keyframe = currentPlayKeyframe.keyframe\n if (this.privateState.currentPlayKeyframe?.keyframe.id !== keyframe.id) this.privateState.currentPlayKeyframe = { keyframe }\n this.enqueueKeyframe(keyframe, { duration })\n } catch (e) {\n console.error(e)\n }\n }\n }\n\n /**\n * @description Get ratate progress\n */\n protected getProgress() {\n return (this.five as any).controller.cameraMotion.progress\n }\n\n /**\n * @description Set pause data\n */\n protected setPauseData() {\n if (this.data?.id)\n return this.pauseDataMap.set(this.data.id, {\n id: this.privateState.currentPlayKeyframe?.keyframe.id,\n fiveState: this.five.getCurrentState(),\n duration: this.privateState.currentPlayKeyframe?.originDuration,\n playedProgress: this.getProgress(),\n })\n }\n\n /**\n * @description: Restore state that before loaded\n */\n protected clear() {\n this.privateState.playId = uuid()\n this.cancelPendingKeyframes()\n this.clearPauseData()\n this.privateState.currentPlayKeyframe = null\n }\n\n /**\n * @description Play single keyframe\n */\n private async playKeyframe(keyframe: CruiseKeyframe, params?: { duration?: number; moveEffect?: MoveEffect }) {\n if (this.privateState.currentPlayKeyframe?.keyframe.id !== keyframe.id) this.privateState.currentPlayKeyframe = { keyframe }\n\n this.enqueueKeyframe(keyframe, params)\n\n return this.actionPromiseQueue()\n }\n\n private enqueueKeyframe(keyframe: CruiseKeyframe, params?: { duration?: number; moveEffect?: MoveEffect }) {\n const promise = this.getPlayPromise(keyframe, params)\n // A later queued frame can reject before the queue reaches it. Keep the original rejection for playback.\n void promise.catch(() => undefined)\n this.privateState.currentPlayQueue.push(promise)\n }\n\n /**\n * @description: getPlayPromise\n */\n private async getPlayPromise(keyframe: CruiseKeyframe, params: { duration?: number; moveEffect?: MoveEffect } = {}) {\n const data = keyframe.data\n params.duration =\n params.duration ?? (keyframe.start !== undefined && keyframe.end !== undefined ? keyframe.end - keyframe.start : undefined)\n if (!data) return\n return new Promise<void>((resolve, reject) => {\n let settled = false\n let removeInterrupt = () => {}\n const cancel = () => settle(false)\n const settle = (failed: boolean, error?: unknown) => {\n if (settled) return\n settled = true\n removeInterrupt()\n this.pendingKeyframes.delete(cancel)\n if (failed) reject(error)\n else resolve()\n }\n this.pendingKeyframes.add(cancel)\n removeInterrupt = this.addInterruptListener(() => {\n if (settled) return\n // Release this frame before pause cancels the remaining queued frames.\n settle(true, new Error('play is interupted'))\n this.hooks.emit('broke')\n // Consumer hooks may synchronously dispose this controller.\n if (this.state.disposed) return\n this.privateState.broke = true\n this.setState({ playing: false })\n })\n try {\n const work = data.effect === 'Move' ? this.move(data, params) : this.rotate(data, params)\n work.then(() => settle(false), error => settle(true, error))\n } catch (error) {\n settle(true, error)\n }\n })\n }\n\n private cancelPendingKeyframes() {\n for (const cancel of [...this.pendingKeyframes]) cancel()\n this.privateState.currentPlayQueue = []\n this.privateState.modeChanging = false\n }\n\n /**\n * @description Action promise queue in sequence\n */\n private async actionPromiseQueue(playId = this.privateState.playId): Promise<void> {\n const { privateState } = this\n return new Promise<void>((resolve, reject) => {\n if (playId !== privateState.playId || privateState.currentPlayQueue.length === 0) {\n resolve()\n return\n }\n const promise = privateState.currentPlayQueue.shift()\n if (!promise) {\n resolve()\n return\n }\n promise.then(resolve, reject)\n }).then(() => {\n if (playId !== privateState.playId || privateState.currentPlayQueue.length === 0) return Promise.resolve()\n return this.actionPromiseQueue(playId)\n })\n }\n\n /**\n * @description Action move keyframe\n */\n private async move(data: Partial<CruiseData>, params?: { duration?: number; moveEffect?: MoveEffect }) {\n const session = this.session\n const playId = this.privateState.playId\n const current = () => playId === this.privateState.playId && !session?.signal.aborted\n if (this.privateState.audio) {\n this.privateState.audio.pause()\n this.privateState.audio.currentTime = 0\n this.privateState.audio = null\n }\n\n if (data.mode && data.mode !== this.five.currentMode) {\n await this.changeMode(data)\n } else if (data.panoIndex !== this.five.panoIndex || this.pendingPanoMove?.panoIndex === data.panoIndex) {\n await this.changePano(data, params)\n }\n // 如果在跳转到指定点位时,音频已暂停,则不重新加载音频\n if (current?.() && !this.privateState.audio?.pause) {\n this.loadAudio(data.audio)\n await this.playAudio()\n }\n return Promise.resolve()\n }\n\n /**\n * @description Action rotate keyframe\n */\n private async rotate(data: Partial<CruiseData>, params?: { duration?: number; moveEffect?: MoveEffect }) {\n const session = this.session\n const playId = this.privateState.playId\n const current = () => playId === this.privateState.playId && !session?.signal.aborted\n if (data.audio && this.privateState.audio) {\n this.privateState.audio.pause()\n this.privateState.audio.currentTime = 0\n this.privateState.audio = null\n }\n\n if (data.mode && data.mode !== this.five.currentMode) {\n await this.changeMode({ mode: data.mode, panoIndex: data.panoIndex })\n } else if (typeof data.panoIndex === 'number' && (data.panoIndex !== this.five.panoIndex || this.pendingPanoMove?.panoIndex === data.panoIndex)) {\n return await this.changePano(data, params)\n }\n\n if (!current?.()) return\n await this.updateCamera(data, params)\n\n if (current?.() && data.audio && !this.privateState.audio?.pause) {\n this.loadAudio(data.audio)\n await this.playAudio()\n }\n }\n\n /**\n * @description Update five camera\n */\n private async updateCamera(data: Partial<Omit<Pose, 'offset'>> & { rotateSpeed?: number; direction?: 'left' | 'right' }, params: { duration?: number } = {}) {\n const { five, privateState, state } = this\n const speed = (() => {\n const speedConfig = state.config?.speedConfig\n const speedValue = data.rotateSpeed ?? speedConfig?.rotateSpeed\n if (speedConfig?.rotateSpeedUnit === undefined) return speedValue\n if (speedValue !== undefined) {\n return speedConfig.rotateSpeedUnit === 'rad/ms' ? speedValue : speedValue / 1000\n }\n })()\n\n const currentState = this.five.getCurrentState()\n const PI_2 = Math.PI * 2\n\n // 根据旋转方向调整 data.longitude,确保满足方向要求\n let targetLongitude = data.longitude\n if (targetLongitude !== undefined) {\n // 将 data.longitude 归一化到 [0, 2π] 范围\n targetLongitude = ((targetLongitude % PI_2) + PI_2) % PI_2\n\n if (data.direction === 'left') {\n // left (逆时针):需要 data.longitude > currentState.longitude\n // 如果 targetLongitude <= currentState.longitude,说明需要绕一圈,加上 2π\n if (targetLongitude <= currentState.longitude) {\n targetLongitude += PI_2\n }\n } else if (data.direction === 'right') {\n // right (顺时针):需要 data.longitude < currentState.longitude\n // 如果 targetLongitude >= currentState.longitude,说明需要绕一圈,减去 2π\n if (targetLongitude >= currentState.longitude) {\n targetLongitude -= PI_2\n }\n }\n }\n\n const duration = (() => {\n if (params.duration) return params.duration\n if (speed) {\n const coordinates1 = currentState\n const coordinates2 = data as any\n const rotation = coordinatesRotation(coordinates1, {...coordinates2, longitude: targetLongitude})\n return rotation / speed\n }\n return 800\n })()\n\n if (privateState.currentPlayKeyframe) privateState.currentPlayKeyframe.originDuration = duration\n\n const _duration = this.getSpeededDuration(duration)\n\n\n return new Promise<void>((resolve) => {\n safeCall(() => {\n return five.updateCameraWithKeyframes(\n [\n {\n progress: 0,\n value: {\n longitude: currentState.longitude,\n latitude: currentState.latitude,\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n {\n progress: 0.25,\n value: {\n longitude: targetLongitude !== undefined ? (currentState.longitude + (targetLongitude + currentState.longitude) / 2) / 2 : currentState.longitude,\n latitude: currentState.latitude,\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n {\n progress: 0.5,\n value: {\n longitude: targetLongitude !== undefined ? (targetLongitude + currentState.longitude) / 2 : currentState.longitude,\n latitude: (data.latitude !== undefined ? (data.latitude + currentState.latitude) / 2 : currentState.latitude),\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n {\n progress: 0.75,\n value: {\n longitude: targetLongitude !== undefined ? (targetLongitude + (targetLongitude + currentState.longitude) / 2) / 2 : currentState.longitude,\n latitude: currentState.latitude,\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n {\n progress: 1,\n value: {\n longitude: targetLongitude !== undefined ? targetLongitude : data.longitude ?? currentState.longitude,\n latitude: data.latitude !== undefined ? data.latitude : currentState.latitude,\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n ],\n _duration,\n );\n },\n )\n setTimeout(() => resolve(), _duration)\n })\n }\n\n /**\n * @description: Change five pano\n */\n private async changePano(data: Partial<CruiseData>, params?: { duration?: number; moveEffect?: MoveEffect }) {\n const { five, privateState, state } = this\n if (typeof data.panoIndex !== 'number') return\n const panoIndex = data.panoIndex\n const workCode = this.workUtil.workCode\n const session = this.session\n const playId = privateState.playId\n const pending = this.pendingPanoMove\n if (pending?.workCode === workCode && pending.panoIndex === panoIndex && pending.playId === playId && pending.session === session) {\n return pending.promise\n }\n if (panoIndex === five.panoIndex) return\n const current = () => playId === privateState.playId && !session?.signal.aborted && !this.state.disposed && this.workUtil.workCode === workCode\n const willChangeMode = five.getCurrentState().mode !== 'Panorama'\n if (willChangeMode) this.privateState.modeChanging = true\n const speed = (() => {\n const speedConfig = state.config?.speedConfig\n const speedValue = data.moveSpeed ?? speedConfig?.moveSpeed\n if (speedConfig?.moveSpeedUnit === undefined) return speedValue\n if (speedValue !== undefined) {\n return speedConfig.moveSpeedUnit === 'm/ms' ? speedValue : speedValue / 1000\n }\n })()\n const duration = (() => {\n if (params?.duration) return params.duration\n if (speed && typeof five.panoIndex === 'number' && typeof data.panoIndex === 'number') {\n const postion1 = this.workUtil.getObserverPosition(five.panoIndex)\n const postion2 = this.workUtil.getObserverPosition(data.panoIndex)\n if (postion1 && postion2) {\n const distance = postion1.distanceTo(postion2)\n return distance / speed\n } else {\n return 800\n }\n }\n return 800\n })()\n if (privateState.currentPlayKeyframe) privateState.currentPlayKeyframe.originDuration = duration\n let resolveMove!: () => void\n let rejectMove!: (error: unknown) => void\n const promise = new Promise<void>((resolve, reject) => {\n resolveMove = resolve\n rejectMove = reject\n })\n const request = { workCode, panoIndex, playId, session, promise }\n this.pendingPanoMove = request\n try {\n let settled = false\n const cancel = () => settle(false)\n const settle = (failed: boolean, error?: unknown) => {\n if (settled) return\n settled = true\n this.pendingKeyframes.delete(cancel)\n if (this.pendingPanoMove === request) this.pendingPanoMove = undefined\n session?.signal.removeEventListener('abort', cancel)\n five.off('panoArrived', onPanoArrived)\n five.off('pano.cancel', onPanoCancelled)\n if (failed && current()) rejectMove(error)\n else resolveMove()\n }\n const onPanoArrived = (index: number, arrivedState: State) => {\n if (index === panoIndex && arrivedState?.panoIndex === panoIndex && arrivedState?.workCode === workCode) settle(false)\n }\n const onPanoCancelled = (event: { state: State; error?: unknown }) => {\n if (event.state?.panoIndex === panoIndex && event.state?.workCode === workCode) {\n settle(true, event.error ?? new Error('Panorama move was cancelled'))\n }\n }\n this.pendingKeyframes.add(cancel)\n session?.signal.addEventListener('abort', cancel, { once: true })\n if (!current()) cancel()\n // Five may reuse an earlier request's callback for the same pending texture load.\n // Only this owner's actual target arrival can complete the current request.\n if (!settled) {\n five.on('panoArrived', onPanoArrived)\n five.on('pano.cancel', onPanoCancelled)\n }\n if (!settled) {\n try {\n const result: unknown = this.fiveUtil.moveToPano(panoIndex, {\n latitude: data.latitude,\n longitude: data.longitude,\n fov: data.fov,\n duration: this.getSpeededDuration(duration),\n effect: params?.moveEffect ?? this.state.config?.moveEffect ?? data.moveEffect,\n moveCancelCallback: () => settle(true, new Error('Panorama move was cancelled')),\n moveEndCallback: () => settle(false),\n })\n const onReturned = (value: unknown) => {\n if (value === false) settle(true, new Error('Panorama move was rejected'))\n }\n onReturned(result)\n // Five returns readiness, not arrival. Fulfillment must not advance the Cruise queue.\n Promise.resolve(result).then(onReturned, error => settle(true, error))\n } catch (error) {\n settle(true, error)\n }\n }\n await promise\n } finally {\n if (willChangeMode && playId === privateState.playId && !this.pendingPanoMove) privateState.modeChanging = false\n }\n }\n\n /**\n * @description Change five mode\n */\n private async changeMode(data: Partial<State>, duration?: number) {\n if (data.mode && data.mode !== this.five.currentMode) {\n this.privateState.modeChanging = true\n await this.five.changeMode(data.mode, data, duration)\n this.privateState.modeChanging = false\n }\n }\n\n private loadAudio(_audio: { url: string; duration: number }) {\n if (!this.privateState.playing || this.session?.signal.aborted) return\n if (_audio) {\n this.cancelAudio?.()\n // 尝试从缓存中获取预加载的音频(在用户手势上下文中创建的)\n let audio: HTMLAudioElement | undefined\n if (this.privateState.audioCache) {\n audio = this.privateState.audioCache.get(_audio.url)\n }\n\n // 如果缓存中没有,创建新的音频对象\n if (!audio) {\n audio = new Audio(_audio.url)\n audio.preload = 'auto'\n audio.load()\n }\n\n if (this.privateState.audio) {\n this.privateState.audio.pause()\n this.privateState.audio.currentTime = 0\n this.privateState.audio = null\n }\n this.privateState.audio = audio\n }\n }\n\n private async playAudio() {\n if (!this.state.playing || this.session?.signal.aborted) return\n const audio = this.privateState.audio\n if (!audio) return\n this.cancelAudio?.()\n const session = this.session\n const playId = this.privateState.playId!\n const current = () => playId === this.privateState.playId && !session?.signal.aborted && this.privateState.audio === audio\n const operations = session?.bind(audio) ?? audio\n operations.muted = false\n await new Promise<void>((resolve, reject) => {\n let started = false\n const cleanup = () => {\n audio.removeEventListener('playing', onPlaying)\n audio.removeEventListener('error', onError)\n audio.removeEventListener('ended', onEnded)\n session?.signal.removeEventListener('abort', cancel)\n if (this.cancelAudio === cancel) this.cancelAudio = undefined\n }\n const cancel = () => { cleanup(); resolve() }\n const onPlaying = () => {\n if (!current()) return cancel()\n started = true\n audio.removeEventListener('playing', onPlaying)\n resolve()\n }\n const fail = (error: unknown) => {\n cleanup()\n if (!current()) { resolve(); return }\n if (started) this.failPlayback(error, playId, session)\n else reject(error)\n }\n const onError = () => fail(new Error(audio.error?.message || 'Audio failed to play'))\n const onEnded = () => {\n cleanup()\n if (!current()) return\n operations.pause()\n operations.currentTime = 0\n this.privateState.audio = undefined\n resolve()\n }\n this.cancelAudio = cancel\n audio.addEventListener('playing', onPlaying)\n audio.addEventListener('error', onError)\n audio.addEventListener('ended', onEnded)\n session?.signal.addEventListener('abort', cancel, { once: true })\n try { operations.play().then(onPlaying, fail) } catch (error) { fail(error) }\n })\n }\n}\n"],"ignoreList":[2,3,4,5,6,7,8],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Work-BE4AgdwH.js","names":["getNormals","$.from_html","$.mutable_source","$.prop","$.deep_read_state","$.get","$.sibling","$.child","$.only_child","$.set_style","objectAssignDeep","CustomTag","PLUGIN","BasePlugin.Controller","objectAssignDeep","objectAssignDeep","BasePluginWithData.Controller","CruisePluginController","objectAssignDeep","coordinates1","coordinates2","__toESM","transformPosition","Subscribe","waitFiveModelLoaded","anyPositionToVector3","isPanoramaLike","isModelLike","blink","vectorToCoordinates","notNil","uuid","GUIDELINE_DEFAULT_ARROW_TEXTURE","GUIDELINE_WHITE_ARROW_TEXTURE","replaceStaticPrefix","to","changeMode","BetterTween","equal","PanoTagPluginController","Controller$1","Controller$2","template_effect","only_child","child","append","from_html","set","deep_read_state","legacy_pre_effect","legacy_pre_effect_reset","mutable_source","sibling","push","set_text","prop","init","next","set_style","pop","reset","mountComponent","get","px2rem","getCurrentFontSize","getGlobalResponsiveFontSize","FONT_SIZE_MAP","require_objectAssignDeep","sleep","THREE","GuideLineMaterial","sourceUv","image","imageColor","imageAlpha","insideBorder","isBorder","backgroundAlpha","borderAlpha","imageDisplayAlpha","mixedColor","mixedAlpha","finalColor","finalAlpha","gradient","logError","name","msg","require_add","add","a","b","out","require_set","x","y","require_normalize","normalize","len","require_subtract","subtract","require_dot","dot","require_polyline_miter_util","tmp","tangent","lineA","lineB","miter","halfThick","dir","require_polyline_normals","util","curNormal","closed","points","total","i","last","cur","addNext","last2","cur2","next2","miterLen2","normal","length","lineIsIntersecting","a1","line1","a2","b1","line2","b2","ua_t","ub_t","u_b","ua","ub","findIntersectingOfLines","j","import_polyline_normals","TRIANGLE_NUMBER_OF_RECTANGLE","VERTEX_NUMBER_OF_TRIANGLE","AXIS_NUMBER_OF_VERTEX","UV_NUMBER_OF_VERTEX","createLineGeometry","unitWidth","options","unitLength","halfUnitWidth","path","curvePath","curve","createCurve","pathData","divisions","curvePoints","curvePointsLength","normals","p","indexNumber","verticesNumber","positionNumber","uvNumber","index","positions","uv","totalLength","maxV","nx","nz","curvePointX","curvePointY","curvePointZ","vertices2i","Vector3","vertices2i1","end","center","skipPosition","intersectingIndex","lastHandleIndex","animationWillError","ni","p1","p2","p3","p4","intersecting","d1","d2","jStart","jEnd","kStart","kEnd","k","result","intersectingX","intersectingY","line1Index","line1RelativeIndex","line2Index","line2RelativeIndex","l","jStartY","line1IndexY","line2IndexY","kEndY","centerY","t","animationWillErrorAttribute","errorIndex","geometry","isCatmullRomCurve3Data","item","point","data","root","root_1","root_2","root_3","Tag","$$props","fontConfig","nameSize","padding","paddingStyle","distancePadding","distancePaddingStyle","lineHeight","lineHeightStyle","text","icon_url","distance","opacity","fontSize","div","styles","div_1","div_2","styles_1","node","consequent","div_3","styles_2","text_1","$$anchor","$$render","node_1","consequent_2","div_4","styles_3","node_2","consequent_1","span","styles_4","text_2","div_5","span_1","styles_5","text_3","span_2","styles_6","text_4","if_block","filterAdjacentDistinct","array","createPath","panoIndexList","fixedPositionInfo","position","panoIndex","work","lastPanoIndex","transform","import_objectAssignDeep","GuideLineModeItem","five","material","visible","width","scale","panoGroup","_panoGroup","currState","workCode","fallbackUrl","nextMaterialStyle","translateVector","applyTagTranslate","nextMeshStyle","tagContainer","tagPositionVector","translate","tagPosition","offset","color","backgroundClip","url","loadTexture","texture","floorIndexes","tag","curveLength","divisionLength","curveLengths","lengths","observerGroupIndex","currentCurvePoint","standingPosition","_tag","type","isModelTag","distanceInMeter","i18n","v","formattedDistance","props","app","container","mode","floor","progress","PLUGIN$1","CruiseController","config","state","prevState","play","enabled","wantsChangeModeHandler","interrupt","handleGesture","duration","longitude","id","func","getFiveStateOnCurve","curveOffset","MoveController","defaultState","defaultConfig","vectors","baseMoveSpeed","GuideLinePlugin","speed","playedProgress","lastProgress","disposer","reject","onRenderFrame","resolve","GuideLineItem","style","geometryStyle","materialStyle","meshStyle","skipPanoGroup","walkData","error","walk","move","plugin","fiveCurrentState","WalkController","onFivePanoArrived","onFiveModeChange","onReject","wantedPanoIndex","onResolve","removeListeners","PLUGIN_NAME","PLUGIN","Controller","generation","prevData","serverData","isV1Data","arrowTextureUrl","baseData","v1Data","v2Data","combineData","prevItem","newItem","processedItem","defaultTextureUrl","textureUrl","fn","enabledTagContainers","isNumberArray","value","isNear","position1","position2","getTagEnable","enabledTagContainer","startTagContainer","endTagContainer","startTagEnable","endTagEnable","coordinatesToVector","coordinates","coordinatesAngle","vector1","coordinates1","vector2","coordinates2","coordinatesRotation","deltaLon","deltaLat","angle","signed","safeCall","waitFiveLoaded","guideLinePanoIndex","tempFloorIndex","hasPanoIndexKeyframes","keyframe","floorIndex","route","_serverData","nextKeyframe","stay","keyframes","moveToFirstPanoEffect","moveToFirstPanoDuration","lookatNextPanoIndex","nextPanoIndex","vectorFrom","vectorTo","vector","privateState","hasAudio","session","currentPlayId","pauseData","target","selectedFrame","hooks","firstKeyframeWasPlayed","playFromIndex","pausedKeyframe","audio","playId","wasPlaying","fromManager","currentPlayKeyframe","params","promise","settled","removeInterrupt","cancel","settle","failed","current","speedConfig","speedValue","currentState","PI_2","targetLongitude","_duration","pending","willChangeMode","postion1","postion2","resolveMove","rejectMove","request","onPanoArrived","onPanoCancelled","arrivedState","event","onReturned","_audio","operations","started","cleanup","onPlaying","onError","onEnded","fail"],"sources":["../../src/GuideLinePlugin/utils/GuideLineMaterial.ts","../../src/shared-utils/log.ts","../../../node_modules/gl-vec2/add.js","../../../node_modules/gl-vec2/set.js","../../../node_modules/gl-vec2/normalize.js","../../../node_modules/gl-vec2/subtract.js","../../../node_modules/gl-vec2/dot.js","../../../node_modules/polyline-miter-util/index.js","../../../node_modules/polyline-normals/index.js","../../src/shared-utils/math/intersecting.ts","../../src/GuideLinePlugin/utils/createLineGeometry.ts","../../src/GuideLinePlugin/Components/Tag.svelte","../../src/GuideLinePlugin/utils/index.ts","../../src/GuideLinePlugin/utils/createPath.ts","../../src/GuideLinePlugin/GuideLineModeItem.ts","../../src/CruisePlugin/BaseController.ts","../../src/CruisePlugin/utils/getFiveStateOnCurve.ts","../../src/CruisePlugin/Move.ts","../../src/GuideLinePlugin/GuideLineItem.ts","../../src/GuideLinePlugin/Controller.ts","../../src/GuideLinePlugin/index.ts","../../src/CruisePlugin/utils/coordinatesToVector.ts","../../src/CruisePlugin/utils/coordinatesAngle.ts","../../src/CruisePlugin/utils/safeCall.ts","../../src/shared-utils/five/fiveLoaded.ts","../../src/CruisePlugin/Work.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\n\nexport class GuideLineMaterial extends THREE.MeshBasicNodeMaterial {\n public readonly mapNode: ReturnType<typeof THREE.TSL.texture>\n public readonly useMapColor = THREE.TSL.uniform(0)\n public readonly mapColor = THREE.TSL.uniform(new THREE.Color())\n public readonly mapOpacity = THREE.TSL.uniform(1)\n public readonly backgroundColor = THREE.TSL.uniform(new THREE.Color())\n public readonly backgroundOpacity = THREE.TSL.uniform(0)\n public readonly borderColor = THREE.TSL.uniform(new THREE.Color())\n public readonly borderOpacity = THREE.TSL.uniform(0)\n public readonly backgroundClip = THREE.TSL.uniform(0)\n public readonly borderWidth = THREE.TSL.uniform(0.05)\n public readonly flickerValue = THREE.TSL.uniform(1)\n public readonly maxV = THREE.TSL.uniform(0)\n public readonly vOffset = THREE.TSL.uniform(0)\n\n public constructor() {\n super({ transparent: true })\n\n const sourceUv = THREE.TSL.uv()\n const image = THREE.TSL.texture(new THREE.Texture(), THREE.TSL.vec2(sourceUv.x, sourceUv.y.sub(this.vOffset)))\n this.mapNode = image\n const imageColor = THREE.TSL.select(\n this.useMapColor.greaterThan(0.5),\n THREE.TSL.mix(image.rgb, this.mapColor, image.a),\n image.rgb,\n )\n const imageAlpha = image.a.mul(this.mapOpacity)\n const insideBorder = sourceUv.x.greaterThan(this.borderWidth).and(\n sourceUv.x.lessThan(THREE.TSL.float(1).sub(this.borderWidth)),\n )\n const isBorder = sourceUv.x.lessThanEqual(this.borderWidth).or(\n sourceUv.x.greaterThanEqual(THREE.TSL.float(1).sub(this.borderWidth)),\n )\n const backgroundAlpha = THREE.TSL.select(\n this.backgroundClip.lessThan(0.5),\n this.backgroundOpacity,\n THREE.TSL.select(insideBorder, this.backgroundOpacity, 0),\n )\n const borderAlpha = THREE.TSL.select(isBorder, this.borderOpacity, 0)\n const imageDisplayAlpha = imageAlpha.mul(0.4).add(0.6)\n const mixedColor = THREE.TSL.mix(this.backgroundColor, imageColor, imageAlpha)\n const mixedAlpha = THREE.TSL.mix(backgroundAlpha, imageDisplayAlpha, imageAlpha)\n const finalColor = THREE.TSL.mix(mixedColor, this.borderColor, borderAlpha)\n const finalAlpha = THREE.TSL.mix(mixedAlpha, borderAlpha, borderAlpha)\n const gradient = THREE.TSL.select(\n sourceUv.y.lessThanEqual(1),\n sourceUv.y,\n THREE.TSL.select(sourceUv.y.lessThanEqual(this.maxV.sub(1)), 1, this.maxV.sub(sourceUv.y)),\n )\n\n this.colorNode = THREE.TSL.vec4(finalColor, finalAlpha.mul(gradient).mul(this.flickerValue))\n }\n}\n","export function logWarning(name: string, msg: string) {\n console.warn(`⛔ ==> [${name}]: ${msg}`)\n}\n\nexport function logError(name: string, msg: string) {\n console.warn(`🚫 ==> [${name}]: ${msg}`)\n}\n","module.exports = add\n\n/**\n * Adds two vec2's\n *\n * @param {vec2} out the receiving vector\n * @param {vec2} a the first operand\n * @param {vec2} b the second operand\n * @returns {vec2} out\n */\nfunction add(out, a, b) {\n out[0] = a[0] + b[0]\n out[1] = a[1] + b[1]\n return out\n}","module.exports = set\n\n/**\n * Set the components of a vec2 to the given values\n *\n * @param {vec2} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @returns {vec2} out\n */\nfunction set(out, x, y) {\n out[0] = x\n out[1] = y\n return out\n}","module.exports = normalize\n\n/**\n * Normalize a vec2\n *\n * @param {vec2} out the receiving vector\n * @param {vec2} a vector to normalize\n * @returns {vec2} out\n */\nfunction normalize(out, a) {\n var x = a[0],\n y = a[1]\n var len = x*x + y*y\n if (len > 0) {\n //TODO: evaluate use of glm_invsqrt here?\n len = 1 / Math.sqrt(len)\n out[0] = a[0] * len\n out[1] = a[1] * len\n }\n return out\n}","module.exports = subtract\n\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec2} out the receiving vector\n * @param {vec2} a the first operand\n * @param {vec2} b the second operand\n * @returns {vec2} out\n */\nfunction subtract(out, a, b) {\n out[0] = a[0] - b[0]\n out[1] = a[1] - b[1]\n return out\n}","module.exports = dot\n\n/**\n * Calculates the dot product of two vec2's\n *\n * @param {vec2} a the first operand\n * @param {vec2} b the second operand\n * @returns {Number} dot product of a and b\n */\nfunction dot(a, b) {\n return a[0] * b[0] + a[1] * b[1]\n}","var add = require('gl-vec2/add')\nvar set = require('gl-vec2/set')\nvar normalize = require('gl-vec2/normalize')\nvar subtract = require('gl-vec2/subtract')\nvar dot = require('gl-vec2/dot')\n\nvar tmp = [0, 0]\n\nmodule.exports.computeMiter = function computeMiter(tangent, miter, lineA, lineB, halfThick) {\n //get tangent line\n add(tangent, lineA, lineB)\n normalize(tangent, tangent)\n\n //get miter as a unit vector\n set(miter, -tangent[1], tangent[0])\n set(tmp, -lineA[1], lineA[0])\n\n //get the necessary length of our miter\n return halfThick / dot(miter, tmp)\n}\n\nmodule.exports.normal = function normal(out, dir) {\n //get perpendicular\n set(out, -dir[1], dir[0])\n return out\n}\n\nmodule.exports.direction = function direction(out, a, b) {\n //get unit dir of two lines\n subtract(out, a, b)\n normalize(out, out)\n return out\n}","var util = require('polyline-miter-util')\n\nvar lineA = [0, 0]\nvar lineB = [0, 0]\nvar tangent = [0, 0]\nvar miter = [0, 0]\n\nmodule.exports = function(points, closed) {\n var curNormal = null\n var out = []\n if (closed) {\n points = points.slice()\n points.push(points[0])\n }\n\n var total = points.length\n for (var i=1; i<total; i++) {\n var last = points[i-1]\n var cur = points[i]\n var next = i<points.length-1 ? points[i+1] : null\n\n util.direction(lineA, cur, last)\n if (!curNormal) {\n curNormal = [0, 0]\n util.normal(curNormal, lineA)\n }\n\n if (i === 1) //add initial normals\n addNext(out, curNormal, 1)\n\n if (!next) { //no miter, simple segment\n util.normal(curNormal, lineA) //reset normal\n addNext(out, curNormal, 1)\n } else { //miter with last\n //get unit dir of next line\n util.direction(lineB, next, cur)\n\n //stores tangent & miter\n var miterLen = util.computeMiter(tangent, miter, lineA, lineB, 1)\n addNext(out, miter, miterLen)\n }\n }\n\n //if the polyline is a closed loop, clean up the last normal\n if (points.length > 2 && closed) {\n var last2 = points[total-2]\n var cur2 = points[0]\n var next2 = points[1]\n\n util.direction(lineA, cur2, last2)\n util.direction(lineB, next2, cur2)\n util.normal(curNormal, lineA)\n \n var miterLen2 = util.computeMiter(tangent, miter, lineA, lineB, 1)\n out[0][0] = miter.slice()\n out[total-1][0] = miter.slice()\n out[0][1] = miterLen2\n out[total-1][1] = miterLen2\n out.pop()\n }\n\n return out\n}\n\nfunction addNext(out, normal, length) {\n out.push([[normal[0], normal[1]], length])\n}","/**\n * @description 两条二维线段是否相交,不考虑端点重合的情况\n */\nexport function lineIsIntersecting(line1: { x: number; y: number }[], line2: { x: number; y: number }[]) {\n const a1 = line1[0]\n const a2 = line1[1]\n const b1 = line2[0]\n const b2 = line2[1]\n var ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x)\n var ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x)\n var u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y)\n if (u_b !== 0) {\n var ua = ua_t / u_b\n var ub = ub_t / u_b\n if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n return true\n }\n }\n return false\n}\n\n/**\n * @description 两条二维折线段的交点,不考虑端点重合的情况\n */\nexport function findIntersectingOfLines(line1: { x: number; y: number }[], line2: { x: number; y: number }[]) {\n for (let i = 0; i < line1.length - 1; i++) {\n for (let j = 0; j < line2.length - 1; j++) {\n if (lineIsIntersecting([line1[i], line1[i + 1]], [line2[j], line2[j + 1]])) {\n return {\n x: (line1[i].x + line1[i + 1].x) / 2,\n y: (line1[i].y + line1[i + 1].y) / 2,\n line1RelativeIndex: i,\n line2RelativeIndex: j,\n }\n }\n }\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { Vector3 } from 'three/webgpu'\nimport getNormals from 'polyline-normals'\nimport type * as PluginType from '../typing'\nimport { findIntersectingOfLines, lineIsIntersecting } from '../../shared-utils/math/intersecting'\n\n/** 生成曲线参数 */\ninterface LineGeometryOption {\n /** 路径 */\n path: PluginType.PathItem[]\n /** 线宽,默认是 0.5 */\n width: number\n /** 每一段的长度,默认是 0.5 */\n unitLength: number\n skipPositions?: THREE.Vector3[] | null\n useAutoDepthTest?: boolean\n}\n\n// 定义常量\nconst TRIANGLE_NUMBER_OF_RECTANGLE = 2 // 每个矩形有两个三角形\nconst VERTEX_NUMBER_OF_TRIANGLE = 3 // 每个三角形有三个顶点\nconst AXIS_NUMBER_OF_VERTEX = 3 // 每个顶点有三个轴坐标\nconst UV_NUMBER_OF_VERTEX = 2 // 每个顶点有两个 UV 轴坐标\n\n/** 创建路线的几何体\n * @param curvePoints 三维点位\n * @param unitWidth 线段宽度\n * @param unitLength 每一段的长度\n * @returns THREE BufferGeometry\n */\n\nexport function createLineGeometry(options: LineGeometryOption) {\n const unitWidth = options.width\n const unitLength = options.unitLength\n const halfUnitWidth = unitWidth / 2\n\n const path = options.path\n if (path.length === 0) return { geometry: new THREE.BufferGeometry(), maxV: 0, curvePath: null, curvePoints: null }\n\n const curvePath = new THREE.CurvePath<THREE.Vector3>()\n path.forEach((pathData) => {\n const curve = createCurve(pathData)\n curve && curvePath.add(curve)\n })\n\n // 切片数\n const divisions = Math.ceil(curvePath.getLength() * 100)\n curvePath.arcLengthDivisions = divisions\n // 切点,length = divisions + 1\n const curvePoints = curvePath.getPoints(divisions)\n\n // 切点数量\n const curvePointsLength = curvePoints.length\n if (curvePointsLength <= 2) return { geometry: new THREE.BufferGeometry(), maxV: 0, curvePath: null, curvePoints: null }\n // 每个切点在曲线上的切线\n const normals = getNormals(curvePoints.map((p) => [p.x, p.z])) // curvePoints:每个点切线的向量「二维」\n\n const rectangleNumber = curvePointsLength - 1 // N 个切线点,构成了 N - 1 个矩形\n const indexNumber = rectangleNumber * TRIANGLE_NUMBER_OF_RECTANGLE * VERTEX_NUMBER_OF_TRIANGLE\n const verticesNumber = 2 * curvePointsLength // 顶点数量(包含公用):每个切点对应两个顶点,N 个 切点有 2N 个顶点\n const positionNumber = verticesNumber * AXIS_NUMBER_OF_VERTEX // 坐标点数量\n const uvNumber = verticesNumber * UV_NUMBER_OF_VERTEX // uv 数量\n\n const index = new Uint32Array(indexNumber)\n const positions = new Float32Array(positionNumber)\n const uv = new Float32Array(uvNumber)\n\n let totalLength = 0\n let maxV = 0\n\n // 每次循环设置两个顶点\n for (let i = 0; i < curvePointsLength; i++) {\n const [nx, nz] = normals[i]![0]!\n const curvePoint = curvePoints[i]!\n const { x: curvePointX, y: curvePointY, z: curvePointZ } = curvePoint\n\n // 顶点1 vertices[2i]\n const vertices2i = new Vector3(curvePointX + nx * halfUnitWidth, curvePointY + 0.05, curvePointZ + nz * halfUnitWidth)\n positions[i * 6 + 0] = vertices2i.x\n positions[i * 6 + 1] = vertices2i.y\n positions[i * 6 + 2] = vertices2i.z\n\n // 顶点2 vertices[2i + 1]\n const vertices2i1 = new Vector3(curvePointX - nx * halfUnitWidth, curvePointY + 0.05, curvePointZ - nz * halfUnitWidth)\n positions[i * 6 + 3] = vertices2i1.x\n positions[i * 6 + 4] = vertices2i1.y\n positions[i * 6 + 5] = vertices2i1.z\n\n // 计算总长度\n totalLength += i > 0 ? curvePoints[i - 1]!.clone().sub(curvePoints[i]!).length() : 0\n\n // 设置 uv\n // uv.y 表示路线的长度点,可以用于在 glsl 中控制颜色展示\n // 前两个顶点的 uv.y 为 0,最后两个顶点的 uv.y 为 end\n const end = totalLength / unitLength\n maxV = end\n // 顶点1的uv\n uv[i * 4 + 0] = 0 // uv.x\n uv[i * 4 + 1] = end // uv.y\n // 顶点2的uv\n uv[i * 4 + 2] = 1 // uv.x\n uv[i * 4 + 3] = end // uv.y\n\n // 目前 skip 时只会把面片跳过去,如果希望图像是连续的,需要跳过的面片的 uv 也要跳过\n const center = new THREE.Vector3().lerpVectors(vertices2i, vertices2i1, 0.5)\n if (options.skipPositions) {\n const shouldSkip = options.skipPositions.some((skipPosition) => skipPosition.distanceTo(center) < 0.26)\n if (shouldSkip) continue\n }\n\n if (i === curvePointsLength - 1) continue\n index[i * 6 + 0] = i * 2 + 0\n index[i * 6 + 1] = i * 2 + 2\n index[i * 6 + 2] = i * 2 + 1\n index[i * 6 + 3] = i * 2 + 2\n index[i * 6 + 4] = i * 2 + 3\n index[i * 6 + 5] = i * 2 + 1\n }\n\n // 后处理,消除转弯处的重叠\n const intersectingIndex: number[] = [] // 参与重叠的i值\n let lastHandleIndex: number // 上一个处理的结束的i值(不包含y值处理的部分,只包含重叠部分计算的)\n const animationWillError: { start: number; end: number }[] = [] // 动画会出错的i值\n for (let i = 0; i < curvePointsLength - 1; i++) {\n if (lastHandleIndex !== undefined) {\n if (i <= lastHandleIndex) continue\n }\n const ni /** next i */ = i + 1\n const p1 = {\n x: positions[i * 6 + 0],\n y: positions[i * 6 + 2],\n }\n const p2 = {\n x: positions[i * 6 + 3],\n y: positions[i * 6 + 5],\n }\n const p3 = {\n x: positions[ni * 6 + 0],\n y: positions[ni * 6 + 2],\n }\n const p4 = {\n x: positions[ni * 6 + 3],\n y: positions[ni * 6 + 5],\n }\n const intersecting = lineIsIntersecting([p1, p2], [p3, p4])\n if (intersecting) intersectingIndex.push(i)\n /** ============ !intersecting 表示重叠部分结束,接下来开始处理重叠部分的positions ============ */\n if (!intersecting && intersectingIndex.length) {\n intersectingIndex.push(i)\n // 求 求交点时应该用哪一侧的线\n const d1 = new THREE.Vector2(p1.x, p1.y).distanceTo(new THREE.Vector2(p3.x, p3.y))\n const d2 = new THREE.Vector2(p2.x, p2.y).distanceTo(new THREE.Vector2(p4.x, p4.y))\n // 前后找一定数量的点组成线,求交点\n const x = 300 // 延伸的长度\n const line1: { x: number; y: number }[] = []\n const line2: { x: number; y: number }[] = []\n\n // 取重叠部分前面的一段点\n const jStart = Math.max(0, intersectingIndex[0] - unitLength * x)\n const jEnd = intersectingIndex[0]\n for (let j = jStart; j < jEnd; j++) {\n if (d1 < d2) {\n line1.push({ x: positions[j * 6 + 0], y: positions[j * 6 + 2] })\n } else {\n line1.push({ x: positions[j * 6 + 3], y: positions[j * 6 + 5] })\n }\n }\n\n // 取重叠部分后面的一段点\n const kStart = intersectingIndex[intersectingIndex.length - 1]\n const kEnd = Math.min(curvePointsLength - 1, intersectingIndex[intersectingIndex.length - 1] + unitLength * x)\n for (let k = kStart; k < kEnd; k++) {\n if (d1 < d2) {\n line2.push({ x: positions[k * 6 + 0], y: positions[k * 6 + 2] })\n } else {\n line2.push({ x: positions[k * 6 + 3], y: positions[k * 6 + 5] })\n }\n }\n const result = findIntersectingOfLines(line1, line2)\n\n if (result) {\n const {\n line1RelativeIndex /** line1的交点的相对index */,\n line2RelativeIndex /** line2的交点的相对index */,\n x: intersectingX,\n y: intersectingY,\n } = result\n const line1Index /** line1的交点的index */ = jStart + line1RelativeIndex\n const line2Index /** line2的交点的index */ = kStart + line2RelativeIndex + 2\n // 需要重新计算的顶点\n for (let l = line1Index; l < line2Index; l++) {\n // 替换xz\n if (d1 < d2) {\n positions[l * 6 + 0] = intersectingX\n positions[l * 6 + 2] = intersectingY\n } else {\n positions[l * 6 + 3] = intersectingX\n positions[l * 6 + 5] = intersectingY\n }\n lastHandleIndex = l\n }\n // 平均一下交点前一段部分的y值, 和交点后一段部分的y值,同时使重叠部分(两个交点之间)内侧的y值保持一致\n let jStartY: number\n let line1IndexY: number\n let line2IndexY: number\n let kEndY: number\n let centerY: number\n if (d1 < d2) {\n jStartY = positions[jStart * 6 + 1]\n line1IndexY = positions[line1Index * 6 + 1]\n line2IndexY = positions[line2Index * 6 + 1]\n kEndY = positions[kEnd * 6 + 1]\n centerY = (line1IndexY + line2IndexY) / 2\n } else {\n jStartY = positions[jStart * 6 + 4]\n line1IndexY = positions[line1Index * 6 + 4]\n line2IndexY = positions[line2Index * 6 + 4]\n kEndY = positions[kEnd * 6 + 4]\n centerY = (line1IndexY + line2IndexY) / 2\n }\n // 修改 jStart(含) ~ line1Index(不含) 的 y 值, y 值为 jSTartY ~ centerY\n for (let l = jStart; l < line1Index; l++) {\n const length = line1Index - jStart // 这里长度故意要加一,因为不希望结尾的y完全等于 centerY,也就是说结尾的t值不是1,要小一点\n const t = (l - jStart) / length\n if (d1 < d2) {\n positions[l * 6 + 1] = jStartY + (centerY - jStartY) * t\n } else {\n positions[l * 6 + 4] = jStartY + (centerY - jStartY) * t\n }\n }\n // 修改 line1Index(含) ~ line2Index(不含) 的 y 值,y 值为 centerY\n for (let l = line1Index; l < line2Index; l++) {\n if (d1 < d2) {\n positions[l * 6 + 1] = centerY\n } else {\n positions[l * 6 + 4] = centerY\n }\n }\n // 修改 line2Index(含) ~ kEnd(不含) 的 y 值,y 值为 centerY ~ kEndY\n for (let l = line2Index; l < kEnd; l++) {\n const length = kEnd - line2Index // 这里长度故意要加一,因为不希望结尾的y完全等于 kEnd 处的Y值,也就是说结尾的t值不是1,要小一点\n const t = (l - line2Index + 1) / length // 这里不希望初始的y完全等于 centerY,也就是说初始的t值不是0,要大一点\n if (d1 < d2) {\n positions[l * 6 + 1] = centerY + (kEndY - centerY) * t\n } else {\n positions[l * 6 + 4] = centerY + (kEndY - centerY) * t\n }\n }\n animationWillError.push({\n start: line1Index,\n end: line2Index,\n })\n }\n\n intersectingIndex.length = 0\n }\n }\n\n const animationWillErrorAttribute = new Float32Array(verticesNumber)\n animationWillError.forEach((errorIndex) => {\n for (let i = 0; i < curvePointsLength - 1; i++) {\n if (i >= errorIndex.start && i <= errorIndex.end) {\n animationWillErrorAttribute[i * 2 + 0] = 1\n animationWillErrorAttribute[i * 2 + 1] = 1\n } else if (animationWillErrorAttribute[i] !== 1) {\n animationWillErrorAttribute[i * 2 + 0] = 0\n animationWillErrorAttribute[i * 2 + 1] = 0\n }\n }\n })\n\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geometry.setAttribute('uv', new THREE.BufferAttribute(uv, 2))\n // 白杰说先不加这个过滤\n // geometry.setAttribute('animationWillError', new THREE.BufferAttribute(animationWillErrorAttribute, 1))\n geometry.setIndex(new THREE.BufferAttribute(index, 1))\n\n return { geometry, maxV, animationWillError, curvePath, curvePoints }\n}\n\nfunction createCurve(item: PluginType.PathItem) {\n if (isCatmullRomCurve3Data(item)) {\n const positions = item.points.map((point) => new THREE.Vector3().fromArray(point))\n const curve = new THREE.CatmullRomCurve3(positions, item.closed ?? false, (item.curve_type ?? 'centripetal') as THREE.CurveType, item.tension)\n return curve\n }\n}\n\nfunction isCatmullRomCurve3Data(data: any): data is PluginType.CatmullRomCurve3 {\n return data.type === 'CatmullRomCurve3'\n}\n","<script lang=\"ts\">\n import { FONT_SIZE_MAP, type FontSizeType } from '../../shared-utils/fontSize'\n import px2rem from '../../shared-utils/px2rem'\n\n export let text = ''\n export let icon_url = ''\n export let distance = ''\n export let opacity = 1\n export let name = ''\n export let fontSize: FontSizeType = 'md'\n const text_background_url =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHUAAAA2CAMAAADOFiZMAAACEFBMVEUAAACIiIheXl5oaGh6enpsbG' +\n 'xiYmJ9fX1wcHBXV1eBgYFzc3NSUlKNjY2Dg4NOTk51dXVXV1dmZmZTU1N3d3dcXFyMjIyEhIRNTU2QkJC0tLS5ubnHx8fOzs6np6' +\n 'exsbHKysqoqKi9vb3U1NTPz8/Nzc2vr6/Dw8OysrK/v7/X19fS0tKurq62traqqqrJycmurq64uLifn5/Dw8O6urqQkJC6urro6O' +\n 'jt7e3o6OjU1NS3t7fBwcGjo6Ozs7Orq6u1tbXAwMCurq6rq6vy8vLx8fHr6+vp6enZ2dnd3d3a2trX19fV1dW/v7/IyMihoaGamp' +\n 'qVlZWLi4uCgoK+vr6urq7m5ubw8PDk5OTu7u7i4uLg4ODe3t7q6urS0tLi4uLOzs7e3t7Hx8fa2tqrq6vExMTAwMCnp6efn5+Wlp' +\n 'aHh4ezs7OoqKiJiYm6urqZmZmurq59fX29vb23t7e4uLipqanp6enc3Nza2trW1tbT09Pm5ubj4+PQ0NDg4ODExMTCwsK7u7vBwc' +\n 'G8vLy5ubm8vLy+vr64uLiysrKdnZ3CwsJoaGisrKzHx8ekpKTExMTv7+/i4uLa2trm5ubk5OTLy8vKysrExMTQ0NDX19ecnJzT09' +\n 'N/f3+dnZ12dnaQkJCXl5etra3Pz8+4uLiXl5fGxsaqqqrr6+vQ0NDKysrNzc3W1takpKShoaGsrKysrKyduRZkAAAAsHRSTlMATE' +\n '1NTExMTUxNTExMTExNTExMTU1MTU1MTICFc313fnl0iIWAe3h3aYqIgXx7eXZzcnFwaGggxLiog4J0dG9mZF82FMfEtK2pkYqKh3' +\n 'x4cm1rZmEmH8G/vry6trOxoZ2clpKOe3ptbWZjYmFgXFpaVlFPSDYlx7CspaSjoJ6akY6HfXt4bGpmY1xUU0g2LSzCuK6lopiWho' +\n 'F3YmFaVlZUUU5KPyEJCcl/fXNdXFxZUIUrIQsAAAV6SURBVFjDvZj3VxNBEMePBBIOQgmEQGghISSASSBBUQFBVIpUEaR3aVJExN' +\n '4F6fbee6//opPN2507E3P7fD4+b54z+935zt7lvPsBYbZ5lyXT7R5xms2ppaVpV615eVeuXL48PPzw4YPBwYsX+/vPnT1bW1t75u' +\n '7p0729PT13urs7O9vbt2/ffurUp1OQ2ts7O7u77/T09PaevnvmTG3t2XPn+vsvDg4+GH5UVjl/SAjGe29La2vr5EFgm4+WlpYDgN' +\n 'frbW7etQuuKDPTPTIy4nSa4bJ8lKYBV69arXmA1WpN81FamgqYzU6n0+12ZwI+qzPtyvDlR0dPCoGsecW4FEZcShwEyUDIGvtD+D' +\n 'cOZlrzFvcE3qylFXZ1cTqIgGk0K1xRSL84abaWtwl/8KM5kTiok04B2BpAPUWXAoGnQK3gn0xNW90ryDhpafXvJsYlJuoSdRCyTJ' +\n 'HqBOxR9IvbUl1/PN5pL9tFR4gTJJmi7N+wl8qf7k33S+YQE0VRJwZz42RogDZcAxx+sTn1jSDho6VFBKAbp9K1XqfXi3oRgmSqQ2' +\n 'AGePziNpfs2GN2lV5Pp+IJkkwIrDFz+Y+Y90h/Yvtz+f0o1YGnc/lVXvshASk8IHUm6ZMIYhI6YAEyqyHkE/n8Kkuh5AX6ZVdBly' +\n 'pJpRJVIgTJ0IluEGCb1BDYCzWFx79h/yl5ZV3PVUSVAQIDFhCyLO/h9E9KfuOPriOqzUFjmRYYueOqTWLGfhPfHZcGrkOlgcAGsk' +\n 'ZdAV7/eIVA2eN6qZGA3Yhcxxozn3+mkD3ZQ64Z3EnQJEBouMB+Xr+68LpAuTZBOokDoPXfNIK85vZP5AqUreNqdYI6AUINkBrAtU' +\n 'atgaA67mEft38GvxRThWopOAFrBbj9kYXsa3z0mnrTsLAHe3yRzxGhjoBQ0BT848foqfONkT6FAAWrce3PeEpA5vZPsDf23aIhgp' +\n 'fIiEiIiH/mKftPfKJxTjaNv8bM6zlSzk5dmIsMDk7EGrMEbj+e+q5xLjoyOrQbGiCCaZh5/PgLzy8YiIrgNPmaZtQovP6J3ezNaf' +\n 'TvxEfHQ2An8v/2K47hV4J0ExVBDbNCD4e/nH0lKj1+1RBvMEQboiEMUJI1BOmmGq0pVOP1z3nYF3G53EAIN4SHx4djNyxAkutQA1' +\n 'QnGeD2z3rY199RIZ+EtVxDPaDm9VdspYcWj65pteFaonIDBghpzeXyzNNTbyy8CpgCyCehjnvYx+uf9RTTU9cbo7SbRPmKQBnzaK' +\n 'MI2igthD8jVAvIuM/rXytjfyz4MFqBDgLWPGuA05/sqRQobaOzsBMbFQsRhaAWco/A6Z92FAuU446wWL+aHJWcHJtMOzEDwWrU+P' +\n 'yvHEcFRlkutELInT4NFiCRGqA6yQDWfH5jWdFegXLL8V3qDIsNIySHoRsWIGMN/wBY8/mXRosFxrrDCE20EwJzCGQ9XP7crBN46A' +\n 'dHbthmkPvluICccLzgchnDjBD/eqaxKOOtIKGyiEzDqSFOCt7D4X/dlHFDkNCWPu3fjTHGQBgpbI06TkeIpuQ37bbltAlSKstM/g' +\n '6EdYcEr0jJv2rLfrZXkFKcPhVjMsWY0GGSrTn00H7TakbD11sChd7qa+gCSKdJVitpyvWLlab6uifsieKtLk1N7QZWtvpYXl4aGx' +\n 'srAtIJBQVNWVlZOTkZGRm2z7bHW0q2lJRkZ2c3NOTn19fV19fn5zfAsmQL8Nhmg66cHOhvKigoSC/Iysk+vH9//jd2n8g6TG7yjb' +\n 'XZYCAMq6s7fBiah4aGLl0aGLhw4f758zuBmpq+vurq6h07dnR1dXTcrqqq2uejqup2R0dXF8jV1X19NTU1O3feu3f+/oWBgUtD++' +\n 'uePHtbLAThNzRClbi+VnseAAAAAElFTkSuQmCC'\n\n $: fontConfig = FONT_SIZE_MAP[fontSize]\n $: nameSize = px2rem(fontConfig?.name || 12)\n $: padding = fontConfig?.padding?.guide || [8, 2]\n $: paddingStyle = `${px2rem(padding[1])} ${px2rem(padding[0])}`\n $: distancePadding = fontConfig?.padding?.distance || [4, 2]\n $: distancePaddingStyle = `${px2rem(distancePadding[1])} ${px2rem(distancePadding[0])}`\n $: lineHeight = fontConfig?.lineHeight || 14\n $: lineHeightStyle = px2rem(lineHeight)\n</script>\n\n<div class=\"guide-line__tag\" style:opacity>\n <div class=\"guide-line__tag-point\" />\n <div class=\"guide-line__tag-line\" />\n <div class=\"guide-line__tag-content\">\n <div class=\"guide-line__tag-icon\" style:background-image={`url(${icon_url})`} />\n {#if text && !distance}\n <div class=\"guide-line__tag-text\" style:font-size={nameSize} style:padding={paddingStyle} style:border-image-source={`url(${text_background_url})`}>{text}</div>\n {/if}\n {#if distance}\n <div class=\"text-with-distance\" style:padding={distancePaddingStyle}>\n {#if name} <span class=\"line-name\" style:line-height={lineHeightStyle} style:font-size={nameSize}>{name}</span> {/if}\n <div class=\"distance-and-name\">\n <span class=\"distance\" style:line-height={lineHeightStyle} style:font-size={nameSize}>\n {distance}\n </span>\n <span class=\"name\" style:line-height={lineHeightStyle} style:font-size={nameSize}>{text}</span>\n </div>\n <div class=\"border\" />\n </div>\n {/if}\n </div>\n</div>\n\n<style>\n .guide-line__tag {\n position: relative;\n }\n\n .text-with-distance {\n display: flex;\n flex-direction: column;\n position: relative;\n padding: 2px 4px;\n border-radius: 2px;\n background: linear-gradient(to top, rgba(147, 147, 147, 0.3), rgba(74, 74, 74, 0.3));\n box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2);\n }\n\n .text-with-distance .border {\n position: absolute;\n top: -50%;\n right: -50%;\n bottom: -50%;\n left: -50%;\n padding: 1px;\n border-radius: 4px;\n background: linear-gradient(to right, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.2));\n mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n mask-composite: exclude;\n -webkit-mask-composite: xor;\n transform: scale(0.5);\n }\n\n .distance-and-name {\n display: flex;\n gap: 3px;\n }\n\n .distance {\n white-space: nowrap;\n font-size: 10px;\n line-height: 14px;\n color: #66afff;\n }\n\n .name {\n opacity: 0.6;\n font-size: 10px;\n line-height: 14px;\n white-space: nowrap;\n color: #ffffff;\n }\n\n .line-name {\n color: #fff;\n white-space: nowrap;\n font-size: 10px;\n line-height: 14px;\n }\n\n .guide-line__tag-point {\n position: absolute;\n left: 50%;\n bottom: 1px;\n width: 7px;\n height: 2px;\n transform: translateX(-50%);\n background: #fff;\n border-radius: 50%;\n opacity: 0.5;\n }\n\n .guide-line__tag-line {\n position: absolute;\n left: 50%;\n bottom: 1px;\n width: 1px;\n height: 30px;\n transform: translateX(-50%);\n background: linear-gradient(to top, #fff, rgba(255, 255, 255, 0));\n }\n\n .guide-line__tag-content {\n position: absolute;\n left: -15px;\n bottom: 31px;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n\n .guide-line__tag-icon {\n width: 30px;\n height: 30px;\n background-size: 100%;\n }\n\n .guide-line__tag-text {\n box-sizing: content-box;\n width: max-content;\n transform: translateX(-3px);\n white-space: nowrap;\n font-size: 10px;\n line-height: 14px;\n border: solid transparent;\n border-width: 2px 8px 2px 6px;\n border-image-slice: 6 25 6 18 fill;\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n</style>\n","/**\n * 筛选出给定数组中,相邻元素不能重复的元素组成的新数组\n * @param array 要筛选的数组\n * @returns 筛选后的新数组\n */\nexport function filterAdjacentDistinct<T>(array: T[]): T[] {\n if (array.length === 0) return []\n\n return array.filter((item, index) => item !== array[index - 1])\n}\n","import type { Work } from '@realsee/five-webgpu'\nimport type { CatmullRomCurve3, ExtraRouteData } from '../typing'\nimport * as THREE from 'three/webgpu'\nimport { transformPosition } from '../../shared-utils/five/transformPosition'\n\nexport function createPath(\n panoIndexList: number[],\n work: Work,\n options?: Omit<CatmullRomCurve3, 'type' | 'points'> & ExtraRouteData,\n): CatmullRomCurve3[] {\n if (panoIndexList.length < 2) return []\n\n const fixedPositionInfo: number[][] = []\n panoIndexList.forEach((panoIndex, i) => {\n let position = options?.route_standing_positions?.[panoIndex]\n if (!position) position = work.observers[panoIndex]?.standingPosition?.toArray()\n\n if (!position) return\n const lastPanoIndex = panoIndexList[i - 1]\n\n // 插值\n const routePoints =\n options?.node_pair_to_route_points?.[`${lastPanoIndex}:${panoIndex}`]?.slice() ??\n options?.node_pair_to_route_points?.[`${panoIndex}:${lastPanoIndex}`]?.slice().reverse()\n\n routePoints?.forEach((point) => {\n fixedPositionInfo.push(point)\n })\n\n fixedPositionInfo.push(position)\n })\n\n const transform = work.transform\n const positions = fixedPositionInfo.map((position) => transformPosition(new THREE.Vector3().fromArray(position), transform).toArray())\n\n return [{ ...options, type: 'CatmullRomCurve3', points: positions }]\n}\n","import { GuideLineMaterial } from './utils/GuideLineMaterial'\nimport type GuideLinePlugin from './Controller'\nimport type { Five, Mode, Work } from '@realsee/five-webgpu'\nimport type { Tag } from '../PanoTagPlugin'\nimport type * as PluginType from './typing'\nimport type { GuideLineItem } from './GuideLineItem'\nimport * as THREE from 'three/webgpu'\nimport { logError, logWarning } from '../shared-utils/log'\nimport { createLineGeometry } from './utils/createLineGeometry'\nimport { BetterTween, blink, GUIDELINE_DEFAULT_ARROW_TEXTURE, isModelLike, isPanoramaLike, notNil, replaceStaticPrefix, tweenProgress } from '../shared-utils'\nimport { loadTexture } from '../shared-utils/three/loadTexture'\nimport { PanoTagPluginController } from '../PanoTagPlugin'\nimport CustomTag from './Components/Tag.svelte'\nimport { filterAdjacentDistinct } from './utils'\nimport objectAssignDeep from 'object-assign-deep'\nimport { createPath } from './utils/createPath'\nimport { getCurrentFontSize, getGlobalResponsiveFontSize } from '../shared-utils/fontSize'\n\nimport { mountComponent, type MountedComponent } from '../shared-utils/svelte/component.svelte'\n/** @link https://threejs.org/docs/index.html#api/en/extras/curves/CatmullRomCurve3 */\ntype CatmullRomCurve3RestParams = Omit<PluginType.CatmullRomCurve3, 'type' | 'points'>\n\nexport interface GuideLineTagContainer {\n tag: Tag<'Custom', '2DPoint'> | null\n plugin: PanoTagPluginController\n app?: MountedComponent<any>\n}\n\n/** 在不同模态下的 GuideLine */\nclass GuideLineModeItem {\n public get panoGroup() {\n return this._panoGroup\n }\n /** 可展示的楼层 */\n public get visibleFloorIndexes() {\n return this._visibleFloorIndexes\n }\n /** THREE Curve 路径 */\n public get curvePath() {\n return this._curvePath\n }\n /** THREE Curve 路径上的点 */\n public get curvePoints() {\n return this._curvePoints\n }\n\n public name = ''\n public startTagContainer?: GuideLineTagContainer\n public endTagContainer?: GuideLineTagContainer\n public path: PluginType.PathItem[] = []\n public geometryStyle: PluginType.GuideLineGeometryStyle = {}\n public materialStyle: PluginType.GuideLineMaterialStyle = {}\n public meshStyle: PluginType.GuideLineMeshStyle = {}\n public readonly group: THREE.Group = new THREE.Group()\n public readonly mesh: THREE.Mesh<THREE.BufferGeometry, GuideLineMaterial>\n public visible: boolean | null = null\n /** 保存原始的 tag 数据,用于更新距离显示 */\n private startTagData: Tag | PluginType.ModelGuideLineTagData | null = null\n private endTagData: Tag | PluginType.ModelGuideLineTagData | null = null\n private five: Five\n private mode: PluginType.GuideLineModeItemMode\n private _curvePath: THREE.CurvePath<THREE.Vector3> | null = null\n private _curvePoints: THREE.Vector3[] | null = null\n private _panoGroup: number[] = []\n private skippedPositions: null | THREE.Vector3[] = null\n private textureUrl = ''\n private scale = 1\n private width = 0.5\n private unitLength = 0.5\n private _visibleFloorIndexes: null | number[] = null\n /** Five Mode 是否满足 */\n private modeVisible = false\n /** 楼层是否满足展示条件 */\n private floorVisible = true\n /** 默认是否展示 */\n private defaultVisible = false\n /** 走点动画 */\n private inWalkAnimation = false\n private customVisible: boolean | null = null\n private parent: GuideLineItem\n private plugin: GuideLinePlugin\n private textureHasLoaded = false\n private disposed = false\n private flowAnime = new BetterTween<{ progress: number }>({ progress: 0 }).to({ progress: 1 }).duration(1500).repeat(Infinity)\n /** 缓存 panoGroup 中每个点距离起点的长度 */\n private cacheLengths: number[] = []\n /** 为了让多条路线在高度上错开,每个路线都需要有个额外的 offset */\n private heightOffset = 0\n /** 响应式字体大小管理器 */\n private fontSizeManager = getGlobalResponsiveFontSize()\n /** 当前字体大小 */\n private currentFontSize = getCurrentFontSize()\n /** 字体大小订阅取消函数 */\n private unsubscribeFontSize: (() => void) | null = null\n\n public constructor(five: Five, options: { mode: PluginType.GuideLineModeItemMode; plugin: GuideLinePlugin; parent: GuideLineItem }) {\n this.five = five\n this.mode = options.mode\n this.plugin = options.plugin\n this.parent = options.parent\n this.group.name = 'GuideLineModeItem'\n\n const geometry = new THREE.BufferGeometry()\n // Keep the initial node material layout valid until path geometry arrives.\n geometry.setAttribute('position', new THREE.Float32BufferAttribute(new Float32Array(9), 3))\n geometry.setAttribute('uv', new THREE.Float32BufferAttribute(new Float32Array(6), 2))\n geometry.setDrawRange(0, 0)\n const material = new GuideLineMaterial()\n this.mesh = new THREE.Mesh(geometry, material)\n\n this.mesh.name = 'GuideLineModeItem'\n\n this.group.add(this.mesh)\n\n if (this.mode === 'panorama') {\n this.parent.hooks.on('walkStart', this.onWalkAnimationStart)\n this.parent.hooks.on('walkEnded', this.onWalkAnimationEnd)\n }\n\n this.updateVisible()\n this.onFiveModeChange(this.five.getCurrentState().mode)\n this.onFiveModelShownFloorChange(this.five.model?.shownFloor ?? null)\n\n this.flowAnime.onUpdate(this.onFlowAnimeUpdate)\n\n this.parent.hooks.on('show', this.updateVisible)\n this.parent.hooks.on('hide', this.updateVisible)\n this.plugin.hooks.on('show', this.updateVisible)\n this.plugin.hooks.on('hide', this.updateVisible)\n this.plugin.hooks.on('enable', this.updateVisible)\n this.plugin.hooks.on('disable', this.updateVisible)\n this.plugin.hooks.on('dispose', this.dispose)\n this.five.on('modeChange', this.onFiveModeChange)\n this.five.on('modelShownFloorChange', this.onFiveModelShownFloorChange)\n\n // 监听字体大小变化\n if (typeof this.fontSizeManager === 'object' && 'subscribe' in this.fontSizeManager) {\n this.unsubscribeFontSize = this.fontSizeManager.subscribe((fontSize) => {\n this.currentFontSize = fontSize\n this.updateTagFontSize()\n })\n }\n\n this.five.needsRender = true\n }\n\n /** 自定义展示 */\n public setCustomVisible(visible: boolean | null) {\n if (this.disposed) return this.logError('disposed')\n if (this.customVisible === visible) return\n this.customVisible = visible\n this.updateVisible()\n }\n\n /** 设置默认展示 */\n public setDefaultVisible(visible: boolean) {\n if (this.disposed) return this.logError('disposed')\n if (this.defaultVisible === visible) return\n this.defaultVisible = visible\n this.updateVisible()\n }\n\n public dispose = () => {\n if (this.disposed) return\n this.disposed = true\n this.parent.hooks.off('show', this.updateVisible)\n this.parent.hooks.off('hide', this.updateVisible)\n this.plugin.hooks.off('show', this.updateVisible)\n this.plugin.hooks.off('hide', this.updateVisible)\n this.plugin.hooks.off('enable', this.updateVisible)\n this.plugin.hooks.off('disable', this.updateVisible)\n this.five.off('modeChange', this.onFiveModeChange)\n this.five.off('modelShownFloorChange', this.onFiveModelShownFloorChange)\n // 取消字体大小订阅\n this.unsubscribeFontSize?.()\n this.doHide()\n this.startTagContainer?.plugin.dispose()\n this.endTagContainer?.plugin.dispose()\n }\n\n /** 基础宽、长 */\n public setUnitSize(width: number, length: number) {\n if (this.disposed) return this.logError('disposed')\n this.width = width\n this.unitLength = length\n this.setGeometryByPath(this.path, { width, unit_length: length })\n }\n\n /** 设置缩放 */\n public setScale(scale: number) {\n if (this.disposed) return this.logError('disposed')\n this.scale = scale\n this.setGeometryByPath(this.path, { scale })\n }\n\n /** 通过点位设置线条形状 */\n public setGeometryByPanoGroup(\n _panoGroup: number[],\n options?: CatmullRomCurve3RestParams & PluginType.ExtraRouteData & PluginType.GuideLineGeometryStyle & { skipPanoGroup?: boolean },\n ) {\n if (this.disposed) return this.logError('disposed')\n if (!this.five.work) return this.logError('setPathByPanoGroup: work is not ready')\n const panoGroup = filterAdjacentDistinct(_panoGroup)\n this._panoGroup = panoGroup\n if (options?.skipPanoGroup !== undefined) {\n const positions = options.skipPanoGroup\n ? panoGroup.map((panoIndex) => this.plugin.workUtil.getObserverStandingPosition(panoIndex)).filter(notNil)\n : null\n this.skippedPositions = positions\n }\n const currState = this.five.getCurrentState()\n // 当前的workCode 可能不是沙盘中对应的workCode, 所以需要在使用workCode之前设置一下workUtil中的workCode, 否则沙盘会报错\n const workCode = this.plugin.workUtil.workCode || currState.workCode\n const work = this.five.works.getWork(workCode)\n const path = createPath(panoGroup, work, options)\n this.path = path\n this.setGeometryByPath(path, options)\n }\n\n /** 通过路径设置线条形状 */\n public setGeometryByPath(path: PluginType.PathItem[], options?: PluginType.GuideLineGeometryStyle) {\n if (this.disposed) return this.logError('disposed')\n\n const scale = options?.scale ?? this.scale\n const width = options?.width ?? this.width\n const unitLength = options?.unit_length ?? this.unitLength\n this.scale = scale\n this.width = width\n this.unitLength = unitLength\n const { geometry, maxV, curvePath, curvePoints } = createLineGeometry({\n path,\n width: width * scale,\n unitLength: unitLength * scale,\n skipPositions: this.skippedPositions,\n })\n this._curvePath = curvePath\n this._curvePoints = curvePoints\n this.mesh.geometry.copy(geometry)\n this.mesh.material.needsUpdate = true\n this.mesh.material.maxV.value = maxV\n\n this.five.needsRender = true\n\n this.path = path\n this.geometryStyle = { ...this.geometryStyle, ...options }\n }\n\n /** 设置线条材质 */\n public setMartial(options?: PluginType.GuideLineMaterialStyle) {\n if (this.disposed) return this.logError('disposed')\n this.setDefaultVisible(options?.visible ?? false)\n this.setColor(options?.color ?? '#ffffff')\n this.setOpacity(options?.opacity ?? 0.5)\n const fallbackUrl = replaceStaticPrefix(this.plugin.staticPrefix, GUIDELINE_DEFAULT_ARROW_TEXTURE)\n this.setTextureUrl(options?.texture?.url ?? fallbackUrl)\n if (options?.background_color !== undefined) this.setBackgroundColor(options.background_color)\n if (options?.background_opacity !== undefined) this.setBackgroundOpacity(options.background_opacity)\n if (options?.border_color !== undefined) this.setBorderColor(options.border_color)\n if (options?.border_opacity !== undefined) this.setBorderOpacity(options.border_opacity)\n if (options?.border_width !== undefined) this.setBorderWidth(options.border_width)\n if (options?.background_clip !== undefined) this.setBackgroundClip(options.background_clip)\n\n const nextMaterialStyle = { ...this.materialStyle, ...options }\n this.materialStyle = nextMaterialStyle\n }\n\n /** 设置模型状态 */\n public setMeshStyle(options?: PluginType.GuideLineMeshStyle) {\n if (options?.translate) {\n const position = new THREE.Vector3()\n const translateVector = new THREE.Vector3().fromArray(options.translate)\n translateVector.y += this.heightOffset\n position.add(translateVector)\n this.group.position.copy(position)\n applyTagTranslate(this.startTagContainer, translateVector)\n applyTagTranslate(this.endTagContainer, translateVector)\n }\n const nextMeshStyle = { ...this.meshStyle, ...options }\n this.meshStyle = nextMeshStyle\n\n function applyTagTranslate(tagContainer: GuideLineTagContainer | undefined, translate: THREE.Vector3) {\n if (!tagContainer?.tag) return\n const tagPositionVector = new THREE.Vector3().fromArray(tagContainer.tag.position)\n tagPositionVector.add(translate)\n const tagPosition = tagPositionVector.toArray()\n tagContainer.plugin.changeTagById(tagContainer.tag.id, { position: tagPosition })\n }\n }\n\n /** 设置 Y 轴上的偏移量,为了让多条路线在高度上错开,每个路线都需要有个额外的 offset */\n public setHeightOffset(offset: number) {\n const position = new THREE.Vector3()\n if (this.meshStyle.translate) position.add(new THREE.Vector3().fromArray(this.meshStyle.translate))\n position.setY(position.y + offset)\n this.group.position.copy(position)\n this.heightOffset = offset\n this.five.needsRender = true\n }\n\n /** 设置贴图颜色 */\n public setColor(color: null | string) {\n if (this.disposed) return this.logError('disposed')\n if (color) {\n this.mesh.material.mapColor.value.set(color)\n }\n this.mesh.material.useMapColor.value = color ? 1 : 0\n this.five.needsRender = true\n }\n\n /** 设置边框 */\n public setBorderColor(color: string) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.borderColor.value.set(color)\n this.five.needsRender = true\n }\n\n /** 设置边框透明度 */\n public setBorderOpacity(opacity: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.borderOpacity.value = opacity\n this.five.needsRender = true\n }\n\n public setBackgroundClip(backgroundClip: PluginType.GuideLineMaterialStyle['background_clip']) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.backgroundClip.value = backgroundClip === 'border-box' ? 0 : 1\n this.five.needsRender = true\n }\n\n /**\n * @description: 设置边框宽度\n */\n public setBorderWidth(width: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.borderWidth.value = width\n this.five.needsRender = true\n }\n\n /** 设置背景颜色 */\n public setBackgroundColor(color: string) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.backgroundColor.value.set(color)\n this.five.needsRender = true\n }\n\n /** 设置背景透明度 */\n public setBackgroundOpacity(opacity: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.backgroundOpacity.value = opacity\n this.five.needsRender = true\n }\n\n /** 设置整体透明度 */\n public setOpacity(opacity: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.opacity = opacity\n this.five.needsRender = true\n }\n\n /** 设置贴图透明度 */\n public setMapOpacity(opacity: number) {\n if (this.disposed) return this.logError('disposed')\n this.mesh.material.mapOpacity.value = opacity\n this.five.needsRender = true\n }\n\n /** 设置贴图 */\n public setTextureUrl(url: string) {\n if (this.disposed) return this.logError('disposed')\n this.textureUrl = url\n loadTexture(url).then((texture) => {\n if (this.disposed) return\n if (this.textureUrl !== url) return\n texture.wrapT = THREE.RepeatWrapping\n this.textureHasLoaded = true\n this.mesh.material.mapNode.value = texture\n this.mesh.material.needsUpdate = true\n this.five.needsRender = true\n this.updateVisible()\n })\n }\n\n public setVisibleFloorIndexes(floorIndexes: number[]) {\n if (this.disposed) return this.logError('disposed')\n this._visibleFloorIndexes = floorIndexes\n this.onFiveModelShownFloorChange(this.five.model?.shownFloor ?? null)\n }\n\n public setStartTag(tag: Tag | PluginType.ModelGuideLineTagData | null) {\n this.startTagData = tag\n this.setTag('start', tag)\n }\n\n public setEndTag(tag: Tag | PluginType.ModelGuideLineTagData | null) {\n this.endTagData = tag\n this.setTag('end', tag)\n }\n\n /** 更新 tag 的距离显示(当 formatDistance 函数改变时调用) */\n public updateTagDistance() {\n if (!this.curvePath) return\n if (this.startTagData) this.setTag('start', this.startTagData)\n if (this.endTagData) this.setTag('end', this.endTagData)\n }\n\n /** 闪烁 */\n public flicker() {\n if (this.disposed) return this.logError('disposed')\n blink([this.group, this.startTagContainer?.plugin?.tags[0]?.dom, this.endTagContainer?.plugin?.tags[0]?.dom].filter(Boolean), {\n loop: 6,\n updateRender: () => {\n this.five.needsRender = true\n },\n })\n }\n\n /** 求起点到 panoIndex 曲线长度\n * @param index panoIndex 在 panoGroup 中的索引\n *\n * @description 为什么不使用 panoIndex 作为参数?\n * - panoIndex 在一个曲线中可能出现多次,无法确定是哪一个。\n */\n public getLengthByPanoGroupIndex(index: number) {\n if (this.disposed) return this.logError('disposed')\n // 优先使用缓存\n if (this.cacheLengths.length !== 0) return this.cacheLengths[index]\n\n this.cacheLengths = this.getPanoGroupLengths()\n return this.cacheLengths[index]\n }\n\n private getPanoGroupLengths() {\n if (!this.curvePoints || !this.curvePath) return []\n const curvePointsLength = this.curvePoints.length\n const curveLength = this.curvePath?.getLength() ?? 0\n const divisions = curvePointsLength - 1\n const divisionLength = curveLength / divisions\n const curveLengths = this.curvePath?.getLengths(divisions) ?? []\n\n const lengths: number[] = []\n let observerGroupIndex = 0\n\n for (let i = 0; i < curvePointsLength; i++) {\n const currentCurvePoint = this.curvePoints[i]\n const standingPosition = this.plugin.workUtil.getObserverStandingPosition(observerGroupIndex)\n if (!standingPosition) break\n // Y 值都设置成 0,消除 Y 轴影响\n const distance = standingPosition.clone().setY(0).distanceTo(currentCurvePoint.clone().setY(0))\n if (distance < divisionLength) {\n lengths.push(curveLengths[i])\n observerGroupIndex += 1\n }\n }\n\n return lengths\n }\n\n private setTag(type: 'start' | 'end', _tag: Tag | PluginType.ModelGuideLineTagData | null) {\n const curvePath = this.curvePath\n if (!_tag?.data) {\n return\n }\n const tagContainer =\n type === 'start'\n ? this.startTagContainer ??\n (() => {\n this.startTagContainer = { tag: null, plugin: new PanoTagPluginController(this.five, { containerZIndex: 10 }) }\n return this.startTagContainer\n })()\n : this.endTagContainer ??\n (() => {\n this.endTagContainer = { tag: null, plugin: new PanoTagPluginController(this.five, { containerZIndex: 10 }) }\n return this.endTagContainer\n })()\n const baseTag: Omit<Tag<'Custom', '2DPoint'>, 'id' | 'position'> = {\n contentType: 'Custom',\n stickType: '2DPoint',\n config: { visibleConfig: { visibleFiveMode: ['Floorplan', 'Mapview'], followModelVisibility: false } },\n style: { point: { enabled: false } },\n data: {},\n }\n const tag = objectAssignDeep({}, baseTag, _tag) as Tag<'Custom', '2DPoint'>\n tagContainer.tag = tag\n if (isModelTag(tag)) {\n tagContainer.tag.element = (container) => {\n tagContainer.app?.destroy()\n const distanceInMeter = curvePath?.getLength() ?? 0\n const i18n = this.plugin.config.i18n ?? ((v: string) => v)\n const formattedDistance = this.plugin.config.formatDistance\n ? this.plugin.config.formatDistance(distanceInMeter)\n : `${i18n('全程')}${Math.round(distanceInMeter)}${i18n('米')}`\n const props =\n type === 'start' ? { ...tag.data, name: this.name, distance: formattedDistance } : tag.data\n const app = mountComponent(CustomTag, container, { fontSize: this.currentFontSize, ...props })\n tagContainer.app = app\n return () => app.destroy()\n }\n }\n tagContainer.plugin.load({ tagList: [tagContainer.tag] })\n const translate = this.meshStyle.translate\n if (translate && tag.position) {\n const position = new THREE.Vector3().fromArray(tag.position)\n const translateVector = new THREE.Vector3().fromArray(translate)\n position.add(translateVector)\n position.y += this.heightOffset\n const tagPosition = position.toArray()\n tagContainer.plugin.changeTagById(tagContainer.tag.id, { position: tagPosition })\n }\n }\n\n /** 开始走点动画 */\n private onWalkAnimationStart = () => {\n this.inWalkAnimation = true\n this.updateVisible()\n }\n\n /** 结束走点动画 */\n private onWalkAnimationEnd = () => {\n this.inWalkAnimation = false\n this.updateVisible()\n }\n\n /** 模型状态变更 */\n private onFiveModeChange = (mode: Mode) => {\n this.modeVisible = this.mode === 'panorama' ? isPanoramaLike(mode) : isModelLike(mode)\n this.updateVisible()\n }\n\n private onFiveModelShownFloorChange = (floor: number | null) => {\n this.floorVisible = floor === null || this.visibleFloorIndexes === null || this.visibleFloorIndexes.includes(floor)\n this.updateVisible()\n }\n\n /** 更新可见性 */\n private updateVisible = () => {\n const visible = (() => {\n if (!this.parent.visible) return false\n if (!this.plugin.state.enabled) return false\n if (!this.plugin.state.visible) return false\n if (this.customVisible !== null) return this.customVisible\n if (this.inWalkAnimation) return true\n return this.modeVisible && this.defaultVisible && this.floorVisible\n })()\n\n this.visible = visible\n\n visible && this.textureHasLoaded ? this.doShow() : this.doHide()\n }\n\n private doShow() {\n if (this.mode === 'model' && !this.flowAnime.isPlaying()) {\n this.flowAnime.play()\n }\n this.five.scene.add(this.group)\n this.startTagContainer?.plugin.show()\n this.endTagContainer?.plugin.show()\n this.five.needsRender = true\n }\n\n private doHide() {\n if (this.mode === 'model') {\n this.flowAnime.stop()\n }\n this.five.scene.remove(this.group)\n this.startTagContainer?.plugin.hide()\n this.endTagContainer?.plugin.hide()\n this.five.needsRender = true\n }\n\n private onFlowAnimeUpdate = (options: { progress: number }) => {\n const { progress } = options\n this.mesh.material.vOffset.value = progress\n this.five.needsRender = true\n }\n\n private logError = (msg: string) => logError('GuideLineModeItem: ', msg)\n\n /** 更新标签字体大小 */\n private updateTagFontSize = () => {\n // 更新开始标签\n if (this.startTagContainer?.app) {\n this.startTagContainer.app.update({ fontSize: this.currentFontSize })\n }\n // 更新结束标签\n if (this.endTagContainer?.app) {\n this.endTagContainer.app.update({ fontSize: this.currentFontSize })\n }\n }\n}\n\nfunction isModelTag(tag: Tag<any, any>): tag is PluginType.ModelGuideLineTag {\n return tag.contentType === 'Custom'\n}\n\nexport { GuideLineModeItem }\n","import type { Five, State } from '@realsee/five-webgpu'\nimport type { BaseOptions } from '../base/BasePlugin'\nimport type { GuideLinePluginExportType } from '../GuideLinePlugin'\nimport * as BasePlugin from '../base/BasePlugin'\nimport type { PluginState, EventMap, MoveEffect } from './typing'\nimport { equal } from '../shared-utils'\nimport type { PartialDeep } from 'type-fest'\nimport objectAssignDeep from 'object-assign-deep'\nimport { FiveUtil } from '../shared-utils/Utils/FiveUtil'\n\nconst PLUGIN_NAME = 'CruisePlugin'\n\nconst PLUGIN = `${PLUGIN_NAME}`\n\nexport const pluginFlag = (name: string) => `${PLUGIN}--${name}`\n\nexport default abstract class CruiseController<PluginData, Config = unknown> extends BasePlugin.Controller<PluginState, EventMap> {\n public state: PluginState = {\n visible: true,\n enabled: true,\n disposed: false,\n playing: false,\n speed: 1,\n }\n\n protected data?: PluginData & { id: string | number }\n\n protected config?: Config\n\n protected pauseDataMap = new Map<\n string | number,\n { fiveState: Partial<State>; id?: string | number; playedProgress: number; duration?: number }\n >()\n\n protected privateState: {\n /**\n * privateState.playing 和 state.playing 的区别:\n * state.playing 先为true,然后才 handleplay,handleplay方法内会检查privateState.playing,如果已经开始(privateState.playing === true),就不执行操作,如果为false,就执行操作\n * 其实就是加了一个不允许重复执行handleplay的逻辑\n */\n playing: boolean\n broke: boolean\n playId?: string\n moveToFirstPanoEffect?: MoveEffect\n moveToFirstPanoDuration?: number\n modeChanging?: boolean\n } = {\n playing: false,\n broke: false,\n modeChanging: false,\n }\n\n protected GuideLine?: GuideLinePluginExportType\n\n public constructor(five: Five, config?: Config) {\n super(five, config)\n this.config = config\n }\n\n /**\n * @description Play | Continue play. if have been paused, continue play from the pause position; if playing, do nothing\n */\n public play(options?: { userAction?: boolean }): void {\n this.setState({ playing: true }, options)\n }\n\n /**\n * @description Pause\n */\n public pause(options?: { userAction?: boolean }) {\n this.setState({ playing: false }, options)\n }\n\n /**\n * @description Show guide line\n */\n public async show(options?: { userAction?: boolean }) {\n this.setState({ visible: true }, options)\n }\n\n /**\n * @description Hide guide line\n */\n public async hide(options?: { userAction?: boolean }) {\n this.setState({ visible: false }, options)\n }\n\n /**\n * @description Enable\n */\n public enable(options?: { userAction?: boolean }) {\n this.setState({ enabled: true }, options)\n }\n\n /**\n * @description Disable\n */\n public disable(options?: { userAction?: boolean }) {\n this.setState({ enabled: false }, options)\n }\n\n /**\n * @description Dispose\n */\n public dispose() {\n if (this.state.disposed) return\n this.setState({ disposed: true })\n }\n\n /**\n * @description Set state\n */\n public setState(state: PartialDeep<PluginState>, options?: BaseOptions & Record<string, any>): void {\n if (this.state.disposed) return this.disposedErrorLog()\n if (!this.state.enabled) {\n // when plugin is disabled, only can change enabled or disposed to true\n if (state.enabled !== true && state.disposed !== true) return this.disableErrorLog()\n }\n const prevState = { ...this.state }\n this.state = objectAssignDeep({}, this.state, state)\n if (state.disposed !== undefined && state.disposed !== prevState.disposed) {\n if (state.disposed) this.handleDispose()\n }\n if (state.visible !== undefined && state.visible !== prevState.visible) {\n this.handleVisible(state.visible, options?.userAction)\n }\n if (state.enabled !== undefined && state.enabled !== prevState.enabled) {\n this.handleEnable(state.enabled, options?.userAction)\n }\n if (state.playing !== undefined && state.playing !== prevState.playing) {\n this.changePlayState(state.playing, options)\n }\n if (state.speed !== undefined && state.speed !== prevState.speed) {\n this.changeSpeed(state.speed)\n }\n\n if (!equal(prevState, this.state, { deep: true })) {\n this.hooks.emit('stateChange', { state: this.state, prevState, userAction: options?.userAction ?? true })\n }\n }\n\n /**\n * @description Clear pause data\n */\n protected clearPauseData() {\n if (this.data?.id) return this.pauseDataMap.delete(this.data?.id)\n }\n\n protected changePlayState(play: boolean, options?: { userAction?: boolean; playFromIndex?: number; playFromId?: string }) {\n this.actionIfStateIsEnabled(() =>\n this.hooks.emit('playStateChange', play ? 'playing' : 'pause', { userAction: options?.userAction ?? true }),\n )\n this.state.playing = play\n play ? this.handlePlay(options) : this.handlePause(options)\n }\n\n protected handleEnable(enabled: boolean, userAction = true) {\n if (enabled) {\n this.GuideLine?.enable()\n this.hooks.emit('enable', { userAction })\n } else {\n this.GuideLine?.disable()\n this.changePlayState(false, { userAction })\n this.hooks.emit('disable', { userAction })\n }\n this.state.enabled = enabled\n }\n\n protected handleVisible(visible: boolean, userAction = true) {\n if (visible) {\n this.GuideLine?.show()\n this.actionIfStateIsEnabled(() => this.hooks.emit('show', { userAction }))\n } else {\n this.GuideLine?.hide()\n this.actionIfStateIsEnabled(() => this.hooks.emit('hide', { userAction }))\n }\n this.state.visible = visible\n }\n\n /**\n * @description: listen interupted by five gesture\n */\n protected addInterruptListener(interrupt: () => void) {\n const wantsChangeModeHandler = () => {\n if (!this.privateState.modeChanging) interrupt()\n }\n\n const handleGesture = (type: string) => {\n if (type !== 'mouseMove') {\n interrupt()\n this.five.off('gesture', handleGesture)\n }\n }\n\n this.five.on('gesture', handleGesture)\n this.five.once('wantsChangeMode', wantsChangeModeHandler)\n return () => {\n this.five.off('gesture', handleGesture)\n this.five.off('wantsChangeMode', wantsChangeModeHandler)\n }\n }\n\n /**\n * @description Get duration by speed\n */\n protected getSpeededDuration(duration: number) {\n return duration / this.state.speed\n }\n\n /**\n * @description Force interupt five updateCamera\n */\n protected forceInteruptUpdateCamera() {\n const longitude = this.five.getCurrentState().longitude + 0.005\n this.five.updateCamera(\n {\n longitude: longitude,\n },\n 0,\n true,\n )\n }\n\n protected getPauseData() {\n if (this.data?.id) return this.pauseDataMap.get(this.data.id)\n }\n\n /**\n * @description Set pause data\n */\n protected setPauseData() {\n const id = this.data?.id\n if (id)\n return this.pauseDataMap.set(id, {\n fiveState: this.five.getCurrentState(),\n playedProgress: this.getProgress(),\n })\n }\n\n /**\n * @description: Restore state that before loaded\n */\n protected clear() {\n this.clearPauseData()\n }\n\n // TODO\n protected handleDispose() {\n this.state.playing = false\n this.clearPauseData()\n this.clear()\n this.GuideLine?.dispose()\n this.GuideLine = undefined\n }\n\n /**\n * @description Action function if plugin is enable\n */\n protected actionIfStateIsEnabled<T = any>(func: () => T, options?: { warnLog?: true }) {\n if (this.state.enabled) return func()\n else {\n if (options?.warnLog) this.disableWarnLog()\n }\n }\n\n protected disposedErrorLog = () => {\n console.error(`${PLUGIN} is disposed`)\n }\n\n protected disableWarnLog = () => {\n console.warn(`${PLUGIN} is disabled`)\n }\n\n protected disableErrorLog = () => {\n console.error(`${PLUGIN} is disabled`)\n }\n\n /**\n * @description Load Data and State\n */\n public abstract load(serverData: unknown, state?: PluginState, userAction?: boolean): Promise<void>\n\n /**\n * @description Play from first keyframe\n */\n public abstract playFromStart(): void\n\n /**\n * @description Play | Continue play. if have been paused, continue play from the pause position; if playing, do nothing\n * @param {number} options.playFromIndex play from keyframes index\n * @param {string} options.playFromId play from keyframes id\n */\n protected abstract handlePlay(options?: {\n userAction?: boolean\n playFromIndex?: number\n playFromId?: string\n notEmitEvent?: true\n }): Promise<string>\n\n /**\n * @description: Change play speed\n */\n protected abstract changeSpeed(speed: number): void\n\n /**\n * @description Get ratate progress\n */\n protected abstract getProgress(): number\n\n /**\n * @description: Pause and record pause state\n */\n protected abstract handlePause(options?: { userAction?: boolean; notEmitEvent?: true }): void\n}\n","import * as THREE from 'three/webgpu'\nimport { vectorToCoordinates } from '../../shared-utils/vectorToCoordinate'\n\n\nexport function getFiveStateOnCurve(\n curve: THREE.Curve<THREE.Vector3>,\n progress: number,\n curveOffset: Partial<{ x: number; y: number; z: number }>,\n) {\n const offset = new THREE.Vector3().fromArray([curveOffset.x ?? 0, curveOffset.y ?? 0, curveOffset.z ?? 0])\n const position = curve.getPointAt(progress).clone().add(offset)\n const tangent = curve.getTangentAt(progress)\n const { longitude, latitude } = vectorToCoordinates(tangent)\n return { offset: position.clone(), longitude, latitude, distance: 0 }\n}\n","import type { Five } from '@realsee/five-webgpu'\nimport CruiseController from './BaseController'\nimport objectAssignDeep from 'object-assign-deep'\nimport type { Config, GuideLineConfig, PluginState } from './typing'\nimport type { PartialDeep } from 'type-fest'\nimport * as THREE from 'three/webgpu'\nimport { uuid } from '../shared-utils'\nimport { getFiveStateOnCurve } from './utils/getFiveStateOnCurve'\nimport { anyPositionToVector3, type AnyPosition } from '../shared-utils/positionToVector3'\nimport GuideLinePlugin from '../GuideLinePlugin'\n\ninterface Data extends GuideLineConfig {\n /**\n * @description: 组成路径的空间坐标点\n */\n path: THREE.CurvePath<THREE.Vector3> | AnyPosition[]\n /**\n * @description: 漫游镜头偏移量,注意会与插件初始化时的 config.offset 叠加\n * @default: { x: 0, y: 0, z: 0 }\n */\n offset?: Partial<{ x: number; y: number; z: number }>\n}\n\nexport interface MoveConfig extends Config {\n /**\n * @description: 漫游时镜头基于路径的偏移量\n * @default: { x: 0, y: 2, z: 0 }\n */\n offset?: Partial<{ x: number; y: number; z: number }>\n /**\n * @description: 滑动屏幕时允许打断漫游\n * @default: true\n */\n allowBroke?: boolean\n}\n\nexport default class MoveController extends CruiseController<Data, MoveConfig> {\n private curve: THREE.Curve<THREE.Vector3>\n private baseCurveOffset: { x: number; y: number; z: number }\n private curveOffset: Partial<{ x: number; y: number; z: number }>\n private playStartedTime = performance.now()\n private duration: number | null\n\n public constructor(five: Five, config?: MoveConfig) {\n super(five, config)\n\n const defaultState: PartialDeep<PluginState> = {\n config: {\n speedConfig: {\n moveSpeed: 2,\n moveSpeedUnit: 'm/s',\n },\n },\n }\n\n const defaultConfig: PartialDeep<MoveConfig> = {\n allowBroke: true,\n }\n\n this.state = objectAssignDeep({}, defaultState, this.state)\n this.config = objectAssignDeep({}, defaultConfig, this.config)\n this.baseCurveOffset = objectAssignDeep({ x: 0, y: 0, z: 0 }, { y: 2 }, this.config?.offset)\n }\n\n public load(data: Data, state?: PartialDeep<PluginState>): Promise<void> {\n // 暂停\n this.handlePause()\n // 清空数据\n this.clear()\n\n this.data = { id: uuid(), ...data }\n\n const curve = (() => {\n if (this.data.path instanceof THREE.Curve) {\n return this.data.path.curves[0]\n } else {\n if (this.data.path.length < 2) return null\n const vectors = this.data.path.map(anyPositionToVector3)\n return new THREE.CatmullRomCurve3(vectors, undefined, 'catmullrom', 0.5)\n }\n })()\n\n if (!curve) return\n\n this.curve = curve\n this.curveOffset = {\n x: this.baseCurveOffset.x + (this.data.offset?.x ?? 0),\n y: this.baseCurveOffset.y + (this.data.offset?.y ?? 0),\n z: this.baseCurveOffset.z + (this.data.offset?.z ?? 0),\n }\n if (!this.curve) {\n throw new Error('curve is not defined')\n }\n const curveLength = this.curve.getLength()\n const baseMoveSpeed = this.state.config.speedConfig.moveSpeedUnit === 'm/ms' ? 1 : 1000\n this.duration = curveLength / (this.state.config.speedConfig.moveSpeed / baseMoveSpeed)\n\n if (Array.isArray(this.data.path)) {\n const points = this.data.path.map(anyPositionToVector3).map((point) => point.toArray())\n // initialize GuideLinePlugin\n if (\n !this.GuideLine &&\n ((this.config?.useGuideLine !== false && data.useGuildLine) || (this.config?.useGuideLine && data.useGuildLine !== false))\n )\n this.GuideLine = GuideLinePlugin(this.five, this.config)\n\n // load GuideLine\n this.GuideLine?.load({\n lines: [\n {\n id: uuid(),\n path: [{ type: 'CatmullRomCurve3', points: points }],\n model_style: { visible: true },\n },\n ],\n })\n }\n\n // initialize plugin state\n if (state) {\n this.setState(state)\n } else {\n // first pause\n this.setState({ playing: false })\n\n // set state\n this.handleVisible(this.state.visible)\n this.handleEnable(this.state.enabled)\n this.changePlayState(this.state.playing)\n this.changeSpeed(this.state.speed)\n }\n\n return Promise.resolve()\n }\n\n public changeSpeed = (speed: number, userAction = true) => {\n this.state.speed = speed\n this.hooks.emit('speedChange', speed, { userAction })\n }\n\n public moveToStart = () => {\n this.five.setState({ ...getFiveStateOnCurve(this.curve, 0, this.curveOffset), mode: 'Model' })\n }\n\n public playFromStart = () => {\n this.clearPauseData()\n this.setState({ playing: true })\n }\n\n protected getDuration = () => {\n return this.getSpeededDuration(this.duration)\n }\n\n protected getProgress = () => {\n const pauseData = this.getPauseData()\n let playedProgress = pauseData?.playedProgress ?? 0\n if (playedProgress < 0 || playedProgress >= 1) {\n playedProgress = 0\n }\n const lastProgress = 1 - playedProgress // 剩余的进度\n\n const duration = this.getDuration()\n const currentTime = performance.now()\n const progress = (currentTime - this.playStartedTime) / duration\n return 1 - lastProgress + progress\n }\n\n protected handlePlay(): Promise<string> {\n\n return new Promise(async (resolve, reject) => {\n this.hooks.emit('play', { userAction: true })\n // 恢复暂停状态\n const pauseData = this.getPauseData()\n let progress = pauseData?.playedProgress ?? 0\n if (progress < 0 || progress >= 1) {\n progress = 0\n }\n const state = getFiveStateOnCurve(this.curve, progress, this.curveOffset)\n\n this.hooks.emit('progressChange', progress)\n this.five.setState({ ...state, mode: 'Model' })\n await this.five.ready()\n\n this.playStartedTime = performance.now()\n\n // 是否允许中断\n if (this.config.allowBroke) {\n const disposer = this.addInterruptListener(() => {\n if (this.state.playing) {\n this.hooks.emit('broke')\n this.handlePause()\n disposer()\n reject(new Error('broke'))\n }\n })\n }\n\n const onRenderFrame = () => {\n const progress = this.getProgress()\n if (progress >= 1) {\n this.five.off('renderFrame', onRenderFrame)\n this.setState({ playing: false }, { userAction: false })\n this.hooks.emit('end')\n this.hooks.emit('progressChange', 1)\n resolve('end')\n } else if (this.state.playing === false) {\n this.five.off('renderFrame', onRenderFrame)\n } else if (progress >= 0) {\n const state = getFiveStateOnCurve(this.curve, progress, this.curveOffset)\n this.hooks.emit('progressChange', progress)\n this.five.setState(state, true)\n }\n }\n\n this.five.on('renderFrame', onRenderFrame)\n })\n }\n\n protected handlePause(options?: { userAction?: boolean }) {\n this.state.playing = false\n this.hooks.emit('pause', { userAction: options?.userAction ?? true })\n this.setPauseData()\n }\n}\n","import type { Five, Mode } from '@realsee/five-webgpu'\nimport type GuideLinePlugin from './Controller'\nimport type * as PluginType from './typing'\nimport { GuideLineModeItem } from './GuideLineModeItem'\nimport type { CruisePluginTypes } from '../CruisePlugin'\nimport { logError } from '../shared-utils/log'\nimport to from '../shared-utils/to'\nimport changeMode from '../shared-utils/five/changeMode'\nimport MoveController from '../CruisePlugin/Move'\nimport WalkController from '../CruisePlugin/Work'\nimport { Subscribe } from '../shared-utils/Subscribe'\n\n/** 路线引导实例。\n * - 路线包括两个部分:全景路线和模型路线。\n * - Five 切换模态时,路线会自动切换。\n * - GuideLineItem P\n */\nclass GuideLineItem {\n public readonly id: string | number\n public readonly renderID?: string\n public readonly isGuideLine = true\n public readonly panoramaItem: GuideLineModeItem\n public readonly modelItem: GuideLineModeItem\n public readonly hooks = new Subscribe<PluginType.GuideLineItemEventMap>()\n public get visible() {\n return this._visible\n }\n private _visible = true\n private plugin: GuideLinePlugin\n private five: Five\n\n public constructor(options: { five: Five; id: string | number; plugin: GuideLinePlugin }) {\n this.id = options.id\n this.five = options.five\n this.plugin = options.plugin\n this.panoramaItem = new GuideLineModeItem(this.five, { mode: 'panorama', plugin: this.plugin, parent: this })\n this.modelItem = new GuideLineModeItem(this.five, { mode: 'model', plugin: this.plugin, parent: this })\n }\n\n public setData(data: PluginType.GuideLineItem) {\n this.setDataByMode('panorama', data)\n this.setDataByMode('model', data)\n }\n\n public setDataByMode(mode: PluginType.GuideLineModeItemMode, data: PluginType.GuideLineItem) {\n const item = mode === 'panorama' ? this.panoramaItem : this.modelItem\n const style = mode === 'panorama' ? data.panorama_style : data.model_style\n const path = data.path\n const geometryStyle: PluginType.GuideLineGeometryStyle = style\n const materialStyle: PluginType.GuideLineMaterialStyle = style\n const meshStyle: PluginType.GuideLineMeshStyle = style\n if (data.pano_group) {\n const skipPanoGroup = mode === 'panorama' && data.panorama_style.skip_group === true\n item.setGeometryByPanoGroup(data.pano_group, { ...data, skipPanoGroup, ...geometryStyle })\n } else if (data.path) {\n item.setGeometryByPath(path, { ...geometryStyle })\n }\n item.name = data.name\n item.setMeshStyle(meshStyle)\n item.setMartial(materialStyle)\n item.setVisibleFloorIndexes(data.visible_floor_indexes ?? null)\n item.setStartTag(style?.start_tag)\n item.setEndTag(style?.end_tag)\n }\n\n public show() {\n this._visible = true\n this.hooks.emit('show', { userAction: true })\n }\n\n public hide() {\n this._visible = false\n this.hooks.emit('hide', { userAction: true })\n }\n\n public dispose() {\n this.panoramaItem.dispose()\n this.modelItem.dispose()\n }\n\n public async walk(options?: CruisePluginTypes.MoveAction) {\n this.hooks.emit('walkStart', { userAction: true })\n if (this.panoramaItem.panoGroup.length) {\n const walkData = { panoIndexList: this.panoramaItem.panoGroup, ...options }\n const [error] = await to(walk(this.five, walkData))\n if (error) return this.logError(error.message)\n } else {\n const walkData = { path: this.panoramaItem.curvePath }\n const [error] = await to(move(this.five, walkData))\n if (error) return this.logError(error.message)\n }\n this.hooks.emit('walkEnded', { userAction: true })\n }\n\n private logError = (msg: string) => logError('GuideLineItem: ', msg)\n}\n\nasync function move(five: Five, data: any) {\n const plugin = new MoveController(five)\n await plugin.load(data)\n plugin.playFromStart()\n}\n\nasync function walk(five: Five, data: CruisePluginTypes.MoveWithPanoIndexAction) {\n if (data.panoIndexList.length === 0) return\n const fiveCurrentState = five.getCurrentState()\n if (fiveCurrentState.mode !== 'Panorama') {\n await changeMode(five, ['Panorama', { longitude: fiveCurrentState.longitude, latitude: 0, panoIndex: data.panoIndexList[0] }])\n }\n const plugin = new WalkController(five)\n await plugin.load(data)\n await new Promise<void>((resolve, reject) => {\n const fiveCurrentState = five.getCurrentState()\n let panoIndexList = data.panoIndexList.slice()\n if (fiveCurrentState.panoIndex === panoIndexList[0]) onFivePanoArrived(fiveCurrentState.panoIndex)\n\n plugin.playFromStart()\n\n function onFiveModeChange(mode: Mode) {\n if (mode !== 'Panorama') return onReject(new Error('mode not match'))\n }\n\n function onFivePanoArrived(panoIndex: number) {\n const wantedPanoIndex = panoIndexList[0]\n panoIndexList = panoIndexList.slice(1)\n if (panoIndex !== wantedPanoIndex)\n return onReject(new Error('panoIndex not match, wanted: ' + wantedPanoIndex + ', got: ' + panoIndex))\n if (panoIndexList.length === 0) return onResolve()\n }\n\n function removeListeners() {\n five.off('modeChange', onFiveModeChange)\n five.off('panoArrived', onFivePanoArrived)\n }\n\n function onReject(error: Error) {\n removeListeners()\n reject(error)\n }\n\n function onResolve() {\n removeListeners()\n resolve()\n }\n\n five.on('modeChange', onFiveModeChange)\n five.on('panoArrived', onFivePanoArrived)\n })\n}\n\nexport { GuideLineItem }\n","import * as BasePluginWithData from '../base/BasePluginWithData'\nimport type { Five } from '@realsee/five-webgpu'\nimport type { EventMap, PluginData, PluginServerData, PluginState } from './typing'\nimport type * as PluginType from './typing'\nimport { equal, replaceStaticPrefix } from '../shared-utils'\nimport type { Config as BaseConfig } from '../base/BasePlugin'\nimport { GuideLineItem } from './GuideLineItem'\nimport CruisePluginController from '../CruisePlugin/Work'\nimport objectAssignDeep from 'object-assign-deep'\nimport * as THREE from 'three/webgpu'\nimport type { GuideLineTagContainer } from './GuideLineModeItem'\nimport { uuid } from '../shared-utils'\nimport { waitFiveModelLoaded } from '../shared-utils/five/fiveModelLoad'\nimport { GUIDELINE_DEFAULT_ARROW_TEXTURE, GUIDELINE_WHITE_ARROW_TEXTURE } from '../shared-utils'\n\nconst PLUGIN_NAME = 'GuideLinePlugin'\n\nconst PLUGIN = `${PLUGIN_NAME}`\n\nexport const pluginFlag = (name: string) => `${PLUGIN}--${name}`\n\ntype Config = BaseConfig & {\n /**\n * @description 格式化距离函数,用于将米转换为显示文本(包含单位)\n * @param distanceInMeter 距离(单位:米)\n * @returns 格式化后的距离字符串,例如 \"10m\" 或 \"32'10\"\"\n */\n formatDistance?: (distanceInMeter: number) => string\n}\n\nexport default class Controller extends BasePluginWithData.Controller<PluginState, EventMap, PluginServerData, PluginData> {\n public readonly name = PLUGIN_NAME\n public readonly cruisePlugin: CruisePluginController\n\n /** GuideLineItem 索引 */\n public readonly itemMap = new Map<string | number, GuideLineItem>()\n public get config() {\n return this._config\n }\n\n public state = {\n visible: false,\n enabled: true,\n }\n\n protected data?: PluginData\n\n /** 当新增一根线时,整体高度的偏移值 */\n private heightOffset = 0\n\n public get disposed() {\n return this._disposed\n }\n\n private _config: Config\n\n private _disposed = false\n private loadGeneration = 0\n\n public constructor(five: Five, config?: Config) {\n super(five, config)\n this._config = config ?? {}\n this.cruisePlugin = new CruisePluginController(five)\n }\n\n public async load(serverData: PluginServerData | PluginData, state?: PluginState, userAction = true): Promise<void> {\n if (this.disposed) return\n const generation = ++this.loadGeneration\n const prevData = this.data ? JSON.parse(JSON.stringify(this.data)) : undefined\n\n // format server data to plugin data\n const data = await this.formatData(serverData)\n if (this.disposed || generation !== this.loadGeneration) return\n\n const config = data.config\n const isV1Data = !data.lines && data.routes\n\n // 转换配置中的箭头贴图 URL\n const arrowTextureUrl = config?.arrowTextureUrl ?? replaceStaticPrefix(this.staticPrefix, GUIDELINE_WHITE_ARROW_TEXTURE)\n\n const baseData: Omit<PluginType.GuideLineItem, 'id'> = {\n ...config,\n model_style: {\n texture: { url: arrowTextureUrl },\n },\n panorama_style: {\n visible: isV1Data ? true : false,\n unit_length: config?.unitHeight ?? 0.4,\n width: config?.unitWidth ?? 0.6,\n texture: { url: arrowTextureUrl },\n },\n }\n\n const v1Data =\n data.routes?.map((item) => objectAssignDeep({}, baseData, { id: item.id ?? uuid(), pano_group: item.panoIndexList })) ?? []\n const v2Data = data.lines?.map((item) => objectAssignDeep({}, baseData, item)) ?? []\n const combineData: PluginType.GuideLineItem[] = [...v1Data, ...v2Data]\n\n // wait for five model loaded\n await waitFiveModelLoaded(this.five)\n\n if (this.disposed || generation !== this.loadGeneration) return\n this.clearItems()\n this.data = data\n this.hooks.emit('dataChange', data, prevData)\n combineData.forEach((item) => {\n this.addGuideLineItem(item)\n })\n this.updateTagsEnable()\n\n // set state\n this.handleVisible(this.state.visible)\n this.handleEnable(this.state.enabled)\n\n // initialize plugin state\n if (state) this.setState(state, { userAction })\n\n this.hooks.emit('dataLoaded', data)\n console.debug(`${PLUGIN} loaded`, data)\n }\n\n public async formatData(serverData: any): Promise<PluginType.PluginData> {\n const dataWithoutVersion = this.getDataWithoutVersion(serverData)\n return dataWithoutVersion\n }\n\n /** 展示插件 */\n public async show(options?: { userAction?: boolean }) {\n this.setState({ visible: true }, options)\n }\n\n /** 隐藏插件 */\n public async hide(options?: { userAction?: boolean }) {\n this.setState({ visible: false }, options)\n }\n\n /** 开启插件 */\n public enable(options?: { userAction?: boolean }) {\n this.setState({ enabled: true }, options)\n }\n\n /** 关闭插件 */\n public disable(options?: { userAction?: boolean }) {\n this.setState({ enabled: false }, options)\n }\n\n /** 销毁插件 */\n public dispose() {\n if (this.disposed) return\n this._disposed = true\n this.clear()\n this.cruisePlugin.dispose()\n this.data = undefined\n this.hooks.emit('dispose')\n }\n\n public setState(state: Partial<PluginState>, options?: { userAction?: boolean }) {\n if (this.disposed) return this.disposedErrorLog()\n const prevState = { ...this.state }\n this.state = { ...this.state, ...state }\n if (state.visible !== undefined && state.visible !== prevState.visible) {\n this.handleVisible(state.visible, options?.userAction)\n }\n if (state.enabled !== undefined && state.enabled !== prevState.enabled) {\n this.handleEnable(state.enabled, options?.userAction)\n }\n\n if (!equal(prevState, this.state, { deep: true })) {\n this.hooks.emit('stateChange', { state: this.state, prevState, userAction: options?.userAction ?? true })\n this.five.needsRender = true\n }\n }\n\n /** 添加一个 GuideLineItem */\n public addGuideLineItem(data?: PluginType.GuideLineItem): GuideLineItem {\n const id = data.render_id || data.id\n // remove prev item\n const prevItem = this.itemMap.get(id)\n if (prevItem) this.removeGuideLineItem(prevItem)\n\n const newItem = new GuideLineItem({ five: this.five, id, plugin: this })\n this.itemMap.set(id, newItem)\n if (data) {\n newItem.setData(this.processItemUrls(data))\n }\n // set height offset\n this.heightOffset += 0.0001\n newItem.modelItem.setHeightOffset(this.heightOffset)\n newItem.panoramaItem.setHeightOffset(this.heightOffset)\n\n return newItem\n }\n\n private processItemUrls(item: PluginType.GuideLineItem): PluginType.GuideLineItem {\n const processedItem = { ...item }\n\n // 默认贴图URL\n const defaultTextureUrl = GUIDELINE_DEFAULT_ARROW_TEXTURE\n\n // 处理panorama_style中的贴图URL\n if (processedItem.panorama_style) {\n const textureUrl = processedItem.panorama_style.texture?.url ?? defaultTextureUrl\n processedItem.panorama_style = {\n ...processedItem.panorama_style,\n texture: {\n ...processedItem.panorama_style.texture,\n url: replaceStaticPrefix(this.staticPrefix, textureUrl),\n },\n }\n }\n\n // 处理model_style中的贴图URL\n if (processedItem.model_style) {\n const textureUrl = processedItem.model_style.texture?.url ?? defaultTextureUrl\n processedItem.model_style = {\n ...processedItem.model_style,\n texture: {\n ...processedItem.model_style.texture,\n url: replaceStaticPrefix(this.staticPrefix, textureUrl),\n },\n }\n }\n\n return processedItem\n }\n\n /** 获取 Plugin 内的 GuideLineItem */\n public getGuideLineItemByID(id: string | number) {\n return this.itemMap.get(id)\n }\n\n /** 移除一个 GuideLineItem */\n public removeGuideLineItem(item: GuideLineItem) {\n this.itemMap.delete(item.id)\n\n item.panoramaItem.dispose()\n item.modelItem.dispose()\n }\n\n /**\n * 动态更新距离格式化函数,立即刷新所有路线标签的距离显示。\n * 不传参时恢复为默认格式(i18n('全程') + 距离 + i18n('米'))。\n * @param fn 格式化函数,输入米数,返回带单位的完整字符串\n * @example\n * // 室内英制:英尺 + 英寸(如 \"5'10\"\")\n * plugin.setDistanceFormatter((m) => {\n * const totalInches = Math.round(m * 39.3701)\n * const feet = Math.floor(totalInches / 12)\n * const inches = totalInches % 12\n * return `${feet}'${inches}\"`\n * })\n * // 室外英制:英里(如 \"1.24 mi\")\n * plugin.setDistanceFormatter((m) => `${(m * 0.000621371).toFixed(2)} mi`)\n * // 自动切换:近距离用英尺,远距离用英里\n * plugin.setDistanceFormatter((m) => {\n * if (m < 300) return `${Math.round(m * 3.28084)} ft`\n * return `${(m * 0.000621371).toFixed(2)} mi`\n * })\n * // 恢复默认(i18n '米')\n * plugin.setDistanceFormatter()\n */\n public setDistanceFormatter(fn?: (distanceInMeter: number) => string): void {\n this._config.formatDistance = fn\n this.updateTagDistances()\n }\n\n /** 更新所有 tag 的距离显示(当 formatDistance 函数改变时调用) */\n private updateTagDistances() {\n this.itemMap.forEach((item) => {\n item.panoramaItem.updateTagDistance()\n item.modelItem.updateTagDistance()\n })\n }\n\n /** 全量更新 tag */\n public updateTagsEnable() {\n const enabledTagContainers: GuideLineTagContainer[] = []\n\n function isNumberArray(value: any): value is number[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'number')\n }\n\n function isNear(position1: number[], position2: number[]) {\n return new THREE.Vector3().fromArray(position1).distanceTo(new THREE.Vector3().fromArray(position2)) < 0.01\n }\n\n function getTagEnable(tagContainer: GuideLineTagContainer) {\n const position = tagContainer?.tag?.position\n if (!isNumberArray(position)) return false\n\n return enabledTagContainers.every((enabledTagContainer) => {\n if (!isNumberArray(enabledTagContainer.tag?.position)) return true\n if (isNear(position, enabledTagContainer.tag.position)) return false\n return true\n })\n }\n\n this.itemMap.forEach((item) => {\n const startTagContainer = item.modelItem.startTagContainer\n const endTagContainer = item.modelItem.endTagContainer\n\n if (!startTagContainer && !endTagContainer) return\n\n const startTagEnable = getTagEnable(startTagContainer)\n if (startTagEnable && startTagContainer) enabledTagContainers.push(startTagContainer)\n startTagContainer?.plugin.setState({ enabled: startTagEnable }, {})\n\n const endTagEnable = getTagEnable(endTagContainer)\n if (endTagEnable && endTagContainer) enabledTagContainers.push(endTagContainer)\n endTagContainer?.plugin.setState({ enabled: endTagEnable }, {})\n })\n }\n\n /** 清空所有 GuideLineItem */\n public clear() {\n this.loadGeneration += 1\n this.clearItems()\n }\n\n private clearItems() {\n this.heightOffset = 0\n this.itemMap.forEach((item) => {\n this.removeGuideLineItem(item)\n })\n }\n\n private handleEnable(enabled: boolean, userAction = true): void {\n this.hooks.emit(enabled ? 'enable' : 'disable', { userAction })\n }\n\n private handleVisible(visible: boolean, userAction = true): void {\n if (!this.state.enabled) return\n this.hooks.emit(visible ? 'show' : 'hide', { userAction })\n }\n\n private disposedErrorLog = () => {\n console.error(`${PLUGIN} is disposed`)\n }\n\n private getDataWithoutVersion(data: any) {\n if (typeof data === 'object' && data !== null && data.data) {\n return data.data as PluginData\n }\n return data\n }\n}\n","import type { Five } from '@realsee/five-webgpu'\nimport Controller from './Controller'\nimport type * as GuideLinePluginType from './typing'\nimport * as GuideLineItem from './GuideLineItem'\nimport * as GuideLineModeItem from './GuideLineModeItem'\n\nexport const GuideLinePlugin = (five: Five, config?: ConstructorParameters<typeof Controller>[1]) => new Controller(five, config)\n\nexport type { GuideLinePluginExportType } from './typing'\nexport type { GuideLinePluginType }\n\nexport default GuideLinePlugin\nexport { GuideLineItem, GuideLineModeItem }\n","import * as THREE from 'three/webgpu'\n\n/** 坐标转换成单位向量 */\nfunction coordinatesToVector(coordinates: { longitude: number; latitude: number }): THREE.Vector3 {\n const distance = Math.abs(Math.cos(coordinates.latitude))\n return new THREE.Vector3(\n /* x */ -Math.sin(coordinates.longitude) * distance,\n /* y */ -Math.sin(coordinates.latitude),\n /* z */ -Math.cos(coordinates.longitude) * distance,\n )\n}\n\nexport { coordinatesToVector }\n","import { coordinatesToVector } from './coordinatesToVector'\n\n/**\n * @description: 获取coordinates间的夹角(两个方向向量之间的最小夹角)\n * @return {number} 夹角角度(0 到 π)\n */\nfunction coordinatesAngle(\n coordinates1: { longitude: number; latitude: number },\n coordinates2: { longitude: number; latitude: number },\n): number {\n const vector1 = coordinatesToVector(coordinates1)\n const vector2 = coordinatesToVector(coordinates2)\n const angle = vector1.angleTo(vector2)\n return angle\n}\n\n/**\n * @description: 获取coordinates间的实际旋转角度(基于 longitude/latitude 差值)\n * @param coordinates1 起始坐标\n * @param coordinates2 目标坐标\n * @param signed 是否返回有符号角度(默认 false)\n * - true: 返回有符号角度(以主要旋转方向的符号为准)\n * - false: 返回无符号角度(绝对值)\n * @return {number} 旋转角度(弧度),可以超过 π\n */\nfunction coordinatesRotation(\n coordinates1: { longitude: number; latitude: number },\n coordinates2: { longitude: number; latitude: number },\n signed: boolean = false,\n): number {\n // 直接计算 longitude 和 latitude 的差值\n const deltaLon = coordinates2.longitude - coordinates1.longitude\n const deltaLat = coordinates2.latitude - coordinates1.latitude\n\n // 使用欧几里得距离计算总旋转角度\n const angle = Math.sqrt(deltaLon * deltaLon + deltaLat * deltaLat)\n\n if (!signed) {\n return angle\n }\n\n // 对于有符号角度,返回主要旋转方向\n if (Math.abs(deltaLon) >= Math.abs(deltaLat)) {\n return deltaLon >= 0 ? angle : -angle\n } else {\n return deltaLat >= 0 ? angle : -angle\n }\n}\n\nexport { coordinatesAngle, coordinatesRotation }\n","export const safeCall = async (fn: () => Promise<any>) => {\n try {\n fn().then(() => {},() => {}).catch(() => {})\n } catch (e) {}\n}\n","import type { Five } from '@realsee/five-webgpu'\n\nexport async function waitFiveLoaded(five: Five) {\n return new Promise<void>((resolve) => {\n if (five.work) {\n resolve()\n return\n }\n five.once('loaded', () => resolve())\n })\n}\n","import type { PlaybackController, PlaybackSession } from '../shared-utils/playback'\nimport type { Five, Pose, State } from '@realsee/five-webgpu'\nimport { GuideLinePlugin } from '../GuideLinePlugin'\nimport uuid from '../shared-utils/uuid'\nimport type { PluginState, PluginServerData, PluginData, CruiseData, CruiseKeyframe, MoveEffect, Config } from './typing'\nimport { coordinatesAngle, coordinatesRotation } from './utils/coordinatesAngle'\nimport { safeCall } from './utils/safeCall'\nimport * as THREE from 'three/webgpu'\nimport { sleep } from './utils/sleep'\nimport { waitFiveLoaded } from '../shared-utils/five/fiveLoaded'\nimport { vectorToCoordinates } from '../shared-utils/vectorToCoordinate'\nimport CruiseController from './BaseController'\nimport { notNil } from '../shared-utils'\n\nexport default class WalkController extends CruiseController<PluginData, Config> {\n private playbackController?: PlaybackController\n private session?: PlaybackSession\n private playbackWorkCode?: string\n private pendingKeyframes = new Set<() => void>()\n private cancelAudio?: () => void\n private pendingPanoMove?: {\n workCode: string\n panoIndex: number\n playId?: string\n session?: PlaybackSession\n promise: Promise<void>\n }\n public state: PluginState = {\n visible: true,\n enabled: true,\n disposed: false,\n playing: false,\n speed: 1,\n config: {\n speedConfig: {\n rotateSpeed: 0.001,\n rotateSpeedUnit: 'rad/ms',\n moveSpeed: 0.002,\n moveSpeedUnit: 'm/ms',\n },\n },\n }\n\n protected privateState: {\n /**\n * privateState.playing 和 state.playing 的区别:\n * state.playing 先为true,然后才 handleplay,handleplay方法内会检查privateState.playing,如果已经开始(privateState.playing === true),就不执行操作,如果为false,就执行操作\n * 其实就是加了一个不允许重复执行handleplay的逻辑\n */\n playing: boolean\n currentPlayKeyframe: {\n keyframe: CruiseKeyframe\n originDuration?: number\n } | null\n currentPlayQueue: Promise<any>[]\n broke: boolean\n playId?: string\n moveToFirstPanoEffect?: MoveEffect\n moveToFirstPanoDuration?: number\n modeChanging?: boolean\n audio?: HTMLAudioElement\n audioCache?: Map<string, HTMLAudioElement>\n } = {\n playing: false,\n currentPlayQueue: [],\n currentPlayKeyframe: null,\n broke: false,\n modeChanging: false,\n }\n\n public constructor(five: Five, config?: Config) {\n super(five, config)\n this.playbackController = config?.mediaManager?.createController({ label: 'cruise', onCancel: () => this.handlePause({ userAction: false }, true) })\n this.config = config\n }\n\n protected handleDispose() {\n this.handlePause({ userAction: false })\n this.playbackController?.dispose()\n super.handleDispose()\n }\n\n protected onWorkCodeChange() {\n if (this.playbackWorkCode !== undefined && this.playbackWorkCode !== this.workUtil.workCode) {\n this.handlePause({ userAction: false })\n }\n }\n\n /**\n * @description Load Data and State\n */\n public async load(serverData: PluginServerData | PluginServerData['data'], state?: PluginState, userAction?: boolean): Promise<void> {\n this.handlePause({ userAction: false })\n this.clear()\n\n // copy this.data\n const prevData = this.data ? JSON.parse(JSON.stringify(this.data)) : undefined\n\n // format server data to plugin data\n const data = await this.formatData(serverData)\n this.data = { id: data.keyframesId, ...data }\n this.hooks.emit('dataChange', data, prevData)\n\n let guideLinePanoIndex: number[][] = []\n let tempFloorIndex: number | undefined\n // filter panoIndex list Data\n const hasPanoIndexKeyframes = this.data.keyframes.filter((keyframe) => keyframe.data.panoIndex !== undefined)\n hasPanoIndexKeyframes\n .filter((keyframe, index) => keyframe.data.panoIndex !== hasPanoIndexKeyframes[index - 1]?.data.panoIndex) // filter repeat panoIndex\n .map((keyframe) => keyframe.data.panoIndex!)\n .forEach((panoIndex) => {\n const floorIndex = this.workUtil.getObserver(panoIndex)?.floorIndex\n if (floorIndex === undefined) return\n if (tempFloorIndex === floorIndex) {\n const index = guideLinePanoIndex.length - 1\n guideLinePanoIndex[index] = [...(guideLinePanoIndex[index] ?? []), panoIndex]\n } else {\n tempFloorIndex = floorIndex\n const index = guideLinePanoIndex.length\n guideLinePanoIndex[index] = [panoIndex]\n }\n })\n\n // initialize GuideLinePlugin\n if (!this.GuideLine && this.config?.useGuideLine !== false && data.useGuildLine !== false)\n this.GuideLine = GuideLinePlugin(this.five, this.config)\n\n // load GuideLine\n this.GuideLine?.load({ routes: guideLinePanoIndex.map((route) => ({ panoIndexList: route })), config: data.guildPluginOptions })\n\n // initialize plugin state\n if (state) {\n this.setState(state, { userAction })\n } else {\n // first pause\n this.setState({ playing: false }, { userAction: false })\n\n // set state\n this.handleVisible(this.state.visible)\n this.handleEnable(this.state.enabled)\n this.changePlayState(this.state.playing, { userAction: false })\n this.changeSpeed(this.state.speed)\n }\n\n this.clearPauseData()\n\n // load end\n console.debug(`WORKPLUGIN loaded`, data)\n this.hooks.emit('dataLoaded', data)\n }\n\n /**\n * @description If playing, first pause, then play from keyframes index/id\n * @param {number} options.index play from keyframes index\n * @param {string} options.id play from keyframes id\n */\n public playFrom(options: { userAction?: boolean; index?: number; id?: string }) {\n const { index, id, userAction } = options\n if (this.state.playing) this.setState({ playing: false }, { userAction })\n this.setState({ playing: true }, { userAction, playFromIndex: index, playFromId: id })\n }\n\n /**\n * @description Play from first keyframe\n */\n public playFromStart(options?: { userAction?: boolean }) {\n return this.playFrom({ ...options, index: 0 })\n }\n\n /**\n * @description Format data\n */\n protected async formatData(serverData: PluginServerData | PluginServerData['data']): Promise<PluginData> {\n if (!this.five.work) await waitFiveLoaded(this.five)\n\n const data = (() => {\n const _serverData = serverData as any\n if (typeof _serverData === 'object' && _serverData !== null && notNil(_serverData.version) && _serverData.data) {\n return _serverData.data as PluginServerData['data']\n }\n return _serverData as PluginServerData['data']\n })()\n if (data.keyframes) {\n return {\n keyframesId: uuid(),\n keyframes: data.keyframes.map((keyframe, index) => {\n const nextKeyframe = data.keyframes[index + 1]\n const stay = (() => {\n if (!nextKeyframe) return 0\n if (nextKeyframe.start === undefined || keyframe.end === undefined) return 0\n return nextKeyframe.start - keyframe.end\n })()\n return { id: keyframe.uuid ?? uuid(), moveIndex: index, stay, index, ...keyframe, guildPluginOptions: data.guildPluginOptions }\n }),\n }\n } else if (data.panoIndexList) {\n let keyframes: Omit<CruiseKeyframe, 'index' | 'id'>[] = []\n const { moveEffect, moveToFirstPanoEffect, moveToFirstPanoDuration } = data\n this.privateState.moveToFirstPanoEffect = moveToFirstPanoEffect\n this.privateState.moveToFirstPanoDuration = moveToFirstPanoDuration\n data.panoIndexList\n // .filter((panoIndex, index) => panoIndex !== data.panoIndexList[index - 1]) // remove the repeat panoIndex\n .forEach((panoIndex, index) => {\n const lookatNextPanoIndex = (() => {\n const nextPanoIndex = data.panoIndexList.slice(index).find((p) => p !== panoIndex) // find next different panoIndex\n if (nextPanoIndex === undefined) return\n const vectorFrom = this.workUtil.getObserverPosition(panoIndex)\n const vectorTo = this.workUtil.getObserverPosition(nextPanoIndex)\n if (!vectorTo || !vectorFrom) return\n // if panoIndex and next panoIndex isn't in same floor, return\n if (this.workUtil.getObserver(panoIndex)?.floorIndex !== this.workUtil.getObserver(nextPanoIndex)?.floorIndex) return\n const vector = new THREE.Vector3().subVectors(vectorTo, vectorFrom)\n return vectorToCoordinates(vector.normalize())\n })()\n if (data.moveType === undefined || data.moveType === 'justMove') {\n // move to panoIndex, latitude, longitude\n keyframes.push({\n moveIndex: index,\n stay: data.stay,\n data: { effect: 'Move', panoIndex, moveEffect, ...(lookatNextPanoIndex ?? {}) },\n })\n } else if (data.moveType === 'moveAndRotate') {\n // move to panoIndex, then rotate to latitude and longitude\n keyframes.push({ moveIndex: index, stay: data.stay, data: { effect: 'Move', panoIndex, moveEffect } })\n if (lookatNextPanoIndex)\n keyframes.push({ moveIndex: index, stay: data.stay, data: { effect: 'Rotate', panoIndex, ...lookatNextPanoIndex } })\n }\n })\n return {\n keyframesId: uuid(),\n keyframes: keyframes.map((keyframe, index) => ({ id: uuid(), index, ...keyframe })),\n guildPluginOptions: data.guildPluginOptions,\n useGuildLine: data.useGuildLine,\n }\n } else {\n throw new Error('format error: data no keyframes or no panoIndexList')\n }\n }\n\n /**\n * @description Play | Continue play. if have been paused, continue play from the pause position; if playing, do nothing\n * @param {number} options.playFromIndex play from keyframes index\n * @param {string} options.playFromId play from keyframes id\n */\n\n protected async handlePlay(options?: { userAction?: boolean; playFromIndex?: number; playFromId?: string; notEmitEvent?: true }) {\n const { data, state, privateState, hooks } = this\n\n // check whether keyframes can be played\n if (privateState.playing) return\n if (!data?.keyframes || data?.keyframes.length === 0) return\n\n const hasAudio = data.keyframes.some((keyframe) => !!keyframe.data.audio?.url)\n const session = this.playbackController?.begin({ userAction: options?.userAction === true, audible: hasAudio })\n if (this.playbackController && !session) { state.playing = false; return }\n this.session = session\n this.playbackWorkCode = this.workUtil.workCode\n\n // set current play id\n const currentPlayId = uuid()\n // if handlePlay function is called again before play end, currentPlayId isn't equal to privateState.playId\n privateState.playId = currentPlayId\n\n try {\n // A selected observer may start with Rotate + audio on the same panorama.\n // Only continuation frames without a new audio track resume the paused one.\n if (privateState.audio && privateState.audio.paused) {\n const pauseData = this.getPauseData()\n const target = options?.playFromIndex !== undefined\n ? data.keyframes[options.playFromIndex]\n : options?.playFromId !== undefined\n ? data.keyframes.find(keyframe => keyframe.id === options.playFromId)\n : data.keyframes.find(keyframe => keyframe.id === pauseData?.id)\n const selectedFrame = options?.playFromIndex !== undefined || options?.playFromId !== undefined\n if (target?.data.effect === 'Move' || (selectedFrame && target?.data.audio)) {\n this.cancelAudio?.()\n privateState.audio.pause()\n privateState.audio.currentTime = 0\n privateState.audio = undefined\n } else {\n await this.playAudio()\n if (session?.signal.aborted || currentPlayId !== privateState.playId) return\n }\n }\n // set state\n privateState.playing = true\n privateState.broke = false\n\n const keyframes = data.keyframes\n const pauseData = this.getPauseData()\n\n if (options?.notEmitEvent !== true) {\n hooks.emit('play', { userAction: options?.userAction ?? true })\n }\n\n let firstKeyframeWasPlayed = false\n\n const getPlayFromIndex = async () => {\n // play from index\n if (options?.playFromIndex !== undefined) return options.playFromIndex\n // play from id\n else if (options?.playFromId !== undefined) return this.data?.keyframes.findIndex((keyframe) => keyframe.id === options.playFromId)\n // play from pause position\n else if (pauseData?.id) {\n const pausedKeyframe = this.data?.keyframes.find((keyframe) => keyframe.id === pauseData.id)\n // restore paused state\n if (pauseData?.fiveState)\n await this.move(pauseData.fiveState, {\n moveEffect: privateState.moveToFirstPanoEffect,\n duration: privateState.moveToFirstPanoDuration,\n })\n if (pausedKeyframe) {\n if (pausedKeyframe.data.effect === 'Move') return pausedKeyframe.index\n else if (pausedKeyframe.data.effect === 'Rotate') {\n const duration = pauseData.duration !== undefined ? pauseData.duration * (1 - pauseData.playedProgress) : undefined\n await this.playKeyframe(pausedKeyframe, { duration })\n firstKeyframeWasPlayed = true\n // playFromIndex += 1 cause played last part of paused keyframe\n return pausedKeyframe.index + 1\n }\n }\n }\n }\n\n const playFromIndex = await getPlayFromIndex()\n if (currentPlayId !== privateState.playId || session?.signal.aborted) return\n\n // 如果是用户操作,在用户手势上下文中预加载所有需要的音频对象\n // 关键:必须在同步代码中创建 Audio 对象,而不是在异步操作之后\n const isUserAction = options?.userAction === true\n if (isUserAction) {\n // 遍历所有 keyframes,预加载所有 Move 类型的音频\n if (!this.privateState.audioCache) {\n this.privateState.audioCache = new Map()\n }\n for (let i = playFromIndex; i < keyframes.length; i++) {\n const keyframe = keyframes[i]\n if (keyframe?.data?.audio && !this.privateState.audioCache.has(keyframe.data.audio.url)) {\n // 在用户手势上下文中同步创建 Audio 对象\n const audio = new Audio(keyframe.data.audio.url)\n audio.preload = 'auto'\n // 存储音频对象,后续复用(使用 URL 作为 key)\n this.privateState.audioCache.set(keyframe.data.audio.url, audio)\n }\n }\n }\n\n this.clearPauseData()\n\n // play keyframes\n for (const keyframe of keyframes) {\n if (privateState.broke || !state.playing || !privateState.playing) return\n if (currentPlayId !== privateState.playId) return\n // jump to start keyframe\n if (playFromIndex !== undefined && keyframe.index < playFromIndex) continue\n // play single keyframe\n try {\n\n hooks.emit('playIndexChange', keyframe.index, keyframe)\n await this.playKeyframe(keyframe, {\n moveEffect: firstKeyframeWasPlayed === false ? privateState.moveToFirstPanoEffect : undefined,\n duration:\n firstKeyframeWasPlayed === false && typeof privateState.moveToFirstPanoDuration === 'number'\n ? privateState.moveToFirstPanoDuration\n : undefined,\n })\n if (keyframe.stay) await sleep(keyframe.stay)\n if (firstKeyframeWasPlayed === false) firstKeyframeWasPlayed = true\n } catch (error) {\n if (currentPlayId !== privateState.playId) return Promise.resolve('broke')\n throw error\n }\n }\n if (state.playing && currentPlayId === privateState.playId) {\n this.setState({ playing: false }, { userAction: false })\n this.session?.finish()\n this.session = undefined\n hooks.emit('end')\n this.clearPauseData()\n }\n } catch (error) {\n this.failPlayback(error, currentPlayId, session)\n }\n }\n\n private failPlayback(error: unknown, playId: string, session?: PlaybackSession) {\n if (this.state.disposed || playId !== this.privateState.playId || session?.signal.aborted) return\n this.handlePause({ userAction: false })\n if (this.state.disposed || this.state.playing) return\n this.hooks.emit('error', error instanceof Error || error instanceof DOMException ? error : new Error(String(error)))\n }\n\n /**\n * @description: Pause and record pause state\n */\n protected handlePause(options?: { userAction?: boolean; notEmitEvent?: true }, fromManager = false) {\n const { state, privateState, hooks } = this\n const wasPlaying = privateState.playing\n privateState.playing = false\n this.session = undefined\n if (!fromManager) this.playbackController?.cancel()\n privateState.playId = uuid()\n this.cancelPendingKeyframes()\n this.cancelAudio?.()\n state.playing = false\n // A pending native play may fail before privateState.playing becomes true.\n privateState.audio?.pause()\n if (!wasPlaying) return\n if (options?.userAction !== false) this.setPauseData()\n if (!privateState.broke) this.forceInteruptUpdateCamera()\n\n if (options?.notEmitEvent !== true) {\n hooks.emit('pause', { userAction: options?.userAction ?? true })\n }\n }\n\n /**\n * @description: Change play speed\n */\n protected changeSpeed(speed: number, userAction = true) {\n const { state, privateState, hooks } = this\n const { currentPlayKeyframe } = privateState\n hooks.emit('speedChange', speed, { userAction })\n\n if (state.playing && currentPlayKeyframe) {\n try {\n const duration =\n currentPlayKeyframe.originDuration !== undefined ? currentPlayKeyframe.originDuration * (1 - this.getProgress()) : undefined\n\n // this.playFeyframe(currentPlayKeyframe.keyframe, { duration })\n // 避免 promise 的互相依赖导致的死锁,手动抄一下 playKeyframe 的逻辑\n const keyframe = currentPlayKeyframe.keyframe\n if (this.privateState.currentPlayKeyframe?.keyframe.id !== keyframe.id) this.privateState.currentPlayKeyframe = { keyframe }\n this.enqueueKeyframe(keyframe, { duration })\n } catch (e) {\n console.error(e)\n }\n }\n }\n\n /**\n * @description Get ratate progress\n */\n protected getProgress() {\n return (this.five as any).controller.cameraMotion.progress\n }\n\n /**\n * @description Set pause data\n */\n protected setPauseData() {\n if (this.data?.id)\n return this.pauseDataMap.set(this.data.id, {\n id: this.privateState.currentPlayKeyframe?.keyframe.id,\n fiveState: this.five.getCurrentState(),\n duration: this.privateState.currentPlayKeyframe?.originDuration,\n playedProgress: this.getProgress(),\n })\n }\n\n /**\n * @description: Restore state that before loaded\n */\n protected clear() {\n this.privateState.playId = uuid()\n this.cancelPendingKeyframes()\n this.clearPauseData()\n this.privateState.currentPlayKeyframe = null\n }\n\n /**\n * @description Play single keyframe\n */\n private async playKeyframe(keyframe: CruiseKeyframe, params?: { duration?: number; moveEffect?: MoveEffect }) {\n if (this.privateState.currentPlayKeyframe?.keyframe.id !== keyframe.id) this.privateState.currentPlayKeyframe = { keyframe }\n\n this.enqueueKeyframe(keyframe, params)\n\n return this.actionPromiseQueue()\n }\n\n private enqueueKeyframe(keyframe: CruiseKeyframe, params?: { duration?: number; moveEffect?: MoveEffect }) {\n const promise = this.getPlayPromise(keyframe, params)\n // A later queued frame can reject before the queue reaches it. Keep the original rejection for playback.\n void promise.catch(() => undefined)\n this.privateState.currentPlayQueue.push(promise)\n }\n\n /**\n * @description: getPlayPromise\n */\n private async getPlayPromise(keyframe: CruiseKeyframe, params: { duration?: number; moveEffect?: MoveEffect } = {}) {\n const data = keyframe.data\n params.duration =\n params.duration ?? (keyframe.start !== undefined && keyframe.end !== undefined ? keyframe.end - keyframe.start : undefined)\n if (!data) return\n return new Promise<void>((resolve, reject) => {\n let settled = false\n let removeInterrupt = () => {}\n const cancel = () => settle(false)\n const settle = (failed: boolean, error?: unknown) => {\n if (settled) return\n settled = true\n removeInterrupt()\n this.pendingKeyframes.delete(cancel)\n if (failed) reject(error)\n else resolve()\n }\n this.pendingKeyframes.add(cancel)\n removeInterrupt = this.addInterruptListener(() => {\n if (settled) return\n // Release this frame before pause cancels the remaining queued frames.\n settle(true, new Error('play is interupted'))\n this.hooks.emit('broke')\n // Consumer hooks may synchronously dispose this controller.\n if (this.state.disposed) return\n this.privateState.broke = true\n this.setState({ playing: false })\n })\n try {\n const work = data.effect === 'Move' ? this.move(data, params) : this.rotate(data, params)\n work.then(() => settle(false), error => settle(true, error))\n } catch (error) {\n settle(true, error)\n }\n })\n }\n\n private cancelPendingKeyframes() {\n for (const cancel of [...this.pendingKeyframes]) cancel()\n this.privateState.currentPlayQueue = []\n this.privateState.modeChanging = false\n }\n\n /**\n * @description Action promise queue in sequence\n */\n private async actionPromiseQueue(playId = this.privateState.playId): Promise<void> {\n const { privateState } = this\n return new Promise<void>((resolve, reject) => {\n if (playId !== privateState.playId || privateState.currentPlayQueue.length === 0) {\n resolve()\n return\n }\n const promise = privateState.currentPlayQueue.shift()\n if (!promise) {\n resolve()\n return\n }\n promise.then(resolve, reject)\n }).then(() => {\n if (playId !== privateState.playId || privateState.currentPlayQueue.length === 0) return Promise.resolve()\n return this.actionPromiseQueue(playId)\n })\n }\n\n /**\n * @description Action move keyframe\n */\n private async move(data: Partial<CruiseData>, params?: { duration?: number; moveEffect?: MoveEffect }) {\n const session = this.session\n const playId = this.privateState.playId\n const current = () => playId === this.privateState.playId && !session?.signal.aborted\n if (this.privateState.audio) {\n this.privateState.audio.pause()\n this.privateState.audio.currentTime = 0\n this.privateState.audio = null\n }\n\n if (data.mode && data.mode !== this.five.currentMode) {\n await this.changeMode(data)\n } else if (data.panoIndex !== this.five.panoIndex || this.pendingPanoMove?.panoIndex === data.panoIndex) {\n await this.changePano(data, params)\n }\n // 如果在跳转到指定点位时,音频已暂停,则不重新加载音频\n if (current?.() && !this.privateState.audio?.pause) {\n this.loadAudio(data.audio)\n await this.playAudio()\n }\n return Promise.resolve()\n }\n\n /**\n * @description Action rotate keyframe\n */\n private async rotate(data: Partial<CruiseData>, params?: { duration?: number; moveEffect?: MoveEffect }) {\n const session = this.session\n const playId = this.privateState.playId\n const current = () => playId === this.privateState.playId && !session?.signal.aborted\n if (data.audio && this.privateState.audio) {\n this.privateState.audio.pause()\n this.privateState.audio.currentTime = 0\n this.privateState.audio = null\n }\n\n if (data.mode && data.mode !== this.five.currentMode) {\n await this.changeMode({ mode: data.mode, panoIndex: data.panoIndex })\n } else if (typeof data.panoIndex === 'number' && (data.panoIndex !== this.five.panoIndex || this.pendingPanoMove?.panoIndex === data.panoIndex)) {\n return await this.changePano(data, params)\n }\n\n if (!current?.()) return\n await this.updateCamera(data, params)\n\n if (current?.() && data.audio && !this.privateState.audio?.pause) {\n this.loadAudio(data.audio)\n await this.playAudio()\n }\n }\n\n /**\n * @description Update five camera\n */\n private async updateCamera(data: Partial<Omit<Pose, 'offset'>> & { rotateSpeed?: number; direction?: 'left' | 'right' }, params: { duration?: number } = {}) {\n const { five, privateState, state } = this\n const speed = (() => {\n const speedConfig = state.config?.speedConfig\n const speedValue = data.rotateSpeed ?? speedConfig?.rotateSpeed\n if (speedConfig?.rotateSpeedUnit === undefined) return speedValue\n if (speedValue !== undefined) {\n return speedConfig.rotateSpeedUnit === 'rad/ms' ? speedValue : speedValue / 1000\n }\n })()\n\n const currentState = this.five.getCurrentState()\n const PI_2 = Math.PI * 2\n\n // 根据旋转方向调整 data.longitude,确保满足方向要求\n let targetLongitude = data.longitude\n if (targetLongitude !== undefined) {\n // 将 data.longitude 归一化到 [0, 2π] 范围\n targetLongitude = ((targetLongitude % PI_2) + PI_2) % PI_2\n\n if (data.direction === 'left') {\n // left (逆时针):需要 data.longitude > currentState.longitude\n // 如果 targetLongitude <= currentState.longitude,说明需要绕一圈,加上 2π\n if (targetLongitude <= currentState.longitude) {\n targetLongitude += PI_2\n }\n } else if (data.direction === 'right') {\n // right (顺时针):需要 data.longitude < currentState.longitude\n // 如果 targetLongitude >= currentState.longitude,说明需要绕一圈,减去 2π\n if (targetLongitude >= currentState.longitude) {\n targetLongitude -= PI_2\n }\n }\n }\n\n const duration = (() => {\n if (params.duration) return params.duration\n if (speed) {\n const coordinates1 = currentState\n const coordinates2 = data as any\n const rotation = coordinatesRotation(coordinates1, {...coordinates2, longitude: targetLongitude})\n return rotation / speed\n }\n return 800\n })()\n\n if (privateState.currentPlayKeyframe) privateState.currentPlayKeyframe.originDuration = duration\n\n const _duration = this.getSpeededDuration(duration)\n\n\n return new Promise<void>((resolve) => {\n safeCall(() => {\n return five.updateCameraWithKeyframes(\n [\n {\n progress: 0,\n value: {\n longitude: currentState.longitude,\n latitude: currentState.latitude,\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n {\n progress: 0.25,\n value: {\n longitude: targetLongitude !== undefined ? (currentState.longitude + (targetLongitude + currentState.longitude) / 2) / 2 : currentState.longitude,\n latitude: currentState.latitude,\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n {\n progress: 0.5,\n value: {\n longitude: targetLongitude !== undefined ? (targetLongitude + currentState.longitude) / 2 : currentState.longitude,\n latitude: (data.latitude !== undefined ? (data.latitude + currentState.latitude) / 2 : currentState.latitude),\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n {\n progress: 0.75,\n value: {\n longitude: targetLongitude !== undefined ? (targetLongitude + (targetLongitude + currentState.longitude) / 2) / 2 : currentState.longitude,\n latitude: currentState.latitude,\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n {\n progress: 1,\n value: {\n longitude: targetLongitude !== undefined ? targetLongitude : data.longitude ?? currentState.longitude,\n latitude: data.latitude !== undefined ? data.latitude : currentState.latitude,\n fov: currentState.fov,\n offset: currentState.offset.clone(),\n distance: currentState.distance,\n },\n },\n ],\n _duration,\n );\n },\n )\n setTimeout(() => resolve(), _duration)\n })\n }\n\n /**\n * @description: Change five pano\n */\n private async changePano(data: Partial<CruiseData>, params?: { duration?: number; moveEffect?: MoveEffect }) {\n const { five, privateState, state } = this\n if (typeof data.panoIndex !== 'number') return\n const panoIndex = data.panoIndex\n const workCode = this.workUtil.workCode\n const session = this.session\n const playId = privateState.playId\n const pending = this.pendingPanoMove\n if (pending?.workCode === workCode && pending.panoIndex === panoIndex && pending.playId === playId && pending.session === session) {\n return pending.promise\n }\n if (panoIndex === five.panoIndex) return\n const current = () => playId === privateState.playId && !session?.signal.aborted && !this.state.disposed && this.workUtil.workCode === workCode\n const willChangeMode = five.getCurrentState().mode !== 'Panorama'\n if (willChangeMode) this.privateState.modeChanging = true\n const speed = (() => {\n const speedConfig = state.config?.speedConfig\n const speedValue = data.moveSpeed ?? speedConfig?.moveSpeed\n if (speedConfig?.moveSpeedUnit === undefined) return speedValue\n if (speedValue !== undefined) {\n return speedConfig.moveSpeedUnit === 'm/ms' ? speedValue : speedValue / 1000\n }\n })()\n const duration = (() => {\n if (params?.duration) return params.duration\n if (speed && typeof five.panoIndex === 'number' && typeof data.panoIndex === 'number') {\n const postion1 = this.workUtil.getObserverPosition(five.panoIndex)\n const postion2 = this.workUtil.getObserverPosition(data.panoIndex)\n if (postion1 && postion2) {\n const distance = postion1.distanceTo(postion2)\n return distance / speed\n } else {\n return 800\n }\n }\n return 800\n })()\n if (privateState.currentPlayKeyframe) privateState.currentPlayKeyframe.originDuration = duration\n let resolveMove!: () => void\n let rejectMove!: (error: unknown) => void\n const promise = new Promise<void>((resolve, reject) => {\n resolveMove = resolve\n rejectMove = reject\n })\n const request = { workCode, panoIndex, playId, session, promise }\n this.pendingPanoMove = request\n try {\n let settled = false\n const cancel = () => settle(false)\n const settle = (failed: boolean, error?: unknown) => {\n if (settled) return\n settled = true\n this.pendingKeyframes.delete(cancel)\n if (this.pendingPanoMove === request) this.pendingPanoMove = undefined\n session?.signal.removeEventListener('abort', cancel)\n five.off('panoArrived', onPanoArrived)\n five.off('pano.cancel', onPanoCancelled)\n if (failed && current()) rejectMove(error)\n else resolveMove()\n }\n const onPanoArrived = (index: number, arrivedState: State) => {\n if (index === panoIndex && arrivedState?.panoIndex === panoIndex && arrivedState?.workCode === workCode) settle(false)\n }\n const onPanoCancelled = (event: { state: State; error?: unknown }) => {\n if (event.state?.panoIndex === panoIndex && event.state?.workCode === workCode) {\n settle(true, event.error ?? new Error('Panorama move was cancelled'))\n }\n }\n this.pendingKeyframes.add(cancel)\n session?.signal.addEventListener('abort', cancel, { once: true })\n if (!current()) cancel()\n // Five may reuse an earlier request's callback for the same pending texture load.\n // Only this owner's actual target arrival can complete the current request.\n if (!settled) {\n five.on('panoArrived', onPanoArrived)\n five.on('pano.cancel', onPanoCancelled)\n }\n if (!settled) {\n try {\n const result: unknown = this.fiveUtil.moveToPano(panoIndex, {\n latitude: data.latitude,\n longitude: data.longitude,\n fov: data.fov,\n duration: this.getSpeededDuration(duration),\n effect: params?.moveEffect ?? this.state.config?.moveEffect ?? data.moveEffect,\n moveCancelCallback: () => settle(true, new Error('Panorama move was cancelled')),\n moveEndCallback: () => settle(false),\n })\n const onReturned = (value: unknown) => {\n if (value === false) settle(true, new Error('Panorama move was rejected'))\n }\n onReturned(result)\n // Five returns readiness, not arrival. Fulfillment must not advance the Cruise queue.\n Promise.resolve(result).then(onReturned, error => settle(true, error))\n } catch (error) {\n settle(true, error)\n }\n }\n await promise\n } finally {\n if (willChangeMode && playId === privateState.playId && !this.pendingPanoMove) privateState.modeChanging = false\n }\n }\n\n /**\n * @description Change five mode\n */\n private async changeMode(data: Partial<State>, duration?: number) {\n if (data.mode && data.mode !== this.five.currentMode) {\n this.privateState.modeChanging = true\n await this.five.changeMode(data.mode, data, duration)\n this.privateState.modeChanging = false\n }\n }\n\n private loadAudio(_audio: { url: string; duration: number }) {\n if (!this.privateState.playing || this.session?.signal.aborted) return\n if (_audio) {\n this.cancelAudio?.()\n // 尝试从缓存中获取预加载的音频(在用户手势上下文中创建的)\n let audio: HTMLAudioElement | undefined\n if (this.privateState.audioCache) {\n audio = this.privateState.audioCache.get(_audio.url)\n }\n\n // 如果缓存中没有,创建新的音频对象\n if (!audio) {\n audio = new Audio(_audio.url)\n audio.preload = 'auto'\n audio.load()\n }\n\n if (this.privateState.audio) {\n this.privateState.audio.pause()\n this.privateState.audio.currentTime = 0\n this.privateState.audio = null\n }\n this.privateState.audio = audio\n }\n }\n\n private async playAudio() {\n if (!this.state.playing || this.session?.signal.aborted) return\n const audio = this.privateState.audio\n if (!audio) return\n this.cancelAudio?.()\n const session = this.session\n const playId = this.privateState.playId!\n const current = () => playId === this.privateState.playId && !session?.signal.aborted && this.privateState.audio === audio\n const operations = session?.bind(audio) ?? audio\n operations.muted = false\n await new Promise<void>((resolve, reject) => {\n let started = false\n const cleanup = () => {\n audio.removeEventListener('playing', onPlaying)\n audio.removeEventListener('error', onError)\n audio.removeEventListener('ended', onEnded)\n session?.signal.removeEventListener('abort', cancel)\n if (this.cancelAudio === cancel) this.cancelAudio = undefined\n }\n const cancel = () => { cleanup(); resolve() }\n const onPlaying = () => {\n if (!current()) return cancel()\n started = true\n audio.removeEventListener('playing', onPlaying)\n resolve()\n }\n const fail = (error: unknown) => {\n cleanup()\n if (!current()) { resolve(); return }\n if (started) this.failPlayback(error, playId, session)\n else reject(error)\n }\n const onError = () => fail(new Error(audio.error?.message || 'Audio failed to play'))\n const onEnded = () => {\n cleanup()\n if (!current()) return\n operations.pause()\n operations.currentTime = 0\n this.privateState.audio = undefined\n resolve()\n }\n this.cancelAudio = cancel\n audio.addEventListener('playing', onPlaying)\n audio.addEventListener('error', onError)\n audio.addEventListener('ended', onEnded)\n session?.signal.addEventListener('abort', cancel, { once: true })\n try { operations.play().then(onPlaying, fail) } catch (error) { fail(error) }\n })\n }\n}\n"],"ignoreList":[2,3,4,5,6,7,8],"mappings":"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"}
|