@soonspacejs/plugin-patrol-controls 2.13.10 → 2.13.12

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/dist/index.d.ts CHANGED
@@ -1,121 +1,121 @@
1
- import { PerspectiveCamera, OrthographicCamera } from 'three';
2
- import SoonSpace from 'soonspacejs';
3
- import type { CameraViewpointData, Position } from 'soonspacejs';
4
- import type { Node } from 'soonspacejs';
5
- import type { Topology } from 'soonspacejs';
6
- import type { Tween } from 'three/examples/jsm/libs/tween.module.js';
7
- export type ProgressParams = {
8
- patrolled: number;
9
- total: number;
10
- percent: number;
11
- };
12
- export interface DefaultOptions {
13
- eyeHeight: number;
14
- /**
15
- * 巡检速度
16
- */
17
- naviSpeed: number;
18
- /**
19
- * 相机转向速度
20
- */
21
- rotateSpeed: number;
22
- /**
23
- * 是否飞向起始点位置
24
- */
25
- flyToStartPoint: boolean;
26
- /**
27
- * 更新回调
28
- */
29
- onUpdate: (realTimePosition: Position, nextNode: Node, toNextNodeDistance: number) => void;
30
- /**
31
- * 巡检进度
32
- */
33
- onProgress: (params: ProgressParams) => void;
34
- /**
35
- * 结束回调
36
- */
37
- onEnd: (endPosition: Position) => void;
38
- }
39
- export type StartOptions = Partial<DefaultOptions>;
40
- export type ResetOptions = Pick<StartOptions, 'eyeHeight' | 'naviSpeed' | 'rotateSpeed'>;
41
- export default class PatrolControlsPlugin {
42
- readonly ssp: SoonSpace;
43
- camera: PerspectiveCamera | OrthographicCamera;
44
- options: DefaultOptions;
45
- states: {
46
- moveDuration: number;
47
- rotateDuration: number;
48
- };
49
- nodes: Node[];
50
- nextPointIndex: number;
51
- /**
52
- * y 轴加上 eyeHeight 的节点之间距离
53
- */
54
- _nodeDistances: number[];
55
- _totalDistance: number;
56
- /**
57
- * 0 - 1
58
- */
59
- _updatePercent: number;
60
- _needsUpdateProgress: boolean;
61
- isPaused: boolean;
62
- isStoped: boolean;
63
- _positionTween: Tween<{
64
- distance: number;
65
- }> | null;
66
- _rotationTween: Tween<{
67
- t: number;
68
- }> | null;
69
- _cameraViewpointData: CameraViewpointData | null;
70
- constructor(ssp: SoonSpace);
71
- /**
72
- * 开始巡检
73
- *
74
- * @param path
75
- * @param options
76
- */
77
- start(path: Topology, options: StartOptions): void;
78
- /**
79
- * 设置巡检进度
80
- * @param percent 0 - 1(不包含 1)
81
- */
82
- setProgress(percent: number): void;
83
- /**
84
- * 设置巡检参数
85
- * @param options
86
- * @returns
87
- */
88
- setOptions(options: ResetOptions): void;
89
- /**
90
- * 暂停巡检
91
- */
92
- pause(): void;
93
- /**
94
- * 恢复巡检
95
- */
96
- resume(): void;
97
- /**
98
- * 中断巡检
99
- */
100
- stop(): void;
101
- private init;
102
- private initOptions;
103
- /**
104
- * 计算两点之间的弧度
105
- * @param sourcePoint
106
- * @param targetPoint
107
- * @returns
108
- */
109
- private computedRotation;
110
- /**
111
- * 计算下一弧度
112
- * @returns
113
- */
114
- private computeNextRotation;
115
- /**
116
- * 开始巡检
117
- * @returns
118
- */
119
- private patrolStart;
120
- private patrolStop;
121
- }
1
+ import { PerspectiveCamera, OrthographicCamera } from 'three';
2
+ import SoonSpace from 'soonspacejs';
3
+ import type { CameraViewpointData, Position } from 'soonspacejs';
4
+ import type { Node } from 'soonspacejs';
5
+ import type { Topology } from 'soonspacejs';
6
+ import type { Tween } from 'three/examples/jsm/libs/tween.module.js';
7
+ export type ProgressParams = {
8
+ patrolled: number;
9
+ total: number;
10
+ percent: number;
11
+ };
12
+ export interface DefaultOptions {
13
+ eyeHeight: number;
14
+ /**
15
+ * 巡检速度
16
+ */
17
+ naviSpeed: number;
18
+ /**
19
+ * 相机转向速度
20
+ */
21
+ rotateSpeed: number;
22
+ /**
23
+ * 是否飞向起始点位置
24
+ */
25
+ flyToStartPoint: boolean;
26
+ /**
27
+ * 更新回调
28
+ */
29
+ onUpdate: (realTimePosition: Position, nextNode: Node, toNextNodeDistance: number) => void;
30
+ /**
31
+ * 巡检进度
32
+ */
33
+ onProgress: (params: ProgressParams) => void;
34
+ /**
35
+ * 结束回调
36
+ */
37
+ onEnd: (endPosition: Position) => void;
38
+ }
39
+ export type StartOptions = Partial<DefaultOptions>;
40
+ export type ResetOptions = Pick<StartOptions, 'eyeHeight' | 'naviSpeed' | 'rotateSpeed'>;
41
+ export default class PatrolControlsPlugin {
42
+ readonly ssp: SoonSpace;
43
+ camera: PerspectiveCamera | OrthographicCamera;
44
+ options: DefaultOptions;
45
+ states: {
46
+ moveDuration: number;
47
+ rotateDuration: number;
48
+ };
49
+ nodes: Node[];
50
+ nextPointIndex: number;
51
+ /**
52
+ * y 轴加上 eyeHeight 的节点之间距离
53
+ */
54
+ _nodeDistances: number[];
55
+ _totalDistance: number;
56
+ /**
57
+ * 0 - 1
58
+ */
59
+ _updatePercent: number;
60
+ _needsUpdateProgress: boolean;
61
+ isPaused: boolean;
62
+ isStoped: boolean;
63
+ _positionTween: Tween<{
64
+ distance: number;
65
+ }> | null;
66
+ _rotationTween: Tween<{
67
+ t: number;
68
+ }> | null;
69
+ _cameraViewpointData: CameraViewpointData | null;
70
+ constructor(ssp: SoonSpace);
71
+ /**
72
+ * 开始巡检
73
+ *
74
+ * @param path
75
+ * @param options
76
+ */
77
+ start(path: Topology, options: StartOptions): void;
78
+ /**
79
+ * 设置巡检进度
80
+ * @param percent 0 - 1(不包含 1)
81
+ */
82
+ setProgress(percent: number): void;
83
+ /**
84
+ * 设置巡检参数
85
+ * @param options
86
+ * @returns
87
+ */
88
+ setOptions(options: ResetOptions): void;
89
+ /**
90
+ * 暂停巡检
91
+ */
92
+ pause(): void;
93
+ /**
94
+ * 恢复巡检
95
+ */
96
+ resume(): void;
97
+ /**
98
+ * 中断巡检
99
+ */
100
+ stop(): void;
101
+ private init;
102
+ private initOptions;
103
+ /**
104
+ * 计算两点之间的弧度
105
+ * @param sourcePoint
106
+ * @param targetPoint
107
+ * @returns
108
+ */
109
+ private computedRotation;
110
+ /**
111
+ * 计算下一弧度
112
+ * @returns
113
+ */
114
+ private computeNextRotation;
115
+ /**
116
+ * 开始巡检
117
+ * @returns
118
+ */
119
+ private patrolStart;
120
+ private patrolStop;
121
+ }
package/dist/index.esm.js CHANGED
@@ -1 +1 @@
1
- import{Vector3 as t,Matrix4 as s,Quaternion as i}from"three";const e=1e-5;class o{constructor(t){this.ssp=t,this.options={naviSpeed:1,rotateSpeed:1,eyeHeight:150,flyToStartPoint:!0,onUpdate:()=>{},onProgress:()=>{},onEnd:()=>{}},this.states={moveDuration:0,rotateDuration:0},this.nodes=[],this.nextPointIndex=0,this._nodeDistances=[],this._totalDistance=0,this._updatePercent=0,this._needsUpdateProgress=!1,this.isPaused=!1,this.isStoped=!0,this._positionTween=null,this._rotationTween=null,this._cameraViewpointData=null;const{cameraManager:s}=this.ssp.viewport;this.camera=s.mainCamera}start(t,s){this.isStoped?(this.ssp.controls.saveState(),this.ssp.controls.enabled=!1,this.init(t),this.initOptions(s),this.patrolStart()):this.ssp.utils.warn("巡检已经开始!")}setProgress(t){var s,i;this._updatePercent=Math.min(Math.max(t,0),1),this._needsUpdateProgress=!0,null===(s=this._positionTween)||void 0===s||s.stop(),null===(i=this._rotationTween)||void 0===i||i.stop()}setOptions(t){if(this.isStoped)return;const{naviSpeed:s,rotateSpeed:i}=t;if(s&&this._positionTween){const t=this.states.moveDuration*this.options.naviSpeed/s;this._positionTween.duration(t),this.states.moveDuration=t}if(i&&this._rotationTween){const t=this.states.rotateDuration*this.options.rotateSpeed/i;this._rotationTween.duration(t),this.states.rotateDuration=t}this.initOptions(t)}pause(){var t,s;this.isPaused||this.isStoped||(this._cameraViewpointData=this.ssp.getCameraViewpoint(),this.isPaused=!0,null===(t=this._positionTween)||void 0===t||t.pause(),null===(s=this._rotationTween)||void 0===s||s.pause())}resume(){var t,s;this.isPaused&&!this.isStoped&&(this._cameraViewpointData&&this.ssp.setCameraViewpoint(this._cameraViewpointData),this.isPaused=!1,null===(t=this._positionTween)||void 0===t||t.resume(),null===(s=this._rotationTween)||void 0===s||s.resume())}stop(){this.isStoped||(this.patrolStop(),this.ssp.controls.reset(),this.ssp.controls.enabled=!0)}init(t){this.isPaused=!1,this.isStoped=!1,this.nextPointIndex=0,this.nodes=[...t.nodes]}initOptions(s){const{eyeHeight:i,naviSpeed:e,rotateSpeed:o,flyToStartPoint:n=!0,onUpdate:a,onProgress:h,onEnd:r}=s;i&&(this.options.eyeHeight=i),e&&(this.options.naviSpeed=e),o&&(this.options.rotateSpeed=o),this.options.flyToStartPoint=n,a&&(this.options.onUpdate=a),h&&(this.options.onProgress=h),r&&(this.options.onEnd=r),this._nodeDistances.length=0,this._nodeDistances.push(0),this._totalDistance=0;for(let s=0,i=this.nodes.length;s<i-1;s++){const i=this.nodes[s],e=this.nodes[s+1];if(i&&e){const s=i.getWorldPosition(new t),o=e.getWorldPosition(new t);s.y+=this.options.eyeHeight,o.y+=this.options.eyeHeight;const n=s.distanceTo(o);this._nodeDistances.push(n),this._totalDistance+=n}}}computedRotation(t,e){const o=new s;o.lookAt(t,e,this.camera.up);return(new i).setFromRotationMatrix(o)}computeNextRotation(s=this.nextPointIndex){var e,o;const n=null===(e=this.nodes[s])||void 0===e?void 0:e.getWorldPosition(new t),a=null===(o=this.nodes[s+1])||void 0===o?void 0:o.getWorldPosition(new t);return n&&a?this.computedRotation(n,a):new i}async patrolStart(){return new Promise((async s=>{var i;const{controls:o}=this.ssp,{onUpdate:n,onProgress:a,onEnd:h}=this.options;if(this.nextPointIndex>=this.nodes.length)null==h||h(this.camera.position.clone()),s(!0);else{if(this._needsUpdateProgress){let s=this._totalDistance*this._updatePercent;for(let i=0,e=this._nodeDistances.length;i<e;i++)if(s-=this._nodeDistances[i],s<0){this.nextPointIndex=i,s+=this._nodeDistances[i];const e=s/this._nodeDistances[i]||0,n=this.nodes[i-1],a=this.nodes[i],h=new t,r=n.getWorldPosition(new t),d=a.getWorldPosition(new t);r.y+=this.options.eyeHeight,d.y+=this.options.eyeHeight;const p=(new t).subVectors(d,r).multiplyScalar(e);h.copy(r).add(p),o.setPosition(h.x,h.y,h.z),o.setTarget(d.x,d.y,d.z);break}this._needsUpdateProgress=!1}const s=this.nodes[this.nextPointIndex],h=s.getWorldPosition(new t);h.setY(h.y+this.options.eyeHeight);const r=o.getPosition(new t).distanceTo(h);if(this.states.moveDuration=0===this.nextPointIndex?1e3:r/this.options.naviSpeed/.6,o.setTarget(h.x,h.y,h.z),0!==this.nextPointIndex||this.options.flyToStartPoint)try{await this.ssp.animation({distance:o.distance},{distance:e},{duration:this.states.moveDuration},(({distance:i})=>{var e;if(this.isPaused)null===(e=this._positionTween)||void 0===e||e.pause();else if(o.dollyTo(i),null==n||n(o.getPosition(new t),s,i),this._nodeDistances[this.nextPointIndex]>0){let t=this._nodeDistances.slice(0,this.nextPointIndex+1).reduce(((t,s)=>t+s),0);t-=i,null==a||a({patrolled:t,total:this._totalDistance,percent:t/this._totalDistance})}}),(t=>{this._positionTween=t}))}catch(t){}else o.dollyTo(e);if(this.nextPointIndex<this.nodes.length-1){const s=this.computeNextRotation(),e=this.camera.quaternion.angleTo(s);this.states.rotateDuration=0===this.nextPointIndex?1e3:300*e/this.options.rotateSpeed;const n=o.getPosition(new t),a=null===(i=this.nodes[this.nextPointIndex+1])||void 0===i?void 0:i.getWorldPosition(new t);a.y+=this.options.eyeHeight;try{await this.ssp.animation({t:0},{t:1},{duration:this.states.rotateDuration},(({t:t})=>{var s;if(this.isPaused)return void(null===(s=this._rotationTween)||void 0===s||s.pause());const i=h.clone().sub(n).normalize(),e=a.clone().sub(h).normalize(),{x:r,y:d,z:p}=i.lerp(e,t).add(h);o.setTarget(r,d,p)}),(t=>{this._rotationTween=t}))}catch(t){}}this._needsUpdateProgress||this.nextPointIndex++,this.isStoped||await this.patrolStart()}}))}patrolStop(){var t,s;this.options={naviSpeed:1,rotateSpeed:1,eyeHeight:150,flyToStartPoint:!0,onUpdate:()=>{},onProgress:()=>{},onEnd:()=>{}},this.nodes=[],this.nextPointIndex=0,this.isPaused=!1,this.isStoped=!0,this._needsUpdateProgress=!1,null===(t=this._positionTween)||void 0===t||t.stop(),null===(s=this._rotationTween)||void 0===s||s.stop(),this._positionTween=null,this._rotationTween=null}}export{o as default};
1
+ import{Vector3 as t,Matrix4 as s,Quaternion as i}from"three";const e=1e-5;class o{constructor(t){this.ssp=t,this.options={naviSpeed:1,rotateSpeed:1,eyeHeight:150,flyToStartPoint:!0,onUpdate:()=>{},onProgress:()=>{},onEnd:()=>{}},this.states={moveDuration:0,rotateDuration:0},this.nodes=[],this.nextPointIndex=0,this._nodeDistances=[],this._totalDistance=0,this._updatePercent=0,this._needsUpdateProgress=!1,this.isPaused=!1,this.isStoped=!0,this._positionTween=null,this._rotationTween=null,this._cameraViewpointData=null;const{cameraManager:s}=this.ssp.viewport;this.camera=s.mainCamera}start(t,s){this.isStoped?(this.ssp.controls.saveState(),this.ssp.controls.enabled=!1,this.init(t),this.initOptions(s),this.patrolStart()):this.ssp.utils.warn("巡检已经开始!")}setProgress(t){var s,i;this._updatePercent=Math.min(Math.max(t,0),1),this._needsUpdateProgress=!0,null===(s=this._positionTween)||void 0===s||s.stop(),null===(i=this._rotationTween)||void 0===i||i.stop()}setOptions(t){if(this.isStoped)return;const{naviSpeed:s,rotateSpeed:i}=t;if(s&&this._positionTween){const t=this.states.moveDuration*this.options.naviSpeed/s;this._positionTween.duration(t),this.states.moveDuration=t}if(i&&this._rotationTween){const t=this.states.rotateDuration*this.options.rotateSpeed/i;this._rotationTween.duration(t),this.states.rotateDuration=t}this.initOptions(t)}pause(){var t,s;this.isPaused||this.isStoped||(this._cameraViewpointData=this.ssp.getCameraViewpoint(),this.isPaused=!0,null===(t=this._positionTween)||void 0===t||t.pause(),null===(s=this._rotationTween)||void 0===s||s.pause())}resume(){var t,s;this.isPaused&&!this.isStoped&&(this._cameraViewpointData&&this.ssp.setCameraViewpoint(this._cameraViewpointData),this.isPaused=!1,null===(t=this._positionTween)||void 0===t||t.resume(),null===(s=this._rotationTween)||void 0===s||s.resume())}stop(){this.isStoped||(this.patrolStop(),this.ssp.controls.reset(),this.ssp.controls.enabled=!0)}init(t){this.isPaused=!1,this.isStoped=!1,this.nextPointIndex=0,this.nodes=[...t.nodes]}initOptions(s){const{eyeHeight:i,naviSpeed:e,rotateSpeed:o,flyToStartPoint:n=!0,onUpdate:a,onProgress:h,onEnd:r}=s;i&&(this.options.eyeHeight=i),e&&(this.options.naviSpeed=e),o&&(this.options.rotateSpeed=o),this.options.flyToStartPoint=n,a&&(this.options.onUpdate=a),h&&(this.options.onProgress=h),r&&(this.options.onEnd=r),this._nodeDistances.length=0,this._nodeDistances.push(0),this._totalDistance=0;for(let s=0,i=this.nodes.length;s<i-1;s++){const i=this.nodes[s],e=this.nodes[s+1];if(i&&e){const s=i.getWorldPosition(new t),o=e.getWorldPosition(new t);s.y+=this.options.eyeHeight,o.y+=this.options.eyeHeight;const n=s.distanceTo(o);this._nodeDistances.push(n),this._totalDistance+=n}}}computedRotation(t,e){const o=new s;o.lookAt(t,e,this.camera.up);return(new i).setFromRotationMatrix(o)}computeNextRotation(s=this.nextPointIndex){var e,o;const n=null===(e=this.nodes[s])||void 0===e?void 0:e.getWorldPosition(new t),a=null===(o=this.nodes[s+1])||void 0===o?void 0:o.getWorldPosition(new t);return n&&a?this.computedRotation(n,a):new i}async patrolStart(){return new Promise(async s=>{var i;const{controls:o}=this.ssp,{onUpdate:n,onProgress:a,onEnd:h}=this.options;if(this.nextPointIndex>=this.nodes.length)null==h||h(this.camera.position.clone()),s(!0);else{if(this._needsUpdateProgress){let s=this._totalDistance*this._updatePercent;for(let i=0,e=this._nodeDistances.length;i<e;i++)if(s-=this._nodeDistances[i],s<0){this.nextPointIndex=i,s+=this._nodeDistances[i];const e=s/this._nodeDistances[i]||0,n=this.nodes[i-1],a=this.nodes[i],h=new t,r=n.getWorldPosition(new t),d=a.getWorldPosition(new t);r.y+=this.options.eyeHeight,d.y+=this.options.eyeHeight;const p=(new t).subVectors(d,r).multiplyScalar(e);h.copy(r).add(p),o.setPosition(h.x,h.y,h.z),o.setTarget(d.x,d.y,d.z);break}this._needsUpdateProgress=!1}const s=this.nodes[this.nextPointIndex],h=s.getWorldPosition(new t);h.setY(h.y+this.options.eyeHeight);const r=o.getPosition(new t).distanceTo(h);if(this.states.moveDuration=0===this.nextPointIndex?1e3:r/this.options.naviSpeed/.6,o.setTarget(h.x,h.y,h.z),0!==this.nextPointIndex||this.options.flyToStartPoint)try{await this.ssp.animation({distance:o.distance},{distance:e},{duration:this.states.moveDuration},({distance:i})=>{var e;if(this.isPaused)null===(e=this._positionTween)||void 0===e||e.pause();else if(o.dollyTo(i),null==n||n(o.getPosition(new t),s,i),this._nodeDistances[this.nextPointIndex]>0){let t=this._nodeDistances.slice(0,this.nextPointIndex+1).reduce((t,s)=>t+s,0);t-=i,null==a||a({patrolled:t,total:this._totalDistance,percent:t/this._totalDistance})}},t=>{this._positionTween=t})}catch(t){}else o.dollyTo(e);if(this.nextPointIndex<this.nodes.length-1){const s=this.computeNextRotation(),e=this.camera.quaternion.angleTo(s);this.states.rotateDuration=0===this.nextPointIndex?1e3:300*e/this.options.rotateSpeed;const n=o.getPosition(new t),a=null===(i=this.nodes[this.nextPointIndex+1])||void 0===i?void 0:i.getWorldPosition(new t);a.y+=this.options.eyeHeight;try{await this.ssp.animation({t:0},{t:1},{duration:this.states.rotateDuration},({t:t})=>{var s;if(this.isPaused)return void(null===(s=this._rotationTween)||void 0===s||s.pause());const i=h.clone().sub(n).normalize(),e=a.clone().sub(h).normalize(),{x:r,y:d,z:p}=i.lerp(e,t).add(h);o.setTarget(r,d,p)},t=>{this._rotationTween=t})}catch(t){}}this._needsUpdateProgress||this.nextPointIndex++,this.isStoped||await this.patrolStart()}})}patrolStop(){var t,s;this.options={naviSpeed:1,rotateSpeed:1,eyeHeight:150,flyToStartPoint:!0,onUpdate:()=>{},onProgress:()=>{},onEnd:()=>{}},this.nodes=[],this.nextPointIndex=0,this.isPaused=!1,this.isStoped=!0,this._needsUpdateProgress=!1,null===(t=this._positionTween)||void 0===t||t.stop(),null===(s=this._rotationTween)||void 0===s||s.stop(),this._positionTween=null,this._rotationTween=null}}export{o as default};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@soonspacejs/plugin-patrol-controls",
3
3
  "pluginName": "PatrolControlsPlugin",
4
- "version": "2.13.10",
4
+ "version": "2.13.12",
5
5
  "description": "Patrol-controls plugin for SoonSpace.js",
6
6
  "main": "dist/index.esm.js",
7
7
  "module": "dist/index.esm.js",
@@ -13,8 +13,8 @@
13
13
  ],
14
14
  "author": "xunwei",
15
15
  "license": "UNLICENSED",
16
- "gitHead": "6bca3b98477ef9c2fa0ba5f67d461561896bb0ff",
16
+ "gitHead": "aa34f472ae1520b537b0a5a1d67f4a746f41236a",
17
17
  "peerDependencies": {
18
- "soonspacejs": "2.13.10"
18
+ "soonspacejs": "2.13.12"
19
19
  }
20
20
  }