@soonspacejs/plugin-patrol-controls 2.13.6 → 2.13.7
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/README.md +5 -5
- package/dist/index.esm.js +357 -1
- package/dist/index.esm.js.map +1 -0
- package/package.json +3 -3
- package/dist/index.d.ts +0 -121
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# @soonspacejs/plugin-patrol-controls
|
|
2
|
-
|
|
3
|
-
> Patrol-controls plugin for SoonSpace.js
|
|
4
|
-
|
|
5
|
-
Document: [http://www.xwbuilders.com:8800/plugin/patrol-controls.html](http://www.xwbuilders.com:8800/plugin/patrol-controls.html)
|
|
1
|
+
# @soonspacejs/plugin-patrol-controls
|
|
2
|
+
|
|
3
|
+
> Patrol-controls plugin for SoonSpace.js
|
|
4
|
+
|
|
5
|
+
Document: [http://www.xwbuilders.com:8800/plugin/patrol-controls.html](http://www.xwbuilders.com:8800/plugin/patrol-controls.html)
|
package/dist/index.esm.js
CHANGED
|
@@ -1 +1,357 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Vector3, Matrix4, Quaternion } from 'three';
|
|
2
|
+
|
|
3
|
+
const EPS = 1e-5;
|
|
4
|
+
class PatrolControlsPlugin {
|
|
5
|
+
constructor(ssp) {
|
|
6
|
+
this.ssp = ssp;
|
|
7
|
+
this.options = {
|
|
8
|
+
naviSpeed: 1,
|
|
9
|
+
rotateSpeed: 1,
|
|
10
|
+
eyeHeight: 150,
|
|
11
|
+
flyToStartPoint: true,
|
|
12
|
+
onUpdate: () => { },
|
|
13
|
+
onProgress: () => { },
|
|
14
|
+
onEnd: () => { },
|
|
15
|
+
};
|
|
16
|
+
this.states = {
|
|
17
|
+
moveDuration: 0,
|
|
18
|
+
rotateDuration: 0,
|
|
19
|
+
};
|
|
20
|
+
// 路径节点列表
|
|
21
|
+
this.nodes = [];
|
|
22
|
+
this.nextPointIndex = 0;
|
|
23
|
+
/**
|
|
24
|
+
* y 轴加上 eyeHeight 的节点之间距离
|
|
25
|
+
*/
|
|
26
|
+
this._nodeDistances = [];
|
|
27
|
+
this._totalDistance = 0;
|
|
28
|
+
/**
|
|
29
|
+
* 0 - 1
|
|
30
|
+
*/
|
|
31
|
+
this._updatePercent = 0;
|
|
32
|
+
this._needsUpdateProgress = false;
|
|
33
|
+
this.isPaused = false;
|
|
34
|
+
this.isStoped = true;
|
|
35
|
+
this._positionTween = null;
|
|
36
|
+
this._rotationTween = null;
|
|
37
|
+
this._cameraViewpointData = null;
|
|
38
|
+
const { cameraManager, } = this.ssp.viewport;
|
|
39
|
+
this.camera = cameraManager.mainCamera;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 开始巡检
|
|
43
|
+
*
|
|
44
|
+
* @param path
|
|
45
|
+
* @param options
|
|
46
|
+
*/
|
|
47
|
+
start(path, options) {
|
|
48
|
+
if (!this.isStoped) {
|
|
49
|
+
this.ssp.utils.warn('巡检已经开始!');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.ssp.controls.saveState();
|
|
53
|
+
this.ssp.controls.enabled = false;
|
|
54
|
+
this.init(path);
|
|
55
|
+
this.initOptions(options);
|
|
56
|
+
this.patrolStart();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 设置巡检进度
|
|
60
|
+
* @param percent 0 - 1(不包含 1)
|
|
61
|
+
*/
|
|
62
|
+
setProgress(percent) {
|
|
63
|
+
var _a, _b;
|
|
64
|
+
this._updatePercent = Math.min(Math.max(percent, 0), 1);
|
|
65
|
+
this._needsUpdateProgress = true;
|
|
66
|
+
(_a = this._positionTween) === null || _a === void 0 ? void 0 : _a.stop();
|
|
67
|
+
(_b = this._rotationTween) === null || _b === void 0 ? void 0 : _b.stop();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 设置巡检参数
|
|
71
|
+
* @param options
|
|
72
|
+
* @returns
|
|
73
|
+
*/
|
|
74
|
+
setOptions(options) {
|
|
75
|
+
if (this.isStoped)
|
|
76
|
+
return;
|
|
77
|
+
const { naviSpeed, rotateSpeed, } = options;
|
|
78
|
+
if (naviSpeed && this._positionTween) {
|
|
79
|
+
const newMoveDuration = this.states.moveDuration * this.options.naviSpeed / naviSpeed;
|
|
80
|
+
this._positionTween.duration(newMoveDuration);
|
|
81
|
+
this.states.moveDuration = newMoveDuration;
|
|
82
|
+
}
|
|
83
|
+
if (rotateSpeed && this._rotationTween) {
|
|
84
|
+
const newRotateDuration = this.states.rotateDuration * this.options.rotateSpeed / rotateSpeed;
|
|
85
|
+
this._rotationTween.duration(newRotateDuration);
|
|
86
|
+
this.states.rotateDuration = newRotateDuration;
|
|
87
|
+
}
|
|
88
|
+
this.initOptions(options);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 暂停巡检
|
|
92
|
+
*/
|
|
93
|
+
pause() {
|
|
94
|
+
var _a, _b;
|
|
95
|
+
if (this.isPaused || this.isStoped)
|
|
96
|
+
return;
|
|
97
|
+
/**
|
|
98
|
+
* 保存巡检相机视角数据
|
|
99
|
+
*/
|
|
100
|
+
this._cameraViewpointData = this.ssp.getCameraViewpoint();
|
|
101
|
+
this.isPaused = true;
|
|
102
|
+
(_a = this._positionTween) === null || _a === void 0 ? void 0 : _a.pause();
|
|
103
|
+
(_b = this._rotationTween) === null || _b === void 0 ? void 0 : _b.pause();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 恢复巡检
|
|
107
|
+
*/
|
|
108
|
+
resume() {
|
|
109
|
+
var _a, _b;
|
|
110
|
+
if (!this.isPaused || this.isStoped)
|
|
111
|
+
return;
|
|
112
|
+
if (this._cameraViewpointData) {
|
|
113
|
+
this.ssp.setCameraViewpoint(this._cameraViewpointData);
|
|
114
|
+
}
|
|
115
|
+
this.isPaused = false;
|
|
116
|
+
(_a = this._positionTween) === null || _a === void 0 ? void 0 : _a.resume();
|
|
117
|
+
(_b = this._rotationTween) === null || _b === void 0 ? void 0 : _b.resume();
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 中断巡检
|
|
121
|
+
*/
|
|
122
|
+
stop() {
|
|
123
|
+
if (this.isStoped)
|
|
124
|
+
return;
|
|
125
|
+
this.patrolStop();
|
|
126
|
+
this.ssp.controls.reset();
|
|
127
|
+
this.ssp.controls.enabled = true;
|
|
128
|
+
}
|
|
129
|
+
init(path) {
|
|
130
|
+
this.isPaused = false;
|
|
131
|
+
this.isStoped = false;
|
|
132
|
+
this.nextPointIndex = 0;
|
|
133
|
+
// initPoints
|
|
134
|
+
this.nodes = [...path.nodes];
|
|
135
|
+
}
|
|
136
|
+
initOptions(options) {
|
|
137
|
+
const { eyeHeight, naviSpeed, rotateSpeed, flyToStartPoint = true, onUpdate, onProgress, onEnd, } = options;
|
|
138
|
+
eyeHeight && (this.options.eyeHeight = eyeHeight);
|
|
139
|
+
naviSpeed && (this.options.naviSpeed = naviSpeed);
|
|
140
|
+
rotateSpeed && (this.options.rotateSpeed = rotateSpeed);
|
|
141
|
+
this.options.flyToStartPoint = flyToStartPoint;
|
|
142
|
+
onUpdate && (this.options.onUpdate = onUpdate);
|
|
143
|
+
onProgress && (this.options.onProgress = onProgress);
|
|
144
|
+
onEnd && (this.options.onEnd = onEnd);
|
|
145
|
+
this._nodeDistances.length = 0;
|
|
146
|
+
this._nodeDistances.push(0);
|
|
147
|
+
this._totalDistance = 0;
|
|
148
|
+
// compute node distance,加上 eyeHeight
|
|
149
|
+
for (let i = 0, len = this.nodes.length; i < len - 1; i++) {
|
|
150
|
+
const currentNode = this.nodes[i], nextNode = this.nodes[i + 1];
|
|
151
|
+
if (currentNode && nextNode) {
|
|
152
|
+
const currentWorldPosition = currentNode.getWorldPosition(new Vector3()), nextWorldPosition = nextNode.getWorldPosition(new Vector3());
|
|
153
|
+
currentWorldPosition.y += this.options.eyeHeight;
|
|
154
|
+
nextWorldPosition.y += this.options.eyeHeight;
|
|
155
|
+
const distance = currentWorldPosition.distanceTo(nextWorldPosition);
|
|
156
|
+
this._nodeDistances.push(distance);
|
|
157
|
+
this._totalDistance += distance;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* 计算两点之间的弧度
|
|
163
|
+
* @param sourcePoint
|
|
164
|
+
* @param targetPoint
|
|
165
|
+
* @returns
|
|
166
|
+
*/
|
|
167
|
+
computedRotation(sourcePoint, targetPoint) {
|
|
168
|
+
const matrix4 = new Matrix4();
|
|
169
|
+
matrix4.lookAt(sourcePoint, targetPoint, this.camera.up);
|
|
170
|
+
const nextRotation = new Quaternion().setFromRotationMatrix(matrix4);
|
|
171
|
+
return nextRotation;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 计算下一弧度
|
|
175
|
+
* @returns
|
|
176
|
+
*/
|
|
177
|
+
computeNextRotation(index = this.nextPointIndex) {
|
|
178
|
+
var _a, _b;
|
|
179
|
+
const currentPoint = (_a = this.nodes[index]) === null || _a === void 0 ? void 0 : _a.getWorldPosition(new Vector3());
|
|
180
|
+
const nextPoint = (_b = this.nodes[index + 1]) === null || _b === void 0 ? void 0 : _b.getWorldPosition(new Vector3());
|
|
181
|
+
return (currentPoint && nextPoint) ? this.computedRotation(currentPoint, nextPoint) : new Quaternion();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 开始巡检
|
|
185
|
+
* @returns
|
|
186
|
+
*/
|
|
187
|
+
async patrolStart() {
|
|
188
|
+
return new Promise(async (resolve) => {
|
|
189
|
+
var _a;
|
|
190
|
+
const { controls, } = this.ssp;
|
|
191
|
+
const { onUpdate, onProgress, onEnd, } = this.options;
|
|
192
|
+
if (this.nextPointIndex >= this.nodes.length) {
|
|
193
|
+
// 巡检结束时
|
|
194
|
+
onEnd === null || onEnd === void 0 ? void 0 : onEnd(this.camera.position.clone());
|
|
195
|
+
resolve(true);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
/**
|
|
199
|
+
* 更新进度
|
|
200
|
+
*/
|
|
201
|
+
if (this._needsUpdateProgress) {
|
|
202
|
+
let percentDistance = this._totalDistance * this._updatePercent;
|
|
203
|
+
for (let i = 0, len = this._nodeDistances.length; i < len; i++) {
|
|
204
|
+
percentDistance -= this._nodeDistances[i];
|
|
205
|
+
if (percentDistance < 0) {
|
|
206
|
+
/**
|
|
207
|
+
* 更新 index
|
|
208
|
+
*/
|
|
209
|
+
this.nextPointIndex = i;
|
|
210
|
+
/**
|
|
211
|
+
* 更新相机位置
|
|
212
|
+
*/
|
|
213
|
+
percentDistance += this._nodeDistances[i];
|
|
214
|
+
const percent = (percentDistance / this._nodeDistances[i]) || 0;
|
|
215
|
+
const prevNode = this.nodes[i - 1], nextNode = this.nodes[i];
|
|
216
|
+
const cameraPosition = new Vector3();
|
|
217
|
+
/**
|
|
218
|
+
* 其他点
|
|
219
|
+
*/
|
|
220
|
+
const prevPosition = prevNode.getWorldPosition(new Vector3()), nextPosition = nextNode.getWorldPosition(new Vector3());
|
|
221
|
+
prevPosition.y += this.options.eyeHeight;
|
|
222
|
+
nextPosition.y += this.options.eyeHeight;
|
|
223
|
+
const diffPosition = new Vector3()
|
|
224
|
+
.subVectors(nextPosition, prevPosition)
|
|
225
|
+
.multiplyScalar(percent);
|
|
226
|
+
cameraPosition.copy(prevPosition).add(diffPosition);
|
|
227
|
+
controls.setPosition(cameraPosition.x, cameraPosition.y, cameraPosition.z);
|
|
228
|
+
controls.setTarget(nextPosition.x, nextPosition.y, nextPosition.z);
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
this._needsUpdateProgress = false;
|
|
233
|
+
}
|
|
234
|
+
const nextNode = this.nodes[this.nextPointIndex];
|
|
235
|
+
const nextNodePosition = nextNode.getWorldPosition(new Vector3());
|
|
236
|
+
// 增加眼睛高度
|
|
237
|
+
nextNodePosition.setY(nextNodePosition.y + this.options.eyeHeight);
|
|
238
|
+
// 相机位置与下一点的距离
|
|
239
|
+
const positionDist = controls.getPosition(new Vector3()).distanceTo(nextNodePosition);
|
|
240
|
+
/**
|
|
241
|
+
* @todo 移动持续时间
|
|
242
|
+
*/
|
|
243
|
+
this.states.moveDuration = this.nextPointIndex === 0 ? 1000 : positionDist / this.options.naviSpeed / 0.6;
|
|
244
|
+
controls.setTarget(nextNodePosition.x, nextNodePosition.y, nextNodePosition.z);
|
|
245
|
+
// 路径行行进
|
|
246
|
+
if (this.nextPointIndex === 0 && !this.options.flyToStartPoint) {
|
|
247
|
+
controls.dollyTo(EPS);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
try {
|
|
251
|
+
await this.ssp.animation({ distance: controls.distance, }, { distance: EPS, }, {
|
|
252
|
+
duration: this.states.moveDuration,
|
|
253
|
+
}, ({ distance, }) => {
|
|
254
|
+
var _a;
|
|
255
|
+
if (this.isPaused) {
|
|
256
|
+
(_a = this._positionTween) === null || _a === void 0 ? void 0 : _a.pause();
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
controls.dollyTo(distance);
|
|
260
|
+
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(controls.getPosition(new Vector3()), nextNode, distance);
|
|
261
|
+
/**
|
|
262
|
+
* progress
|
|
263
|
+
*/
|
|
264
|
+
if (this._nodeDistances[this.nextPointIndex] > 0) {
|
|
265
|
+
let patrolled = this._nodeDistances.slice(0, this.nextPointIndex + 1).reduce((accumulator, currentValue) => accumulator + currentValue, 0);
|
|
266
|
+
patrolled -= distance;
|
|
267
|
+
onProgress === null || onProgress === void 0 ? void 0 : onProgress({
|
|
268
|
+
patrolled,
|
|
269
|
+
total: this._totalDistance,
|
|
270
|
+
percent: patrolled / this._totalDistance,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}, tween => {
|
|
274
|
+
this._positionTween = tween;
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch (_b) {
|
|
278
|
+
/**
|
|
279
|
+
* stop
|
|
280
|
+
*/
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// 节点转弯
|
|
284
|
+
if (this.nextPointIndex < this.nodes.length - 1) {
|
|
285
|
+
const nextRotation = this.computeNextRotation();
|
|
286
|
+
const rotationDist = this.camera.quaternion.angleTo(nextRotation);
|
|
287
|
+
/**
|
|
288
|
+
* @todo
|
|
289
|
+
*/
|
|
290
|
+
this.states.rotateDuration = this.nextPointIndex === 0 ? 1000 : rotationDist * 300 / this.options.rotateSpeed;
|
|
291
|
+
const currentPosition = controls.getPosition(new Vector3());
|
|
292
|
+
const nextPoint = (_a = this.nodes[this.nextPointIndex + 1]) === null || _a === void 0 ? void 0 : _a.getWorldPosition(new Vector3());
|
|
293
|
+
nextPoint.y += this.options.eyeHeight;
|
|
294
|
+
try {
|
|
295
|
+
await this.ssp.animation({ t: 0, }, { t: 1, }, {
|
|
296
|
+
duration: this.states.rotateDuration,
|
|
297
|
+
}, ({ t, }) => {
|
|
298
|
+
var _a;
|
|
299
|
+
if (this.isPaused) {
|
|
300
|
+
(_a = this._rotationTween) === null || _a === void 0 ? void 0 : _a.pause();
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const diff1 = nextNodePosition
|
|
304
|
+
.clone()
|
|
305
|
+
.sub(currentPosition)
|
|
306
|
+
.normalize();
|
|
307
|
+
const diff2 = nextPoint
|
|
308
|
+
.clone()
|
|
309
|
+
.sub(nextNodePosition)
|
|
310
|
+
.normalize();
|
|
311
|
+
const { x, y, z, } = diff1
|
|
312
|
+
.lerp(diff2, t)
|
|
313
|
+
.add(nextNodePosition);
|
|
314
|
+
controls.setTarget(x, y, z);
|
|
315
|
+
}, tween => {
|
|
316
|
+
this._rotationTween = tween;
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
catch (_c) {
|
|
320
|
+
/**
|
|
321
|
+
* stop
|
|
322
|
+
*/
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (!this._needsUpdateProgress)
|
|
326
|
+
this.nextPointIndex++;
|
|
327
|
+
if (!this.isStoped) {
|
|
328
|
+
await this.patrolStart();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
patrolStop() {
|
|
334
|
+
var _a, _b;
|
|
335
|
+
this.options = {
|
|
336
|
+
naviSpeed: 1,
|
|
337
|
+
rotateSpeed: 1,
|
|
338
|
+
eyeHeight: 150,
|
|
339
|
+
flyToStartPoint: true,
|
|
340
|
+
onUpdate: () => { },
|
|
341
|
+
onProgress: () => { },
|
|
342
|
+
onEnd: () => { },
|
|
343
|
+
};
|
|
344
|
+
this.nodes = [];
|
|
345
|
+
this.nextPointIndex = 0;
|
|
346
|
+
this.isPaused = false;
|
|
347
|
+
this.isStoped = true;
|
|
348
|
+
this._needsUpdateProgress = false;
|
|
349
|
+
(_a = this._positionTween) === null || _a === void 0 ? void 0 : _a.stop();
|
|
350
|
+
(_b = this._rotationTween) === null || _b === void 0 ? void 0 : _b.stop();
|
|
351
|
+
this._positionTween = null;
|
|
352
|
+
this._rotationTween = null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export { PatrolControlsPlugin as default };
|
|
357
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/index.ts"],"sourcesContent":["import { PerspectiveCamera, OrthographicCamera, Vector3, Matrix4, Quaternion, } from 'three'\r\nimport SoonSpace from 'soonspacejs'\r\nimport type { CameraViewpointData, Position, } from 'soonspacejs'\r\nimport type { Node, } from 'soonspacejs'\r\nimport type { Topology, } from 'soonspacejs'\r\nimport type { Tween, } from 'three/examples/jsm/libs/tween.module.js'\r\n\r\nconst EPS = 1e-5\r\n\r\nexport type ProgressParams = {\r\n patrolled: number;\r\n total: number;\r\n percent: number;\r\n}\r\n\r\nexport interface DefaultOptions {\r\n /*\r\n * 眼睛高度\r\n */\r\n eyeHeight: number;\r\n /**\r\n * 巡检速度\r\n */\r\n naviSpeed: number;\r\n /**\r\n * 相机转向速度\r\n */\r\n rotateSpeed: number;\r\n /**\r\n * 是否飞向起始点位置\r\n */\r\n flyToStartPoint: boolean;\r\n /**\r\n * 更新回调\r\n */\r\n onUpdate: ( realTimePosition: Position, nextNode: Node, toNextNodeDistance: number ) => void;\r\n /**\r\n * 巡检进度\r\n */\r\n onProgress: ( params: ProgressParams ) => void;\r\n /**\r\n * 结束回调\r\n */\r\n onEnd: ( endPosition: Position ) => void;\r\n}\r\n\r\nexport type StartOptions = Partial<DefaultOptions>\r\n\r\nexport type ResetOptions = Pick<StartOptions, 'eyeHeight' | 'naviSpeed' | 'rotateSpeed'>\r\n\r\nexport default class PatrolControlsPlugin {\r\n\r\n camera: PerspectiveCamera | OrthographicCamera\r\n\r\n options: DefaultOptions = {\r\n naviSpeed: 1,\r\n rotateSpeed: 1,\r\n eyeHeight: 150,\r\n flyToStartPoint: true,\r\n onUpdate: () => { },\r\n onProgress: () => {},\r\n onEnd: () => { },\r\n }\r\n\r\n states = {\r\n moveDuration: 0,\r\n rotateDuration: 0,\r\n }\r\n\r\n // 路径节点列表\r\n nodes: Node[] = []\r\n nextPointIndex = 0\r\n /**\r\n * y 轴加上 eyeHeight 的节点之间距离\r\n */\r\n _nodeDistances: number[] = []\r\n _totalDistance = 0\r\n\r\n /**\r\n * 0 - 1\r\n */\r\n _updatePercent = 0\r\n _needsUpdateProgress = false\r\n\r\n isPaused = false\r\n isStoped = true\r\n\r\n _positionTween: Tween<{distance: number}> | null = null\r\n _rotationTween: Tween<{t: number}> | null = null\r\n _cameraViewpointData: CameraViewpointData | null = null\r\n\r\n constructor ( readonly ssp: SoonSpace ) {\r\n\r\n const { cameraManager, } = this.ssp.viewport\r\n\r\n this.camera = cameraManager.mainCamera\r\n \r\n }\r\n\r\n /**\r\n * 开始巡检\r\n * \r\n * @param path \r\n * @param options \r\n */\r\n start ( path: Topology, options: StartOptions ) {\r\n\r\n if ( !this.isStoped ) {\r\n\r\n this.ssp.utils.warn( '巡检已经开始!' )\r\n\r\n return\r\n \r\n }\r\n\r\n this.ssp.controls.saveState()\r\n this.ssp.controls.enabled = false\r\n\r\n this.init( path )\r\n this.initOptions( options )\r\n this.patrolStart()\r\n\r\n }\r\n\r\n /**\r\n * 设置巡检进度\r\n * @param percent 0 - 1(不包含 1)\r\n */\r\n setProgress ( percent: number ) {\r\n\r\n this._updatePercent = Math.min( Math.max( percent, 0 ), 1 )\r\n this._needsUpdateProgress = true\r\n this._positionTween?.stop()\r\n this._rotationTween?.stop()\r\n\r\n }\r\n\r\n /**\r\n * 设置巡检参数\r\n * @param options \r\n * @returns \r\n */\r\n setOptions ( options: ResetOptions ) {\r\n\r\n if ( this.isStoped ) return\r\n\r\n const { naviSpeed, rotateSpeed, } = options\r\n\r\n if ( naviSpeed && this._positionTween ) {\r\n\r\n const newMoveDuration = this.states.moveDuration * this.options.naviSpeed / naviSpeed\r\n\r\n this._positionTween.duration( newMoveDuration )\r\n this.states.moveDuration = newMoveDuration\r\n \r\n }\r\n\r\n if ( rotateSpeed && this._rotationTween ) {\r\n\r\n const newRotateDuration = this.states.rotateDuration * this.options.rotateSpeed / rotateSpeed\r\n\r\n this._rotationTween.duration( newRotateDuration )\r\n this.states.rotateDuration = newRotateDuration\r\n \r\n }\r\n\r\n this.initOptions( options )\r\n\r\n }\r\n\r\n /**\r\n * 暂停巡检\r\n */\r\n pause () {\r\n\r\n if ( this.isPaused || this.isStoped ) return\r\n\r\n /**\r\n * 保存巡检相机视角数据\r\n */\r\n this._cameraViewpointData = this.ssp.getCameraViewpoint()\r\n\r\n this.isPaused = true\r\n this._positionTween?.pause()\r\n this._rotationTween?.pause()\r\n\r\n }\r\n\r\n /**\r\n * 恢复巡检\r\n */\r\n resume () {\r\n\r\n if ( !this.isPaused || this.isStoped ) return\r\n\r\n if ( this._cameraViewpointData ) {\r\n\r\n this.ssp.setCameraViewpoint( this._cameraViewpointData )\r\n \r\n }\r\n\r\n this.isPaused = false\r\n this._positionTween?.resume()\r\n this._rotationTween?.resume()\r\n\r\n }\r\n\r\n /**\r\n * 中断巡检\r\n */\r\n stop () {\r\n\r\n if ( this.isStoped ) return\r\n\r\n this.patrolStop()\r\n\r\n this.ssp.controls.reset()\r\n this.ssp.controls.enabled = true\r\n\r\n }\r\n\r\n private init ( path: Topology ) {\r\n\r\n this.isPaused = false\r\n this.isStoped = false\r\n this.nextPointIndex = 0\r\n\r\n // initPoints\r\n this.nodes = [ ...path.nodes ]\r\n \r\n }\r\n\r\n private initOptions ( options: StartOptions ) {\r\n\r\n const { eyeHeight, naviSpeed, rotateSpeed, flyToStartPoint = true, onUpdate, onProgress, onEnd, } = options\r\n\r\n eyeHeight && ( this.options.eyeHeight = eyeHeight )\r\n naviSpeed && ( this.options.naviSpeed = naviSpeed )\r\n rotateSpeed && ( this.options.rotateSpeed = rotateSpeed )\r\n\r\n this.options.flyToStartPoint = flyToStartPoint\r\n\r\n onUpdate && ( this.options.onUpdate = onUpdate )\r\n onProgress && ( this.options.onProgress = onProgress )\r\n onEnd && ( this.options.onEnd = onEnd )\r\n\r\n this._nodeDistances.length = 0\r\n this._nodeDistances.push( 0 )\r\n this._totalDistance = 0\r\n\r\n // compute node distance,加上 eyeHeight\r\n for ( let i = 0, len = this.nodes.length;i < len - 1;i++ ) {\r\n\r\n const currentNode = this.nodes[ i ], nextNode = this.nodes[ i + 1 ]\r\n\r\n if ( currentNode && nextNode ) {\r\n\r\n const currentWorldPosition = currentNode.getWorldPosition( new Vector3() ),\r\n nextWorldPosition = nextNode.getWorldPosition( new Vector3() )\r\n\r\n currentWorldPosition.y += this.options.eyeHeight\r\n nextWorldPosition.y += this.options.eyeHeight\r\n\r\n const distance = currentWorldPosition.distanceTo( nextWorldPosition )\r\n\r\n this._nodeDistances.push( distance )\r\n this._totalDistance += distance\r\n \r\n }\r\n \r\n }\r\n\r\n }\r\n\r\n /**\r\n * 计算两点之间的弧度\r\n * @param sourcePoint \r\n * @param targetPoint \r\n * @returns \r\n */\r\n private computedRotation ( sourcePoint: Vector3, targetPoint: Vector3 ): Quaternion {\r\n \r\n const matrix4 = new Matrix4()\r\n\r\n matrix4.lookAt( sourcePoint, targetPoint, this.camera.up )\r\n\r\n const nextRotation = new Quaternion().setFromRotationMatrix( matrix4 )\r\n\r\n return nextRotation\r\n \r\n }\r\n\r\n /**\r\n * 计算下一弧度\r\n * @returns \r\n */\r\n private computeNextRotation ( index = this.nextPointIndex ): Quaternion {\r\n\r\n const currentPoint = this.nodes[ index ]?.getWorldPosition( new Vector3() )\r\n const nextPoint = this.nodes[ index + 1 ]?.getWorldPosition( new Vector3() )\r\n\r\n return ( currentPoint && nextPoint ) ? this.computedRotation( currentPoint, nextPoint ) : new Quaternion()\r\n\r\n }\r\n\r\n /**\r\n * 开始巡检\r\n * @returns \r\n */\r\n private async patrolStart (): Promise<boolean> {\r\n\r\n return new Promise( async resolve => {\r\n\r\n const { controls, } = this.ssp\r\n\r\n const {\r\n onUpdate,\r\n onProgress,\r\n onEnd,\r\n } = this.options\r\n\r\n if ( this.nextPointIndex >= this.nodes.length ) {\r\n\r\n // 巡检结束时\r\n onEnd?.( this.camera.position.clone() )\r\n resolve( true )\r\n \r\n } else {\r\n\r\n /**\r\n * 更新进度\r\n */\r\n if ( this._needsUpdateProgress ) {\r\n\r\n let percentDistance = this._totalDistance * this._updatePercent\r\n\r\n for ( let i = 0, len = this._nodeDistances.length;i < len;i++ ) {\r\n\r\n percentDistance -= this._nodeDistances[ i ]\r\n\r\n if ( percentDistance < 0 ) {\r\n\r\n /**\r\n * 更新 index\r\n */\r\n this.nextPointIndex = i\r\n\r\n /**\r\n * 更新相机位置\r\n */\r\n percentDistance += this._nodeDistances[ i ]\r\n\r\n const percent = ( percentDistance / this._nodeDistances[ i ] ) || 0\r\n\r\n const prevNode = this.nodes[ i - 1 ], nextNode = this.nodes[ i ]\r\n\r\n const cameraPosition = new Vector3()\r\n\r\n /**\r\n * 其他点\r\n */\r\n const prevPosition = prevNode.getWorldPosition( new Vector3() ),\r\n nextPosition = nextNode.getWorldPosition( new Vector3() )\r\n\r\n prevPosition.y += this.options.eyeHeight\r\n nextPosition.y += this.options.eyeHeight\r\n\r\n const diffPosition = new Vector3()\r\n .subVectors( nextPosition, prevPosition )\r\n .multiplyScalar( percent )\r\n\r\n cameraPosition.copy( prevPosition ).add( diffPosition )\r\n\r\n controls.setPosition( cameraPosition.x, cameraPosition.y, cameraPosition.z )\r\n controls.setTarget( nextPosition.x, nextPosition.y, nextPosition.z )\r\n\r\n break\r\n \r\n }\r\n \r\n }\r\n\r\n this._needsUpdateProgress = false\r\n \r\n }\r\n\r\n const nextNode = this.nodes[ this.nextPointIndex ]\r\n const nextNodePosition = nextNode.getWorldPosition( new Vector3() )\r\n\r\n // 增加眼睛高度\r\n nextNodePosition.setY( nextNodePosition.y + this.options.eyeHeight )\r\n \r\n // 相机位置与下一点的距离\r\n const positionDist = controls.getPosition( new Vector3() ).distanceTo( nextNodePosition )\r\n\r\n /**\r\n * @todo 移动持续时间\r\n */\r\n this.states.moveDuration = this.nextPointIndex === 0 ? 1000 : positionDist / this.options.naviSpeed / 0.6\r\n\r\n controls.setTarget( nextNodePosition.x, nextNodePosition.y, nextNodePosition.z )\r\n\r\n // 路径行行进\r\n if ( this.nextPointIndex === 0 && !this.options.flyToStartPoint ) {\r\n\r\n controls.dollyTo( EPS )\r\n\r\n } else {\r\n\r\n try {\r\n\r\n await this.ssp.animation(\r\n { distance: controls.distance, },\r\n { distance: EPS, },\r\n {\r\n duration: this.states.moveDuration,\r\n },\r\n ( { distance, } ) => {\r\n \r\n if ( this.isPaused ) {\r\n \r\n this._positionTween?.pause()\r\n \r\n return\r\n \r\n }\r\n\r\n controls.dollyTo( distance )\r\n\r\n onUpdate?.( controls.getPosition( new Vector3() ), nextNode, distance )\r\n \r\n /**\r\n * progress\r\n */\r\n if ( this._nodeDistances[ this.nextPointIndex ] > 0 ) {\r\n\r\n let patrolled = this._nodeDistances.slice( 0, this.nextPointIndex + 1 ).reduce( ( accumulator, currentValue ) => accumulator + currentValue, 0 )\r\n\r\n patrolled -= distance\r\n \r\n onProgress?.( {\r\n patrolled, \r\n total: this._totalDistance,\r\n percent: patrolled / this._totalDistance,\r\n } )\r\n \r\n }\r\n \r\n },\r\n tween => {\r\n \r\n this._positionTween = tween\r\n \r\n }\r\n )\r\n \r\n } catch {\r\n \r\n /**\r\n * stop\r\n */\r\n\r\n }\r\n\r\n }\r\n\r\n // 节点转弯\r\n if ( this.nextPointIndex < this.nodes.length - 1 ) {\r\n\r\n const nextRotation = this.computeNextRotation()\r\n const rotationDist = this.camera.quaternion.angleTo( nextRotation )\r\n\r\n /**\r\n * @todo \r\n */\r\n this.states.rotateDuration = this.nextPointIndex === 0 ? 1000 : rotationDist * 300 / this.options.rotateSpeed\r\n\r\n const currentPosition = controls.getPosition( new Vector3() )\r\n const nextPoint = this.nodes[ this.nextPointIndex + 1 ]?.getWorldPosition( new Vector3() )\r\n\r\n nextPoint.y += this.options.eyeHeight\r\n \r\n try {\r\n\r\n await this.ssp.animation(\r\n { t: 0, },\r\n { t: 1, },\r\n {\r\n duration: this.states.rotateDuration,\r\n },\r\n ( { t, } ) => {\r\n \r\n if ( this.isPaused ) {\r\n \r\n this._rotationTween?.pause()\r\n\r\n return\r\n \r\n }\r\n\r\n const diff1 = nextNodePosition\r\n .clone()\r\n .sub( currentPosition )\r\n .normalize()\r\n const diff2 = nextPoint\r\n .clone()\r\n .sub( nextNodePosition )\r\n .normalize()\r\n \r\n const { x, y, z, } = diff1\r\n .lerp( diff2, t )\r\n .add( nextNodePosition )\r\n\r\n controls.setTarget( x, y, z )\r\n \r\n },\r\n tween => {\r\n \r\n this._rotationTween = tween\r\n \r\n }\r\n )\r\n \r\n } catch {\r\n\r\n /**\r\n * stop\r\n */\r\n\r\n }\r\n\r\n }\r\n\r\n if ( !this._needsUpdateProgress ) this.nextPointIndex++\r\n\r\n if ( !this.isStoped ) {\r\n\r\n await this.patrolStart()\r\n\r\n }\r\n\r\n }\r\n\r\n } )\r\n\r\n }\r\n\r\n private patrolStop () {\r\n\r\n this.options = {\r\n naviSpeed: 1,\r\n rotateSpeed: 1,\r\n eyeHeight: 150,\r\n flyToStartPoint: true,\r\n onUpdate: () => { },\r\n onProgress: () => {},\r\n onEnd: () => { },\r\n }\r\n\r\n this.nodes = []\r\n this.nextPointIndex = 0\r\n this.isPaused = false\r\n this.isStoped = true\r\n\r\n this._needsUpdateProgress = false\r\n\r\n this._positionTween?.stop()\r\n this._rotationTween?.stop()\r\n\r\n this._positionTween = null\r\n this._rotationTween = null\r\n \r\n }\r\n\r\n}\r\n"],"names":[],"mappings":"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"}
|
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.
|
|
4
|
+
"version": "2.13.7",
|
|
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": "
|
|
16
|
+
"gitHead": "550040550bf20ec0015982ff1159d0cfe9b35ed3",
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"soonspacejs": "2.13.
|
|
18
|
+
"soonspacejs": "2.13.7"
|
|
19
19
|
}
|
|
20
20
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
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
|
-
}
|