fl-web-component 2.0.8 → 2.0.10
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 +4 -0
- package/dist/fl-web-component.common.2.js +126 -48
- package/dist/fl-web-component.common.2.js.map +1 -1
- package/dist/fl-web-component.common.js +7366 -1277
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +1 -1
- package/packages/components/com-graphics/component/context.js +123 -0
- package/packages/components/com-graphics/index.vue +1243 -85
- package/packages/utils/StreamLoader.js +73 -16
- package/src/utils/threejs/editor/command.js +36 -0
- package/src/utils/threejs/editor/commands/add-element-command.js +41 -0
- package/src/utils/threejs/editor/commands/add-group-command.js +10 -0
- package/src/utils/threejs/editor/commands/clone-element-command.js +100 -0
- package/src/utils/threejs/editor/commands/move-element-command.js +57 -0
- package/src/utils/threejs/editor/commands/multi-command.js +29 -0
- package/src/utils/threejs/editor/commands/remove-element-command.js +46 -0
- package/src/utils/threejs/editor/commands/reset-original-model-style-command.js +30 -0
- package/src/utils/threejs/editor/commands/set-geometry-params-command.js +41 -0
- package/src/utils/threejs/editor/commands/set-original-model-style-command.js +56 -0
- package/src/utils/threejs/editor/commands/set-position-command.js +54 -0
- package/src/utils/threejs/editor/commands/set-rotation-command.js +53 -0
- package/src/utils/threejs/editor/commands/set-scale-command.js +54 -0
- package/src/utils/threejs/editor/commands/set-value-command.js +107 -0
- package/src/utils/threejs/editor/constants.js +107 -0
- package/src/utils/threejs/editor/element-factory.js +163 -0
- package/src/utils/threejs/editor/event-bus.js +34 -0
- package/src/utils/threejs/editor/history.js +80 -0
- package/src/utils/threejs/editor/scene-command-service.js +1529 -0
- package/src/utils/threejs/editor/scene-event-bridge.js +32 -0
- package/src/utils/threejs/editor/scene-helpers.js +415 -0
- package/src/utils/threejs/measure-angle.js +22 -2
- package/src/utils/threejs/measure-area.js +23 -3
- package/src/utils/threejs/measure-distance.js +20 -1
- package/src/utils/threejs/measure-height.js +17 -1
|
@@ -128,6 +128,7 @@ import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment
|
|
|
128
128
|
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';
|
|
129
129
|
import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer';
|
|
130
130
|
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js';
|
|
131
|
+
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
|
|
131
132
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
132
133
|
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
|
|
133
134
|
import MeasureDistance from '@/utils/threejs/measure-distance.js';
|
|
@@ -155,6 +156,10 @@ import { OBB } from 'three/examples/jsm/math/OBB.js';
|
|
|
155
156
|
import boxJson from './box.json';
|
|
156
157
|
import { StreamLoader } from '../../utils/StreamLoader.js';
|
|
157
158
|
import StreamLoaderParserWorker from '../../utils/StreamLoaderParser.worker.js';
|
|
159
|
+
import SceneCommandService from '@/utils/threejs/editor/scene-command-service.js';
|
|
160
|
+
import { EDITOR_EVENT, SCENE_NODE_TYPE, TRANSFORM_MODE } from '@/utils/threejs/editor/constants.js';
|
|
161
|
+
import { isCustomRoot, isTransformAttachableObject } from '@/utils/threejs/editor/scene-helpers.js';
|
|
162
|
+
import { onContextHandle } from './component/context';
|
|
158
163
|
|
|
159
164
|
const isDebug = process.env.NODE_ENV !== 'production' || process.env.VUE_APP_IS_WATCH === true;
|
|
160
165
|
// const isDebug = false;
|
|
@@ -168,6 +173,10 @@ export default {
|
|
|
168
173
|
return {};
|
|
169
174
|
},
|
|
170
175
|
},
|
|
176
|
+
transformEditDisabled: {
|
|
177
|
+
type: Boolean,
|
|
178
|
+
default: false,
|
|
179
|
+
},
|
|
171
180
|
containId: {
|
|
172
181
|
type: String,
|
|
173
182
|
default: 'fl-model',
|
|
@@ -200,8 +209,16 @@ export default {
|
|
|
200
209
|
totalCount: 0,
|
|
201
210
|
isPaused: false,
|
|
202
211
|
},
|
|
212
|
+
isolateMode: false,
|
|
203
213
|
};
|
|
204
214
|
},
|
|
215
|
+
watch: {
|
|
216
|
+
transformEditDisabled(val) {
|
|
217
|
+
if (val) {
|
|
218
|
+
this.detachTransformControls();
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
},
|
|
205
222
|
beforeCreate() {
|
|
206
223
|
this.spaceUp = true;
|
|
207
224
|
let arr = [
|
|
@@ -345,6 +362,23 @@ export default {
|
|
|
345
362
|
occlusionWorkerRequestMap: new Map(),
|
|
346
363
|
occlusionWorkerRequestId: 0,
|
|
347
364
|
};
|
|
365
|
+
this.sceneCommandService = null;
|
|
366
|
+
this.sceneCommandEventDisposers = [];
|
|
367
|
+
this.transformEditor = {
|
|
368
|
+
transformControls: null,
|
|
369
|
+
transformHelper: null,
|
|
370
|
+
transformMode: TRANSFORM_MODE.TRANSLATE,
|
|
371
|
+
transforming: false,
|
|
372
|
+
transformTargetUuid: '',
|
|
373
|
+
transformStartSnapshot: null,
|
|
374
|
+
suppressSelectionOnce: false,
|
|
375
|
+
suppressSelectionTimer: null,
|
|
376
|
+
cameraControlsEnabled: true,
|
|
377
|
+
pointerCameraGuard: false,
|
|
378
|
+
pointerCameraEnabled: true,
|
|
379
|
+
keydownHandler: null,
|
|
380
|
+
handlers: {},
|
|
381
|
+
};
|
|
348
382
|
this.modelGroups = [];
|
|
349
383
|
this.modelActions = [];
|
|
350
384
|
this.lastMiddleClickTime = 0;
|
|
@@ -369,8 +403,10 @@ export default {
|
|
|
369
403
|
this.instructions = document.getElementById(this.containId); // 'fl-model'
|
|
370
404
|
this.initRender();
|
|
371
405
|
this.initScene();
|
|
406
|
+
this.initSceneCommandService();
|
|
372
407
|
this.initCamera();
|
|
373
408
|
this.initControl();
|
|
409
|
+
this.initTransformControls();
|
|
374
410
|
this.initPostProcessing();
|
|
375
411
|
// 初始化统一的相机事件监听
|
|
376
412
|
this.initCameraChangeObserver();
|
|
@@ -379,14 +415,7 @@ export default {
|
|
|
379
415
|
this.exportParmas();
|
|
380
416
|
|
|
381
417
|
// 判断是设备是手机还是电脑
|
|
382
|
-
|
|
383
|
-
if (isMobileDevice) {
|
|
384
|
-
this.renderer.domElement.addEventListener('pointerup', this.mouseClick, false);
|
|
385
|
-
this.renderer.domElement.addEventListener('pointerdown', this.mouseDown, false);
|
|
386
|
-
} else {
|
|
387
|
-
this.renderer.domElement.addEventListener('mouseup', this.mouseClick, false);
|
|
388
|
-
this.renderer.domElement.addEventListener('mousedown', this.mouseDown, false);
|
|
389
|
-
}
|
|
418
|
+
this.bindScenePointerEvents();
|
|
390
419
|
this.animate();
|
|
391
420
|
},
|
|
392
421
|
beforeDestroy() {
|
|
@@ -394,6 +423,764 @@ export default {
|
|
|
394
423
|
this.destroyScene();
|
|
395
424
|
},
|
|
396
425
|
methods: {
|
|
426
|
+
bindScenePointerEvents() {
|
|
427
|
+
if (!this.renderer || !this.renderer.domElement) return;
|
|
428
|
+
this.renderer.domElement.addEventListener('pointerup', this.mouseClick, true);
|
|
429
|
+
this.renderer.domElement.addEventListener('pointerdown', this.mouseDown, true);
|
|
430
|
+
},
|
|
431
|
+
unbindScenePointerEvents() {
|
|
432
|
+
if (!this.renderer || !this.renderer.domElement) return;
|
|
433
|
+
this.renderer.domElement.removeEventListener('pointerup', this.mouseClick, true);
|
|
434
|
+
this.renderer.domElement.removeEventListener('pointerdown', this.mouseDown, true);
|
|
435
|
+
this.renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
|
|
436
|
+
this.renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
|
|
437
|
+
this.renderer.domElement.removeEventListener('pointerup', this.mouseClick, false);
|
|
438
|
+
this.renderer.domElement.removeEventListener('pointerdown', this.mouseDown, false);
|
|
439
|
+
},
|
|
440
|
+
setPointerCameraGuard(active) {
|
|
441
|
+
const editor = this.transformEditor;
|
|
442
|
+
if (!editor || !this.cameraControls) return;
|
|
443
|
+
if (active) {
|
|
444
|
+
if (editor.pointerCameraGuard) return;
|
|
445
|
+
editor.pointerCameraEnabled = this.cameraControls.enabled;
|
|
446
|
+
editor.pointerCameraGuard = true;
|
|
447
|
+
this.cameraControls.enabled = false;
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if (!editor.pointerCameraGuard) {
|
|
451
|
+
this.restoreTransformCameraControls();
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (!(this.firstPerSign && this.pointControls && this.pointControls.isLocked)) {
|
|
455
|
+
this.cameraControls.enabled = editor.pointerCameraEnabled || editor.cameraControlsEnabled;
|
|
456
|
+
}
|
|
457
|
+
editor.pointerCameraGuard = false;
|
|
458
|
+
},
|
|
459
|
+
restoreTransformCameraControls() {
|
|
460
|
+
const editor = this.transformEditor;
|
|
461
|
+
if (!editor || !this.cameraControls) return;
|
|
462
|
+
const isFirstPersonLocked = !!(
|
|
463
|
+
this.firstPerSign &&
|
|
464
|
+
this.pointControls &&
|
|
465
|
+
this.pointControls.isLocked
|
|
466
|
+
);
|
|
467
|
+
editor.pointerCameraGuard = false;
|
|
468
|
+
editor.transforming = false;
|
|
469
|
+
if (!isFirstPersonLocked) {
|
|
470
|
+
this.cameraControls.enabled = true;
|
|
471
|
+
editor.cameraControlsEnabled = true;
|
|
472
|
+
editor.pointerCameraEnabled = true;
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
scheduleSuppressSelectionOnce() {
|
|
476
|
+
const editor = this.transformEditor;
|
|
477
|
+
if (!editor) return;
|
|
478
|
+
editor.suppressSelectionOnce = true;
|
|
479
|
+
if (editor.suppressSelectionTimer) {
|
|
480
|
+
clearTimeout(editor.suppressSelectionTimer);
|
|
481
|
+
}
|
|
482
|
+
editor.suppressSelectionTimer = setTimeout(() => {
|
|
483
|
+
editor.suppressSelectionOnce = false;
|
|
484
|
+
editor.suppressSelectionTimer = null;
|
|
485
|
+
}, 0);
|
|
486
|
+
},
|
|
487
|
+
initSceneCommandService() {
|
|
488
|
+
if (!this.scene || this.sceneCommandService) return;
|
|
489
|
+
this.sceneCommandService = new SceneCommandService({
|
|
490
|
+
THREE: this.THREE,
|
|
491
|
+
getScene: () => this.scene,
|
|
492
|
+
requestRender: () => {
|
|
493
|
+
if (typeof this.notifyCameraChange === 'function') {
|
|
494
|
+
this.notifyCameraChange('customEdit');
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
});
|
|
498
|
+
Object.values(EDITOR_EVENT).forEach(eventName => {
|
|
499
|
+
const dispose = this.sceneCommandService.subscribe(eventName, payload => {
|
|
500
|
+
this.handleSceneCommandEvent(eventName, payload);
|
|
501
|
+
this.$emit(eventName, payload);
|
|
502
|
+
});
|
|
503
|
+
this.sceneCommandEventDisposers.push(dispose);
|
|
504
|
+
});
|
|
505
|
+
},
|
|
506
|
+
handleSceneCommandEvent(eventName, payload) {
|
|
507
|
+
switch (eventName) {
|
|
508
|
+
case EDITOR_EVENT.OBJECT_SELECTED:
|
|
509
|
+
this.syncTransformSelection(payload && payload.uuid ? payload.uuid : '');
|
|
510
|
+
break;
|
|
511
|
+
case EDITOR_EVENT.TRANSFORM_MODE_CHANGED:
|
|
512
|
+
this.applyTransformMode(
|
|
513
|
+
payload && payload.mode ? payload.mode : TRANSFORM_MODE.TRANSLATE
|
|
514
|
+
);
|
|
515
|
+
break;
|
|
516
|
+
case EDITOR_EVENT.OBJECT_ADDED:
|
|
517
|
+
case EDITOR_EVENT.OBJECT_REMOVED:
|
|
518
|
+
case EDITOR_EVENT.OBJECT_CHANGED:
|
|
519
|
+
case EDITOR_EVENT.HISTORY_CHANGED:
|
|
520
|
+
case EDITOR_EVENT.SCENE_GRAPH_CHANGED:
|
|
521
|
+
this.ensureTransformSelectionValid();
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
initTransformControls() {
|
|
526
|
+
if (!this.scene || !this.camera || !this.renderer || this.transformEditor.transformControls)
|
|
527
|
+
return;
|
|
528
|
+
const controls = new TransformControls(this.camera, this.renderer.domElement);
|
|
529
|
+
const helper = controls.getHelper();
|
|
530
|
+
controls.setMode(this.getTransformMode());
|
|
531
|
+
helper.visible = false;
|
|
532
|
+
helper.traverse(item => {
|
|
533
|
+
if (!item.userData) {
|
|
534
|
+
item.userData = {};
|
|
535
|
+
}
|
|
536
|
+
item.userData.transformControlHelper = true;
|
|
537
|
+
});
|
|
538
|
+
this.transformEditor.handlers = {
|
|
539
|
+
change: () => {
|
|
540
|
+
if (typeof this.notifyCameraChange === 'function') {
|
|
541
|
+
this.notifyCameraChange('customTransformControl');
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
objectChange: () => {
|
|
545
|
+
this.handleTransformObjectChange();
|
|
546
|
+
},
|
|
547
|
+
mouseUp: () => {
|
|
548
|
+
this.scheduleSuppressSelectionOnce();
|
|
549
|
+
this.restoreTransformCameraControls();
|
|
550
|
+
},
|
|
551
|
+
draggingChanged: event => {
|
|
552
|
+
this.handleTransformDraggingChanged(event);
|
|
553
|
+
},
|
|
554
|
+
};
|
|
555
|
+
controls.addEventListener('change', this.transformEditor.handlers.change);
|
|
556
|
+
controls.addEventListener('objectChange', this.transformEditor.handlers.objectChange);
|
|
557
|
+
controls.addEventListener('mouseUp', this.transformEditor.handlers.mouseUp);
|
|
558
|
+
controls.addEventListener('dragging-changed', this.transformEditor.handlers.draggingChanged);
|
|
559
|
+
this.scene.add(helper);
|
|
560
|
+
this.transformEditor.transformControls = controls;
|
|
561
|
+
this.transformEditor.transformHelper = helper;
|
|
562
|
+
this.transformEditor.keydownHandler = event => {
|
|
563
|
+
const isEscape = event && (event.key === 'Escape' || event.keyCode === 27);
|
|
564
|
+
if (!isEscape) return;
|
|
565
|
+
if (this.sceneCommandService && this.sceneCommandService.selectedUuid) {
|
|
566
|
+
this.clearCustomSelection();
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
window.addEventListener('keydown', this.transformEditor.keydownHandler, false);
|
|
570
|
+
},
|
|
571
|
+
disposeTransformControls() {
|
|
572
|
+
const editor = this.transformEditor;
|
|
573
|
+
if (!editor) return;
|
|
574
|
+
if (editor.keydownHandler) {
|
|
575
|
+
window.removeEventListener('keydown', editor.keydownHandler, false);
|
|
576
|
+
editor.keydownHandler = null;
|
|
577
|
+
}
|
|
578
|
+
const controls = editor.transformControls;
|
|
579
|
+
const helper = editor.transformHelper;
|
|
580
|
+
if (editor.suppressSelectionTimer) {
|
|
581
|
+
clearTimeout(editor.suppressSelectionTimer);
|
|
582
|
+
editor.suppressSelectionTimer = null;
|
|
583
|
+
}
|
|
584
|
+
if (controls) {
|
|
585
|
+
if (editor.handlers.change) {
|
|
586
|
+
controls.removeEventListener('change', editor.handlers.change);
|
|
587
|
+
}
|
|
588
|
+
if (editor.handlers.objectChange) {
|
|
589
|
+
controls.removeEventListener('objectChange', editor.handlers.objectChange);
|
|
590
|
+
}
|
|
591
|
+
if (editor.handlers.mouseUp) {
|
|
592
|
+
controls.removeEventListener('mouseUp', editor.handlers.mouseUp);
|
|
593
|
+
}
|
|
594
|
+
if (editor.handlers.draggingChanged) {
|
|
595
|
+
controls.removeEventListener('dragging-changed', editor.handlers.draggingChanged);
|
|
596
|
+
}
|
|
597
|
+
controls.detach();
|
|
598
|
+
}
|
|
599
|
+
if (helper && this.scene) {
|
|
600
|
+
this.scene.remove(helper);
|
|
601
|
+
}
|
|
602
|
+
editor.handlers = {};
|
|
603
|
+
editor.transformControls = null;
|
|
604
|
+
editor.transformHelper = null;
|
|
605
|
+
editor.transforming = false;
|
|
606
|
+
editor.transformTargetUuid = '';
|
|
607
|
+
editor.transformStartSnapshot = null;
|
|
608
|
+
editor.suppressSelectionOnce = false;
|
|
609
|
+
},
|
|
610
|
+
isTransformEditBlocked() {
|
|
611
|
+
return !!(this.firstPerSign && this.pointControls && this.pointControls.isLocked);
|
|
612
|
+
},
|
|
613
|
+
isTransformControlDisabled() {
|
|
614
|
+
return !!this.transformEditDisabled || this.isTransformEditBlocked();
|
|
615
|
+
},
|
|
616
|
+
applyTransformMode(mode) {
|
|
617
|
+
const nextMode =
|
|
618
|
+
Object.values(TRANSFORM_MODE).indexOf(mode) !== -1 ? mode : TRANSFORM_MODE.TRANSLATE;
|
|
619
|
+
this.transformEditor.transformMode = nextMode;
|
|
620
|
+
if (this.transformEditor.transformControls) {
|
|
621
|
+
this.transformEditor.transformControls.setMode(nextMode);
|
|
622
|
+
}
|
|
623
|
+
return nextMode;
|
|
624
|
+
},
|
|
625
|
+
getSelectableSceneObject(target) {
|
|
626
|
+
if (!this.sceneCommandService || !target) return null;
|
|
627
|
+
return this.sceneCommandService.findSelectableObject(target);
|
|
628
|
+
},
|
|
629
|
+
getSelectableCustomObject(target) {
|
|
630
|
+
const object = this.getSelectableSceneObject(target);
|
|
631
|
+
if (!object || !this.sceneCommandService) return null;
|
|
632
|
+
const nodeType = this.sceneCommandService.getNodeType(object.uuid);
|
|
633
|
+
return nodeType === 'custom-element' ||
|
|
634
|
+
nodeType === 'custom-group' ||
|
|
635
|
+
nodeType === 'custom-root'
|
|
636
|
+
? object
|
|
637
|
+
: null;
|
|
638
|
+
},
|
|
639
|
+
selectSceneObject(uuid, options = {}) {
|
|
640
|
+
if (!this.sceneCommandService) return null;
|
|
641
|
+
if (this.isTransformEditBlocked()) return null;
|
|
642
|
+
return this.sceneCommandService.selectObject(uuid, options);
|
|
643
|
+
},
|
|
644
|
+
selectElement(uuid, options = {}) {
|
|
645
|
+
if (!this.sceneCommandService) return null;
|
|
646
|
+
if (this.isTransformEditBlocked()) return null;
|
|
647
|
+
return this.sceneCommandService.selectElement(uuid, options);
|
|
648
|
+
},
|
|
649
|
+
clearCustomSelection(options = {}) {
|
|
650
|
+
if (!this.sceneCommandService) {
|
|
651
|
+
this.detachTransformControls();
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
this.sceneCommandService.clearSelection(options);
|
|
655
|
+
},
|
|
656
|
+
getDefaultPrimitivePlacement() {
|
|
657
|
+
const defaultPosition = { x: 0, y: 0, z: 0 };
|
|
658
|
+
const defaultSize = 100;
|
|
659
|
+
if (!this.cameraControls) {
|
|
660
|
+
return {
|
|
661
|
+
position: defaultPosition,
|
|
662
|
+
size: defaultSize,
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
const target = new this.THREE.Vector3();
|
|
666
|
+
if (typeof this.cameraControls.getTarget === 'function') {
|
|
667
|
+
this.cameraControls.getTarget(target);
|
|
668
|
+
} else if (this.cameraControls._target) {
|
|
669
|
+
target.copy(this.cameraControls._target);
|
|
670
|
+
}
|
|
671
|
+
const distance =
|
|
672
|
+
this.camera && this.camera.position && typeof this.camera.position.distanceTo === 'function'
|
|
673
|
+
? this.camera.position.distanceTo(target)
|
|
674
|
+
: 0;
|
|
675
|
+
const size = Math.min(Math.max(distance * 0.008, 20), 100) || defaultSize;
|
|
676
|
+
return {
|
|
677
|
+
position: {
|
|
678
|
+
x: target.x,
|
|
679
|
+
y: target.y,
|
|
680
|
+
z: target.z,
|
|
681
|
+
},
|
|
682
|
+
size,
|
|
683
|
+
};
|
|
684
|
+
},
|
|
685
|
+
buildDefaultPrimitiveTransform(transform, position) {
|
|
686
|
+
const nextTransform = transform && typeof transform === 'object' ? { ...transform } : {};
|
|
687
|
+
if (!Array.isArray(nextTransform.position)) {
|
|
688
|
+
nextTransform.position = [position.x, position.y, position.z];
|
|
689
|
+
}
|
|
690
|
+
if (!Array.isArray(nextTransform.rotation)) {
|
|
691
|
+
nextTransform.rotation = [0, 0, 0];
|
|
692
|
+
}
|
|
693
|
+
if (!Array.isArray(nextTransform.scale)) {
|
|
694
|
+
nextTransform.scale = [1, 1, 1];
|
|
695
|
+
}
|
|
696
|
+
return nextTransform;
|
|
697
|
+
},
|
|
698
|
+
buildDefaultPrimitiveGeometryParams(type, size) {
|
|
699
|
+
const primitiveSize = Number.isFinite(size) ? size : 100;
|
|
700
|
+
switch (type) {
|
|
701
|
+
case 'box':
|
|
702
|
+
return {
|
|
703
|
+
width: primitiveSize,
|
|
704
|
+
height: primitiveSize,
|
|
705
|
+
depth: primitiveSize,
|
|
706
|
+
};
|
|
707
|
+
case 'sphere':
|
|
708
|
+
return {
|
|
709
|
+
radius: primitiveSize / 2,
|
|
710
|
+
phiStart: 0,
|
|
711
|
+
phiLength: 360,
|
|
712
|
+
thetaStart: 0,
|
|
713
|
+
thetaLength: 180,
|
|
714
|
+
};
|
|
715
|
+
case 'cylinder':
|
|
716
|
+
return {
|
|
717
|
+
radiusTop: primitiveSize / 2,
|
|
718
|
+
radiusBottom: primitiveSize / 2,
|
|
719
|
+
height: primitiveSize,
|
|
720
|
+
};
|
|
721
|
+
case 'capsule':
|
|
722
|
+
return {
|
|
723
|
+
radius: primitiveSize / 3,
|
|
724
|
+
length: primitiveSize,
|
|
725
|
+
};
|
|
726
|
+
case 'tetrahedron':
|
|
727
|
+
case 'octahedron':
|
|
728
|
+
return {
|
|
729
|
+
radius: primitiveSize / 2,
|
|
730
|
+
};
|
|
731
|
+
case 'ring':
|
|
732
|
+
return {
|
|
733
|
+
radius: primitiveSize / 2,
|
|
734
|
+
tube: primitiveSize / 8,
|
|
735
|
+
arc: 360,
|
|
736
|
+
};
|
|
737
|
+
default:
|
|
738
|
+
return {};
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
normalizeAddElementOptions(options = {}) {
|
|
742
|
+
const placement = this.getDefaultPrimitivePlacement();
|
|
743
|
+
const nextOptions = { ...options };
|
|
744
|
+
nextOptions.transform = this.buildDefaultPrimitiveTransform(
|
|
745
|
+
nextOptions.transform,
|
|
746
|
+
placement.position
|
|
747
|
+
);
|
|
748
|
+
if (!nextOptions.geometryParams) {
|
|
749
|
+
nextOptions.geometryParams = this.buildDefaultPrimitiveGeometryParams(
|
|
750
|
+
nextOptions.type,
|
|
751
|
+
placement.size
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
return nextOptions;
|
|
755
|
+
},
|
|
756
|
+
normalizeAddGroupOptions(options = {}) {
|
|
757
|
+
const placement = this.getDefaultPrimitivePlacement();
|
|
758
|
+
return {
|
|
759
|
+
...options,
|
|
760
|
+
transform: this.buildDefaultPrimitiveTransform(options.transform, placement.position),
|
|
761
|
+
};
|
|
762
|
+
},
|
|
763
|
+
addElement(options) {
|
|
764
|
+
if (!this.sceneCommandService) return null;
|
|
765
|
+
return this.sceneCommandService.addElement(this.normalizeAddElementOptions(options));
|
|
766
|
+
},
|
|
767
|
+
addGroup(options = {}) {
|
|
768
|
+
if (!this.sceneCommandService) return null;
|
|
769
|
+
return this.sceneCommandService.addGroup(this.normalizeAddGroupOptions(options));
|
|
770
|
+
},
|
|
771
|
+
removeElement(uuid) {
|
|
772
|
+
if (!this.sceneCommandService) return;
|
|
773
|
+
this.sceneCommandService.removeElement(uuid);
|
|
774
|
+
},
|
|
775
|
+
cloneElement(uuid, options = {}) {
|
|
776
|
+
if (!this.sceneCommandService) return null;
|
|
777
|
+
return this.sceneCommandService.cloneElement(uuid, options);
|
|
778
|
+
},
|
|
779
|
+
moveElement(uuid, targetParentUuid, referenceUuid, insertMode = 'append') {
|
|
780
|
+
if (!this.sceneCommandService) return null;
|
|
781
|
+
return this.sceneCommandService.moveElement(
|
|
782
|
+
uuid,
|
|
783
|
+
targetParentUuid,
|
|
784
|
+
referenceUuid,
|
|
785
|
+
insertMode
|
|
786
|
+
);
|
|
787
|
+
},
|
|
788
|
+
updateElement(options) {
|
|
789
|
+
if (!this.sceneCommandService) return null;
|
|
790
|
+
return this.sceneCommandService.updateElement(options);
|
|
791
|
+
},
|
|
792
|
+
updateOriginalModelStyle(options) {
|
|
793
|
+
if (!this.sceneCommandService) return null;
|
|
794
|
+
return this.sceneCommandService.updateOriginalModelStyle(options);
|
|
795
|
+
},
|
|
796
|
+
resetOriginalModelStyle(uuid) {
|
|
797
|
+
if (!this.sceneCommandService) return null;
|
|
798
|
+
return this.sceneCommandService.resetOriginalModelStyle(uuid);
|
|
799
|
+
},
|
|
800
|
+
setElementPosition(uuid, position, oldPosition) {
|
|
801
|
+
if (!this.sceneCommandService) return null;
|
|
802
|
+
return this.sceneCommandService.setElementPosition(uuid, position, oldPosition);
|
|
803
|
+
},
|
|
804
|
+
setElementRotation(uuid, rotation, oldRotation) {
|
|
805
|
+
if (!this.sceneCommandService) return null;
|
|
806
|
+
return this.sceneCommandService.setElementRotation(uuid, rotation, oldRotation);
|
|
807
|
+
},
|
|
808
|
+
setElementScale(uuid, scale, oldScale) {
|
|
809
|
+
if (!this.sceneCommandService) return null;
|
|
810
|
+
return this.sceneCommandService.setElementScale(uuid, scale, oldScale);
|
|
811
|
+
},
|
|
812
|
+
renameElement(uuid, name) {
|
|
813
|
+
if (!this.sceneCommandService) return null;
|
|
814
|
+
return this.sceneCommandService.renameElement(uuid, name);
|
|
815
|
+
},
|
|
816
|
+
setElementVisible(uuid, visible) {
|
|
817
|
+
if (!this.sceneCommandService) return null;
|
|
818
|
+
return this.sceneCommandService.setElementVisible(uuid, visible);
|
|
819
|
+
},
|
|
820
|
+
setTransformMode(mode) {
|
|
821
|
+
if (!this.sceneCommandService) return null;
|
|
822
|
+
return this.sceneCommandService.setTransformMode(mode, {
|
|
823
|
+
forceEmit: true,
|
|
824
|
+
});
|
|
825
|
+
},
|
|
826
|
+
getTransformMode() {
|
|
827
|
+
if (!this.sceneCommandService) {
|
|
828
|
+
return this.transformEditor.transformMode;
|
|
829
|
+
}
|
|
830
|
+
return this.sceneCommandService.getTransformMode();
|
|
831
|
+
},
|
|
832
|
+
getCustomObjectSnapshot(uuid) {
|
|
833
|
+
if (!this.sceneCommandService) return null;
|
|
834
|
+
return this.sceneCommandService.getObjectSnapshot(uuid);
|
|
835
|
+
},
|
|
836
|
+
getModelReviseLocateName(uuid) {
|
|
837
|
+
if (!uuid || !this.sceneCommandService) return '';
|
|
838
|
+
const snapshot = this.sceneCommandService.getObjectSnapshot(uuid);
|
|
839
|
+
if (snapshot && snapshot.name) {
|
|
840
|
+
return snapshot.name;
|
|
841
|
+
}
|
|
842
|
+
const originalRecord = this.sceneCommandService.getOriginalModelStyle(uuid);
|
|
843
|
+
return originalRecord && originalRecord.name ? originalRecord.name : '';
|
|
844
|
+
},
|
|
845
|
+
setOriginalModelNodeName(options = {}) {
|
|
846
|
+
if (!this.sceneCommandService || !this.sceneCommandService.setOriginalModelNodeName) {
|
|
847
|
+
return '';
|
|
848
|
+
}
|
|
849
|
+
return this.sceneCommandService.setOriginalModelNodeName(options);
|
|
850
|
+
},
|
|
851
|
+
getOriginalModelSelectablePriority(object) {
|
|
852
|
+
if (!object) return -1;
|
|
853
|
+
let priority = 0;
|
|
854
|
+
if (object.isInstancedMesh === true) {
|
|
855
|
+
priority += 8;
|
|
856
|
+
}
|
|
857
|
+
if (object.type && object.type !== 'Group') {
|
|
858
|
+
priority += 4;
|
|
859
|
+
}
|
|
860
|
+
if (object.material) {
|
|
861
|
+
priority += 2;
|
|
862
|
+
}
|
|
863
|
+
return priority;
|
|
864
|
+
},
|
|
865
|
+
findOriginalModelSelectableObject(uuid, name) {
|
|
866
|
+
if (
|
|
867
|
+
this.sceneCommandService &&
|
|
868
|
+
typeof this.sceneCommandService.resolveOriginalModelObject === 'function'
|
|
869
|
+
) {
|
|
870
|
+
const originalObject = this.sceneCommandService.resolveOriginalModelObject({
|
|
871
|
+
uuid,
|
|
872
|
+
name,
|
|
873
|
+
});
|
|
874
|
+
if (originalObject && originalObject.uuid) {
|
|
875
|
+
return originalObject;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
const objectByUuid = this.sceneCommandService
|
|
879
|
+
? this.sceneCommandService.getObjectByUuid(uuid)
|
|
880
|
+
: null;
|
|
881
|
+
if (objectByUuid) {
|
|
882
|
+
return objectByUuid;
|
|
883
|
+
}
|
|
884
|
+
if (!name) {
|
|
885
|
+
return null;
|
|
886
|
+
}
|
|
887
|
+
const objectList = this.getObjectByName(name, '');
|
|
888
|
+
if (!Array.isArray(objectList) || objectList.length === 0) {
|
|
889
|
+
return null;
|
|
890
|
+
}
|
|
891
|
+
return (
|
|
892
|
+
objectList
|
|
893
|
+
.filter(item => item && item.uuid)
|
|
894
|
+
.sort(
|
|
895
|
+
(left, right) =>
|
|
896
|
+
this.getOriginalModelSelectablePriority(right) -
|
|
897
|
+
this.getOriginalModelSelectablePriority(left)
|
|
898
|
+
)[0] || null
|
|
899
|
+
);
|
|
900
|
+
},
|
|
901
|
+
async locateModelByUuid(uuid) {
|
|
902
|
+
if (!uuid || !this.sceneCommandService) return false;
|
|
903
|
+
const originalRecord = this.sceneCommandService.getOriginalModelStyle(uuid);
|
|
904
|
+
const nodeType =
|
|
905
|
+
this.sceneCommandService.getNodeType(uuid) ||
|
|
906
|
+
(originalRecord ? SCENE_NODE_TYPE.ORIGINAL_MODEL : '');
|
|
907
|
+
if (uuid === SCENE_NODE_TYPE.ORIGINAL_MODEL || nodeType === SCENE_NODE_TYPE.CUSTOM_ROOT) {
|
|
908
|
+
this.selectElement();
|
|
909
|
+
return false;
|
|
910
|
+
}
|
|
911
|
+
if (
|
|
912
|
+
nodeType === SCENE_NODE_TYPE.CUSTOM_GROUP ||
|
|
913
|
+
nodeType === SCENE_NODE_TYPE.CUSTOM_ELEMENT
|
|
914
|
+
) {
|
|
915
|
+
this.selectElement(uuid);
|
|
916
|
+
return this.locateModel(uuid);
|
|
917
|
+
}
|
|
918
|
+
const name =
|
|
919
|
+
originalRecord && originalRecord.name
|
|
920
|
+
? originalRecord.name
|
|
921
|
+
: this.getModelReviseLocateName(uuid);
|
|
922
|
+
if (nodeType !== SCENE_NODE_TYPE.ORIGINAL_MODEL && !name) {
|
|
923
|
+
return false;
|
|
924
|
+
}
|
|
925
|
+
if (!name) return false;
|
|
926
|
+
try {
|
|
927
|
+
const targetObject = this.findOriginalModelSelectableObject(uuid, name);
|
|
928
|
+
if (targetObject && targetObject.uuid) {
|
|
929
|
+
this.selectSceneObject(targetObject.uuid);
|
|
930
|
+
} else {
|
|
931
|
+
this.selectElement();
|
|
932
|
+
}
|
|
933
|
+
await this.loadModelByIds({
|
|
934
|
+
params: {
|
|
935
|
+
ids: [name],
|
|
936
|
+
},
|
|
937
|
+
onComplete: () => {
|
|
938
|
+
this.locateModel([name]);
|
|
939
|
+
const loadedObject = this.findOriginalModelSelectableObject(uuid, name);
|
|
940
|
+
if (loadedObject && loadedObject.uuid) {
|
|
941
|
+
this.selectSceneObject(loadedObject.uuid);
|
|
942
|
+
}
|
|
943
|
+
},
|
|
944
|
+
});
|
|
945
|
+
return true;
|
|
946
|
+
} catch (error) {
|
|
947
|
+
return false;
|
|
948
|
+
}
|
|
949
|
+
},
|
|
950
|
+
getSelectedSceneObjectSnapshot() {
|
|
951
|
+
if (!this.sceneCommandService) return null;
|
|
952
|
+
return this.sceneCommandService.getSelectedObjectSnapshot();
|
|
953
|
+
},
|
|
954
|
+
getSelectedCustomObjectSnapshot() {
|
|
955
|
+
if (!this.sceneCommandService) return null;
|
|
956
|
+
if (this.sceneCommandService.getSelectedNodeType() === 'original-model') {
|
|
957
|
+
return null;
|
|
958
|
+
}
|
|
959
|
+
return this.sceneCommandService.getSelectedObjectSnapshot();
|
|
960
|
+
},
|
|
961
|
+
getSelectedOriginalModelStyleSnapshot() {
|
|
962
|
+
if (!this.sceneCommandService) return null;
|
|
963
|
+
return this.sceneCommandService.getSelectedOriginalModelStyleSnapshot();
|
|
964
|
+
},
|
|
965
|
+
getOriginalModelStyleChanges() {
|
|
966
|
+
if (!this.sceneCommandService) return [];
|
|
967
|
+
return this.sceneCommandService.getOriginalModelStyleChanges();
|
|
968
|
+
},
|
|
969
|
+
undo() {
|
|
970
|
+
if (!this.sceneCommandService) return null;
|
|
971
|
+
return this.sceneCommandService.undo();
|
|
972
|
+
},
|
|
973
|
+
redo() {
|
|
974
|
+
if (!this.sceneCommandService) return null;
|
|
975
|
+
return this.sceneCommandService.redo();
|
|
976
|
+
},
|
|
977
|
+
subscribe(eventName, handler) {
|
|
978
|
+
if (!this.sceneCommandService) {
|
|
979
|
+
return function () {};
|
|
980
|
+
}
|
|
981
|
+
return this.sceneCommandService.subscribe(eventName, handler);
|
|
982
|
+
},
|
|
983
|
+
getCustomTree() {
|
|
984
|
+
if (!this.sceneCommandService) return null;
|
|
985
|
+
return this.sceneCommandService.getCustomTree();
|
|
986
|
+
},
|
|
987
|
+
getCustomSaveTree() {
|
|
988
|
+
if (!this.sceneCommandService) return null;
|
|
989
|
+
return this.sceneCommandService.getCustomSaveTree();
|
|
990
|
+
},
|
|
991
|
+
getSaveSnapshot() {
|
|
992
|
+
if (!this.sceneCommandService) return null;
|
|
993
|
+
return this.sceneCommandService.getSaveSnapshot();
|
|
994
|
+
},
|
|
995
|
+
applySaveSnapshot(snapshot) {
|
|
996
|
+
if (!this.sceneCommandService) return null;
|
|
997
|
+
return this.sceneCommandService.applySaveSnapshot(snapshot);
|
|
998
|
+
},
|
|
999
|
+
serializeCustomElements() {
|
|
1000
|
+
if (!this.sceneCommandService) return null;
|
|
1001
|
+
return this.sceneCommandService.serializeCustomElements();
|
|
1002
|
+
},
|
|
1003
|
+
deserializeCustomElements(json) {
|
|
1004
|
+
if (!this.sceneCommandService) return null;
|
|
1005
|
+
return this.sceneCommandService.deserializeCustomElements(json);
|
|
1006
|
+
},
|
|
1007
|
+
removeAllCustomElements() {
|
|
1008
|
+
if (!this.sceneCommandService) return;
|
|
1009
|
+
this.sceneCommandService.removeAllCustomElements();
|
|
1010
|
+
},
|
|
1011
|
+
resolveInsertTarget(selectedUuid) {
|
|
1012
|
+
if (!this.sceneCommandService) return null;
|
|
1013
|
+
return this.sceneCommandService.resolveInsertTarget(selectedUuid);
|
|
1014
|
+
},
|
|
1015
|
+
detachTransformControls() {
|
|
1016
|
+
const editor = this.transformEditor;
|
|
1017
|
+
if (!editor) return;
|
|
1018
|
+
const controls = editor.transformControls;
|
|
1019
|
+
const helper = editor.transformHelper;
|
|
1020
|
+
if (controls) {
|
|
1021
|
+
controls.detach();
|
|
1022
|
+
}
|
|
1023
|
+
if (helper) {
|
|
1024
|
+
helper.visible = false;
|
|
1025
|
+
}
|
|
1026
|
+
editor.transforming = false;
|
|
1027
|
+
editor.transformTargetUuid = '';
|
|
1028
|
+
editor.transformStartSnapshot = null;
|
|
1029
|
+
this.restoreTransformCameraControls();
|
|
1030
|
+
if (typeof this.notifyCameraChange === 'function') {
|
|
1031
|
+
this.notifyCameraChange('customTransformDetach');
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
attachTransformControls(object) {
|
|
1035
|
+
const editor = this.transformEditor;
|
|
1036
|
+
if (!editor || !editor.transformControls) return null;
|
|
1037
|
+
if (this.isTransformControlDisabled()) {
|
|
1038
|
+
this.detachTransformControls();
|
|
1039
|
+
return null;
|
|
1040
|
+
}
|
|
1041
|
+
if (!object || isCustomRoot(object) || !isTransformAttachableObject(object)) {
|
|
1042
|
+
this.detachTransformControls();
|
|
1043
|
+
return null;
|
|
1044
|
+
}
|
|
1045
|
+
object.updateMatrixWorld(true);
|
|
1046
|
+
editor.transformControls.attach(object);
|
|
1047
|
+
if (editor.transformHelper) {
|
|
1048
|
+
editor.transformHelper.visible = true;
|
|
1049
|
+
}
|
|
1050
|
+
editor.transformTargetUuid = object.uuid;
|
|
1051
|
+
this.applyTransformMode(this.getTransformMode());
|
|
1052
|
+
if (typeof this.notifyCameraChange === 'function') {
|
|
1053
|
+
this.notifyCameraChange('customTransformAttach');
|
|
1054
|
+
}
|
|
1055
|
+
return object;
|
|
1056
|
+
},
|
|
1057
|
+
syncTransformSelection(uuid) {
|
|
1058
|
+
if (!this.sceneCommandService) return null;
|
|
1059
|
+
if (!uuid) {
|
|
1060
|
+
this.detachTransformControls();
|
|
1061
|
+
return null;
|
|
1062
|
+
}
|
|
1063
|
+
const object = this.sceneCommandService.getObjectByUuid(uuid);
|
|
1064
|
+
return this.attachTransformControls(object);
|
|
1065
|
+
},
|
|
1066
|
+
ensureTransformSelectionValid() {
|
|
1067
|
+
if (!this.sceneCommandService) return null;
|
|
1068
|
+
const selectedUuid = this.sceneCommandService.selectedUuid;
|
|
1069
|
+
if (!selectedUuid) {
|
|
1070
|
+
this.detachTransformControls();
|
|
1071
|
+
return null;
|
|
1072
|
+
}
|
|
1073
|
+
const object = this.sceneCommandService.getObjectByUuid(selectedUuid);
|
|
1074
|
+
if (!object || !isTransformAttachableObject(object)) {
|
|
1075
|
+
this.detachTransformControls();
|
|
1076
|
+
return null;
|
|
1077
|
+
}
|
|
1078
|
+
return this.attachTransformControls(object);
|
|
1079
|
+
},
|
|
1080
|
+
buildTransformPayload(objectData, options = {}) {
|
|
1081
|
+
if (!objectData) return null;
|
|
1082
|
+
return {
|
|
1083
|
+
...objectData,
|
|
1084
|
+
isTransforming: !!options.isTransforming,
|
|
1085
|
+
mode: this.getTransformMode(),
|
|
1086
|
+
};
|
|
1087
|
+
},
|
|
1088
|
+
emitTransformEvent(eventName, objectData, options = {}) {
|
|
1089
|
+
const payload = this.buildTransformPayload(objectData, options);
|
|
1090
|
+
if (!payload || !this.sceneCommandService) return;
|
|
1091
|
+
this.sceneCommandService.emitEvent(eventName, payload);
|
|
1092
|
+
},
|
|
1093
|
+
isTransformValueChanged(oldValue = [], newValue = []) {
|
|
1094
|
+
if (
|
|
1095
|
+
!Array.isArray(oldValue) ||
|
|
1096
|
+
!Array.isArray(newValue) ||
|
|
1097
|
+
oldValue.length !== newValue.length
|
|
1098
|
+
) {
|
|
1099
|
+
return true;
|
|
1100
|
+
}
|
|
1101
|
+
for (let index = 0; index < oldValue.length; index += 1) {
|
|
1102
|
+
const currentDiff = Math.abs(
|
|
1103
|
+
(Number(oldValue[index]) || 0) - (Number(newValue[index]) || 0)
|
|
1104
|
+
);
|
|
1105
|
+
if (currentDiff > 0.000001) {
|
|
1106
|
+
return true;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
return false;
|
|
1110
|
+
},
|
|
1111
|
+
commitTransformChanges(object) {
|
|
1112
|
+
if (!object || !this.sceneCommandService) return null;
|
|
1113
|
+
const startSnapshot = this.transformEditor.transformStartSnapshot;
|
|
1114
|
+
const endSnapshot = this.getCustomObjectSnapshot(object.uuid);
|
|
1115
|
+
if (!startSnapshot || !endSnapshot) {
|
|
1116
|
+
return endSnapshot;
|
|
1117
|
+
}
|
|
1118
|
+
const mode = this.getTransformMode();
|
|
1119
|
+
if (mode === TRANSFORM_MODE.TRANSLATE) {
|
|
1120
|
+
if (this.isTransformValueChanged(startSnapshot.position, endSnapshot.position)) {
|
|
1121
|
+
this.setElementPosition(object.uuid, endSnapshot.position, startSnapshot.position);
|
|
1122
|
+
}
|
|
1123
|
+
} else if (mode === TRANSFORM_MODE.ROTATE) {
|
|
1124
|
+
if (this.isTransformValueChanged(startSnapshot.rotation, endSnapshot.rotation)) {
|
|
1125
|
+
this.setElementRotation(object.uuid, endSnapshot.rotation, startSnapshot.rotation);
|
|
1126
|
+
}
|
|
1127
|
+
} else if (mode === TRANSFORM_MODE.SCALE) {
|
|
1128
|
+
if (this.isTransformValueChanged(startSnapshot.scale, endSnapshot.scale)) {
|
|
1129
|
+
this.setElementScale(object.uuid, endSnapshot.scale, startSnapshot.scale);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return this.getCustomObjectSnapshot(object.uuid);
|
|
1133
|
+
},
|
|
1134
|
+
handleTransformObjectChange() {
|
|
1135
|
+
const editor = this.transformEditor;
|
|
1136
|
+
const controls = editor && editor.transformControls;
|
|
1137
|
+
if (!editor || !controls || !controls.object || !editor.transforming) return;
|
|
1138
|
+
controls.object.updateMatrixWorld(true);
|
|
1139
|
+
this.emitTransformEvent(
|
|
1140
|
+
EDITOR_EVENT.OBJECT_TRANSFORM_CHANGING,
|
|
1141
|
+
this.getCustomObjectSnapshot(controls.object.uuid),
|
|
1142
|
+
{
|
|
1143
|
+
isTransforming: true,
|
|
1144
|
+
}
|
|
1145
|
+
);
|
|
1146
|
+
if (typeof this.notifyCameraChange === 'function') {
|
|
1147
|
+
this.notifyCameraChange('customTransform');
|
|
1148
|
+
}
|
|
1149
|
+
},
|
|
1150
|
+
handleTransformDraggingChanged(event) {
|
|
1151
|
+
const editor = this.transformEditor;
|
|
1152
|
+
if (!editor) return;
|
|
1153
|
+
const isDraggingNow = !!(event && event.value);
|
|
1154
|
+
editor.transforming = isDraggingNow;
|
|
1155
|
+
if (this.cameraControls) {
|
|
1156
|
+
if (isDraggingNow) {
|
|
1157
|
+
editor.cameraControlsEnabled = editor.pointerCameraGuard
|
|
1158
|
+
? editor.pointerCameraEnabled
|
|
1159
|
+
: this.cameraControls.enabled;
|
|
1160
|
+
this.cameraControls.enabled = false;
|
|
1161
|
+
} else {
|
|
1162
|
+
this.restoreTransformCameraControls();
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
const controls = editor.transformControls;
|
|
1166
|
+
const object = controls && controls.object ? controls.object : null;
|
|
1167
|
+
if (isDraggingNow) {
|
|
1168
|
+
editor.transformStartSnapshot = object ? this.getCustomObjectSnapshot(object.uuid) : null;
|
|
1169
|
+
this.emitTransformEvent(
|
|
1170
|
+
EDITOR_EVENT.OBJECT_TRANSFORM_CHANGING,
|
|
1171
|
+
editor.transformStartSnapshot,
|
|
1172
|
+
{
|
|
1173
|
+
isTransforming: true,
|
|
1174
|
+
}
|
|
1175
|
+
);
|
|
1176
|
+
return;
|
|
1177
|
+
}
|
|
1178
|
+
const resultSnapshot = this.commitTransformChanges(object);
|
|
1179
|
+
editor.transformStartSnapshot = null;
|
|
1180
|
+
this.emitTransformEvent(EDITOR_EVENT.OBJECT_TRANSFORM_CHANGED, resultSnapshot, {
|
|
1181
|
+
isTransforming: false,
|
|
1182
|
+
});
|
|
1183
|
+
},
|
|
397
1184
|
getOutlineInstanceProxyKey(instancedMesh, instanceIndex) {
|
|
398
1185
|
return `${instancedMesh.uuid}:${instanceIndex}`;
|
|
399
1186
|
},
|
|
@@ -490,20 +1277,6 @@ export default {
|
|
|
490
1277
|
if (proxy.material) proxy.material.dispose && proxy.material.dispose();
|
|
491
1278
|
return proxy;
|
|
492
1279
|
},
|
|
493
|
-
// 判断是设备是手机还是电脑
|
|
494
|
-
isMobileDevice() {
|
|
495
|
-
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
|
496
|
-
if (/windows phone/i.test(userAgent)) {
|
|
497
|
-
return true;
|
|
498
|
-
}
|
|
499
|
-
if (/android/i.test(userAgent)) {
|
|
500
|
-
return true;
|
|
501
|
-
}
|
|
502
|
-
if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
|
|
503
|
-
return true;
|
|
504
|
-
}
|
|
505
|
-
return false;
|
|
506
|
-
},
|
|
507
1280
|
// 节流工具方法
|
|
508
1281
|
throttle(func, limit) {
|
|
509
1282
|
let lastFunc;
|
|
@@ -2306,6 +3079,7 @@ export default {
|
|
|
2306
3079
|
projectId,
|
|
2307
3080
|
debug: isDebug,
|
|
2308
3081
|
renderModelData: this.renderModelData.bind(this),
|
|
3082
|
+
onRangeStreamComplete: this.handleRangeStreamComplete.bind(this),
|
|
2309
3083
|
ensureNotInteracting: async abortSignal => {
|
|
2310
3084
|
if (
|
|
2311
3085
|
this.userInteracting ||
|
|
@@ -2415,6 +3189,19 @@ export default {
|
|
|
2415
3189
|
this.setSceneBox(null, documentId, false);
|
|
2416
3190
|
this.setBoxIndex(null, documentId, false);
|
|
2417
3191
|
},
|
|
3192
|
+
locateSceneBoxByDocumentId(documentId, options = {}) {
|
|
3193
|
+
if (!documentId || !this.noObserver || !this.noObserver.sceneBoxes) {
|
|
3194
|
+
return false;
|
|
3195
|
+
}
|
|
3196
|
+
const box = this.noObserver.sceneBoxes.get(String(documentId));
|
|
3197
|
+
if (!box || !box.isBox3 || box.isEmpty()) {
|
|
3198
|
+
return false;
|
|
3199
|
+
}
|
|
3200
|
+
const center = box.getCenter(new this.THREE.Vector3());
|
|
3201
|
+
const size = box.getSize(new this.THREE.Vector3());
|
|
3202
|
+
this.locateByCenterBox(center, size, options);
|
|
3203
|
+
return true;
|
|
3204
|
+
},
|
|
2418
3205
|
/**
|
|
2419
3206
|
* 同步获取当前WebGL画面的截图数据,解决preserveDrawingBuffer为false时html2canvas截黑屏的问题
|
|
2420
3207
|
*/
|
|
@@ -2434,7 +3221,15 @@ export default {
|
|
|
2434
3221
|
/**
|
|
2435
3222
|
* 内部渲染流式数据方法
|
|
2436
3223
|
*/
|
|
2437
|
-
renderModelData(
|
|
3224
|
+
renderModelData(
|
|
3225
|
+
meshes,
|
|
3226
|
+
primitives,
|
|
3227
|
+
list,
|
|
3228
|
+
range,
|
|
3229
|
+
onComplete,
|
|
3230
|
+
immediateUpdate,
|
|
3231
|
+
renderOptions = {}
|
|
3232
|
+
) {
|
|
2438
3233
|
// 构造 drawModel 需要的数据格式
|
|
2439
3234
|
const modelRegistry = this.noObserver.streamLoader.modelRegistry;
|
|
2440
3235
|
const modelRecords = Array.from(modelRegistry.values());
|
|
@@ -2481,10 +3276,56 @@ export default {
|
|
|
2481
3276
|
version: list ? list.version : '',
|
|
2482
3277
|
};
|
|
2483
3278
|
|
|
2484
|
-
options.
|
|
3279
|
+
options.suppressLoadComplete = !!renderOptions.suppressLoadComplete;
|
|
2485
3280
|
options.immediateUpdate = immediateUpdate;
|
|
2486
3281
|
|
|
2487
|
-
|
|
3282
|
+
return new Promise(resolve => {
|
|
3283
|
+
let finished = false;
|
|
3284
|
+
const finish = result => {
|
|
3285
|
+
if (finished) return;
|
|
3286
|
+
finished = true;
|
|
3287
|
+
resolve(result || {});
|
|
3288
|
+
};
|
|
3289
|
+
|
|
3290
|
+
options.onComplete = complete => {
|
|
3291
|
+
if (
|
|
3292
|
+
this.sceneCommandService &&
|
|
3293
|
+
typeof this.sceneCommandService.retryPendingOriginalModelSaveChanges === 'function'
|
|
3294
|
+
) {
|
|
3295
|
+
this.sceneCommandService.retryPendingOriginalModelSaveChanges();
|
|
3296
|
+
}
|
|
3297
|
+
onComplete?.(complete);
|
|
3298
|
+
finish(complete);
|
|
3299
|
+
};
|
|
3300
|
+
options.onCancel = cancelInfo => {
|
|
3301
|
+
finish({
|
|
3302
|
+
canceled: true,
|
|
3303
|
+
...(cancelInfo || {}),
|
|
3304
|
+
});
|
|
3305
|
+
};
|
|
3306
|
+
|
|
3307
|
+
this.drawModel(regionModelData, '', meshNameConfig, options);
|
|
3308
|
+
});
|
|
3309
|
+
},
|
|
3310
|
+
|
|
3311
|
+
waitNextRenderFrame() {
|
|
3312
|
+
return new Promise(resolve => {
|
|
3313
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
3314
|
+
requestAnimationFrame(() => {
|
|
3315
|
+
resolve();
|
|
3316
|
+
});
|
|
3317
|
+
return;
|
|
3318
|
+
}
|
|
3319
|
+
setTimeout(resolve, 0);
|
|
3320
|
+
});
|
|
3321
|
+
},
|
|
3322
|
+
|
|
3323
|
+
async handleRangeStreamComplete(payload = {}) {
|
|
3324
|
+
await this.waitNextRenderFrame();
|
|
3325
|
+
this.$emit('loadComplete', {
|
|
3326
|
+
source: 'inRangeDis2',
|
|
3327
|
+
...payload,
|
|
3328
|
+
});
|
|
2488
3329
|
},
|
|
2489
3330
|
|
|
2490
3331
|
getRangeStream(options) {
|
|
@@ -2570,6 +3411,9 @@ export default {
|
|
|
2570
3411
|
this.renderer.debug.checkShaderErrors = false;
|
|
2571
3412
|
this.renderer.info.autoReset = false;
|
|
2572
3413
|
this.renderer.setPixelRatio(window.devicePixelRatio);
|
|
3414
|
+
if (this.instructions && window.getComputedStyle(this.instructions).position === 'static') {
|
|
3415
|
+
this.instructions.style.position = 'relative';
|
|
3416
|
+
}
|
|
2573
3417
|
const rect = this.instructions.getBoundingClientRect();
|
|
2574
3418
|
this.renderer.setSize(rect.width, rect.height);
|
|
2575
3419
|
this.renderer.domElement.id = 'three-model-' + this.containId;
|
|
@@ -2825,7 +3669,7 @@ export default {
|
|
|
2825
3669
|
const rect = this.instructions.getBoundingClientRect();
|
|
2826
3670
|
this.labelRenderer.setSize(rect.width, rect.height);
|
|
2827
3671
|
this.labelRenderer.domElement.style.position = 'absolute';
|
|
2828
|
-
|
|
3672
|
+
this.labelRenderer.domElement.style.left = '0';
|
|
2829
3673
|
this.labelRenderer.domElement.style.top = '0';
|
|
2830
3674
|
this.labelRenderer.domElement.style.pointerEvents = 'none';
|
|
2831
3675
|
this.instructions.appendChild(this.labelRenderer.domElement);
|
|
@@ -2853,7 +3697,9 @@ export default {
|
|
|
2853
3697
|
options?.onComplete?.(complete);
|
|
2854
3698
|
console.log('加载完成');
|
|
2855
3699
|
// 触发原有的完成事件
|
|
2856
|
-
|
|
3700
|
+
if (!options?.suppressLoadComplete) {
|
|
3701
|
+
this.$emit('loadComplete');
|
|
3702
|
+
}
|
|
2857
3703
|
}
|
|
2858
3704
|
);
|
|
2859
3705
|
},
|
|
@@ -2885,6 +3731,14 @@ export default {
|
|
|
2885
3731
|
this.skipNextRenderFrame = true;
|
|
2886
3732
|
|
|
2887
3733
|
const intersects = this.getRaycasterObjects(event);
|
|
3734
|
+
const shouldBlockCamera = intersects.some(item =>
|
|
3735
|
+
this.isActiveTransformControlIntersection(item)
|
|
3736
|
+
);
|
|
3737
|
+
if (shouldBlockCamera) {
|
|
3738
|
+
this.setPointerCameraGuard(true);
|
|
3739
|
+
} else {
|
|
3740
|
+
this.setPointerCameraGuard(false);
|
|
3741
|
+
}
|
|
2888
3742
|
this.firstTime = new Date().getTime();
|
|
2889
3743
|
let params = {
|
|
2890
3744
|
event,
|
|
@@ -2915,6 +3769,87 @@ export default {
|
|
|
2915
3769
|
? this.raycaster.intersectObjects(this.scene.children, true)
|
|
2916
3770
|
: [];
|
|
2917
3771
|
},
|
|
3772
|
+
isTransformControlIntersection(intersection) {
|
|
3773
|
+
let current = intersection && intersection.object ? intersection.object : null;
|
|
3774
|
+
while (current) {
|
|
3775
|
+
if (current.userData && current.userData.transformControlHelper === true) {
|
|
3776
|
+
return true;
|
|
3777
|
+
}
|
|
3778
|
+
current = current.parent;
|
|
3779
|
+
}
|
|
3780
|
+
return false;
|
|
3781
|
+
},
|
|
3782
|
+
isActiveTransformControlIntersection(intersection) {
|
|
3783
|
+
const editor = this.transformEditor;
|
|
3784
|
+
const controls = editor && editor.transformControls;
|
|
3785
|
+
const helper = editor && editor.transformHelper;
|
|
3786
|
+
if (!controls || !controls.object || !helper || !helper.visible) {
|
|
3787
|
+
return false;
|
|
3788
|
+
}
|
|
3789
|
+
return this.isTransformControlIntersection(intersection);
|
|
3790
|
+
},
|
|
3791
|
+
getPrimaryIntersection(intersects = []) {
|
|
3792
|
+
if (!Array.isArray(intersects) || intersects.length === 0) {
|
|
3793
|
+
return null;
|
|
3794
|
+
}
|
|
3795
|
+
const validIntersects = intersects.filter(
|
|
3796
|
+
item => item && item.object && !this.isTransformControlIntersection(item)
|
|
3797
|
+
);
|
|
3798
|
+
if (validIntersects.length === 0) {
|
|
3799
|
+
return null;
|
|
3800
|
+
}
|
|
3801
|
+
const selectableIntersect = validIntersects.find(item =>
|
|
3802
|
+
this.getSelectableSceneObject(item.object)
|
|
3803
|
+
);
|
|
3804
|
+
return selectableIntersect || validIntersects[0] || null;
|
|
3805
|
+
},
|
|
3806
|
+
buildIntersectionParams(intersection, event, cameraData) {
|
|
3807
|
+
if (!intersection) {
|
|
3808
|
+
return {
|
|
3809
|
+
objects: [],
|
|
3810
|
+
mousePosition: { x: event.clientX, y: event.clientY },
|
|
3811
|
+
camera: cameraData,
|
|
3812
|
+
v3Position: {
|
|
3813
|
+
x: -1,
|
|
3814
|
+
y: -1,
|
|
3815
|
+
z: -1,
|
|
3816
|
+
},
|
|
3817
|
+
};
|
|
3818
|
+
}
|
|
3819
|
+
const selectableObject = this.getSelectableSceneObject(intersection.object);
|
|
3820
|
+
const params = {
|
|
3821
|
+
objects: [intersection.object],
|
|
3822
|
+
mousePosition: { x: event.clientX, y: event.clientY },
|
|
3823
|
+
camera: cameraData,
|
|
3824
|
+
v3Position: {
|
|
3825
|
+
x: intersection.point.x,
|
|
3826
|
+
y: intersection.point.y,
|
|
3827
|
+
z: intersection.point.z,
|
|
3828
|
+
},
|
|
3829
|
+
instanceId: this.getInstanceId(intersection.object, intersection.instanceId),
|
|
3830
|
+
};
|
|
3831
|
+
if (selectableObject) {
|
|
3832
|
+
const nodeType = this.sceneCommandService
|
|
3833
|
+
? this.sceneCommandService.getNodeType(selectableObject.uuid)
|
|
3834
|
+
: '';
|
|
3835
|
+
params.selectedObject = selectableObject;
|
|
3836
|
+
params.selectedObjectUuid = selectableObject.uuid;
|
|
3837
|
+
params.selectedNodeType = nodeType;
|
|
3838
|
+
if (
|
|
3839
|
+
nodeType === 'custom-element' ||
|
|
3840
|
+
nodeType === 'custom-group' ||
|
|
3841
|
+
nodeType === 'custom-root'
|
|
3842
|
+
) {
|
|
3843
|
+
params.customObject = selectableObject;
|
|
3844
|
+
params.customObjectUuid = selectableObject.uuid;
|
|
3845
|
+
}
|
|
3846
|
+
if (nodeType === 'original-model') {
|
|
3847
|
+
params.originalModel = selectableObject;
|
|
3848
|
+
params.originalModelUuid = selectableObject.uuid;
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
return params;
|
|
3852
|
+
},
|
|
2918
3853
|
getInstanceId(instancedMesh, instanceIndex, options) {
|
|
2919
3854
|
if (!instancedMesh || instanceIndex === undefined || instanceIndex === null) {
|
|
2920
3855
|
return null;
|
|
@@ -2936,10 +3871,14 @@ export default {
|
|
|
2936
3871
|
}, 50); // 短暂延迟确保交互完成
|
|
2937
3872
|
|
|
2938
3873
|
// 在测量模式下,不进行事件暴露
|
|
3874
|
+
if (!this.transformEditor.transforming) {
|
|
3875
|
+
this.setPointerCameraGuard(false);
|
|
3876
|
+
}
|
|
2939
3877
|
if (!this.measureFlag) {
|
|
2940
3878
|
this.lastTime = new Date().getTime();
|
|
2941
3879
|
if (this.lastTime - this.firstTime < 300) {
|
|
2942
3880
|
const intersects = this.getRaycasterObjects(event);
|
|
3881
|
+
const primaryIntersection = this.getPrimaryIntersection(intersects);
|
|
2943
3882
|
let params = {};
|
|
2944
3883
|
let cameraData = {
|
|
2945
3884
|
position: {
|
|
@@ -2953,43 +3892,101 @@ export default {
|
|
|
2953
3892
|
roll: this.cameraControls._target.z,
|
|
2954
3893
|
},
|
|
2955
3894
|
};
|
|
2956
|
-
if (
|
|
3895
|
+
if (primaryIntersection) {
|
|
2957
3896
|
this.clearBypassCullingModelIds();
|
|
2958
|
-
|
|
2959
|
-
params = {
|
|
2960
|
-
objects: [intersects[0].object],
|
|
2961
|
-
mousePosition: { x: event.clientX, y: event.clientY },
|
|
2962
|
-
camera: cameraData,
|
|
2963
|
-
v3Position: {
|
|
2964
|
-
x: intersects[0].point.x,
|
|
2965
|
-
y: intersects[0].point.y,
|
|
2966
|
-
z: intersects[0].point.z,
|
|
2967
|
-
},
|
|
2968
|
-
// inHighPriorityRegion: inHighPriority,
|
|
2969
|
-
instanceId,
|
|
2970
|
-
};
|
|
3897
|
+
params = this.buildIntersectionParams(primaryIntersection, event, cameraData);
|
|
2971
3898
|
} else {
|
|
2972
|
-
params =
|
|
2973
|
-
objects: [],
|
|
2974
|
-
mousePosition: { x: event.clientX, y: event.clientY },
|
|
2975
|
-
camera: cameraData,
|
|
2976
|
-
v3Position: {
|
|
2977
|
-
x: -1,
|
|
2978
|
-
y: -1,
|
|
2979
|
-
z: -1,
|
|
2980
|
-
},
|
|
2981
|
-
// inHighPriorityRegion: false,
|
|
2982
|
-
};
|
|
3899
|
+
params = this.buildIntersectionParams(null, event, cameraData);
|
|
2983
3900
|
}
|
|
2984
3901
|
if (event.button === 0) {
|
|
3902
|
+
if (this.transformEditor && this.transformEditor.suppressSelectionOnce) {
|
|
3903
|
+
this.transformEditor.suppressSelectionOnce = false;
|
|
3904
|
+
this.setPointerCameraGuard(false);
|
|
3905
|
+
return;
|
|
3906
|
+
}
|
|
3907
|
+
if (params.selectedObjectUuid) {
|
|
3908
|
+
this.selectSceneObject(params.selectedObjectUuid);
|
|
3909
|
+
} else if (this.sceneCommandService) {
|
|
3910
|
+
this.clearCustomSelection();
|
|
3911
|
+
}
|
|
3912
|
+
if (!this.transformEditor.transforming) {
|
|
3913
|
+
this.setPointerCameraGuard(false);
|
|
3914
|
+
}
|
|
2985
3915
|
this.$emit('leftClick', params);
|
|
2986
3916
|
} else if (event.button === 1) {
|
|
3917
|
+
this.setPointerCameraGuard(false);
|
|
2987
3918
|
if (this.lastTime - this.lastMiddleClickTime < 2000) {
|
|
2988
3919
|
this.$emit('middleDblClick', params);
|
|
2989
3920
|
this.lastMiddleClickTime = 0;
|
|
2990
3921
|
} else {
|
|
2991
3922
|
this.lastMiddleClickTime = this.lastTime;
|
|
2992
3923
|
}
|
|
3924
|
+
} else if (event.button === 2) {
|
|
3925
|
+
if ((params.objects && params.objects.length > 0) || this.isolateMode) {
|
|
3926
|
+
this.setPointerCameraGuard(false);
|
|
3927
|
+
this.$emit('rightClick', params);
|
|
3928
|
+
onContextHandle(
|
|
3929
|
+
event,
|
|
3930
|
+
'fl-model',
|
|
3931
|
+
'隐藏',
|
|
3932
|
+
this.isolateMode ? '取消隔离' : '隔离',
|
|
3933
|
+
() => {
|
|
3934
|
+
this.updateProperty([
|
|
3935
|
+
{
|
|
3936
|
+
name: params.instanceId,
|
|
3937
|
+
attr: {
|
|
3938
|
+
visible: false,
|
|
3939
|
+
},
|
|
3940
|
+
},
|
|
3941
|
+
]);
|
|
3942
|
+
},
|
|
3943
|
+
() => {
|
|
3944
|
+
this.setAllModelVisible(this.isolateMode);
|
|
3945
|
+
this.updateProperty([
|
|
3946
|
+
{
|
|
3947
|
+
name: params.instanceId,
|
|
3948
|
+
attr: {
|
|
3949
|
+
visible: true,
|
|
3950
|
+
},
|
|
3951
|
+
},
|
|
3952
|
+
]);
|
|
3953
|
+
this.isolateMode = !this.isolateMode;
|
|
3954
|
+
}
|
|
3955
|
+
);
|
|
3956
|
+
}
|
|
3957
|
+
} else if (event.button === 2) {
|
|
3958
|
+
if ((params.objects && params.objects.length > 0) || this.isolateMode) {
|
|
3959
|
+
this.setPointerCameraGuard(false);
|
|
3960
|
+
this.$emit('rightClick', params);
|
|
3961
|
+
onContextHandle(
|
|
3962
|
+
event,
|
|
3963
|
+
'fl-model',
|
|
3964
|
+
'隐藏',
|
|
3965
|
+
this.isolateMode ? '取消隔离' : '隔离',
|
|
3966
|
+
() => {
|
|
3967
|
+
this.updateProperty([
|
|
3968
|
+
{
|
|
3969
|
+
name: params.instanceId,
|
|
3970
|
+
attr: {
|
|
3971
|
+
visible: false,
|
|
3972
|
+
},
|
|
3973
|
+
},
|
|
3974
|
+
]);
|
|
3975
|
+
},
|
|
3976
|
+
() => {
|
|
3977
|
+
this.setAllModelVisible(this.isolateMode);
|
|
3978
|
+
this.updateProperty([
|
|
3979
|
+
{
|
|
3980
|
+
name: params.instanceId,
|
|
3981
|
+
attr: {
|
|
3982
|
+
visible: true,
|
|
3983
|
+
},
|
|
3984
|
+
},
|
|
3985
|
+
]);
|
|
3986
|
+
this.isolateMode = !this.isolateMode;
|
|
3987
|
+
}
|
|
3988
|
+
);
|
|
3989
|
+
}
|
|
2993
3990
|
}
|
|
2994
3991
|
}
|
|
2995
3992
|
}
|
|
@@ -3129,7 +4126,9 @@ export default {
|
|
|
3129
4126
|
case 'color':
|
|
3130
4127
|
targetObj.forEach(children => {
|
|
3131
4128
|
if (children.isMesh) {
|
|
3132
|
-
const
|
|
4129
|
+
const instanceInfo = children.userData?.instancesMap?.get(instanceId);
|
|
4130
|
+
if (!instanceInfo) return;
|
|
4131
|
+
const { instanceIndex } = instanceInfo;
|
|
3133
4132
|
children.setColorAt(instanceIndex, new this.THREE.Color(ele.attr[key]));
|
|
3134
4133
|
children.instanceColor.needsUpdate = true;
|
|
3135
4134
|
if (!this.isCurrentVisible(instanceId, children)) {
|
|
@@ -3167,6 +4166,7 @@ export default {
|
|
|
3167
4166
|
}
|
|
3168
4167
|
targetObj.forEach(children => {
|
|
3169
4168
|
const instanceInfo = children.userData.instancesMap.get(instanceId);
|
|
4169
|
+
if (!instanceInfo) return;
|
|
3170
4170
|
const { instanceIndex, copyMatrix } = instanceInfo;
|
|
3171
4171
|
const nextVisible = requestedVisible && this.isSourceVisible(instanceId, children);
|
|
3172
4172
|
instanceInfo.visible = nextVisible;
|
|
@@ -3193,7 +4193,9 @@ export default {
|
|
|
3193
4193
|
targetObj.forEach(children => {
|
|
3194
4194
|
if (children.isMesh) {
|
|
3195
4195
|
const opacity = children.geometry.attributes.opacity.array;
|
|
3196
|
-
const
|
|
4196
|
+
const instanceInfo = children.userData?.instancesMap?.get(instanceId);
|
|
4197
|
+
if (!instanceInfo) return;
|
|
4198
|
+
const { instanceIndex } = instanceInfo;
|
|
3197
4199
|
opacity[instanceIndex] = ele.attr[key];
|
|
3198
4200
|
children.geometry.attributes.opacity.needsUpdate = true;
|
|
3199
4201
|
}
|
|
@@ -3263,7 +4265,9 @@ export default {
|
|
|
3263
4265
|
let targetObj = this.getObjectByName(instanceId);
|
|
3264
4266
|
targetObj.forEach(children => {
|
|
3265
4267
|
if (children.isMesh) {
|
|
3266
|
-
const
|
|
4268
|
+
const instanceInfo = children.userData?.instancesMap?.get(instanceId);
|
|
4269
|
+
if (!instanceInfo) return;
|
|
4270
|
+
const { instanceIndex } = instanceInfo;
|
|
3267
4271
|
if (!this.isSourceVisible(instanceId, children)) {
|
|
3268
4272
|
this.removeOutlineObject(children, instanceIndex);
|
|
3269
4273
|
return;
|
|
@@ -3287,7 +4291,9 @@ export default {
|
|
|
3287
4291
|
let targetObj = this.getObjectByName(instanceId);
|
|
3288
4292
|
targetObj.forEach(children => {
|
|
3289
4293
|
if (children.isMesh) {
|
|
3290
|
-
const
|
|
4294
|
+
const instanceInfo = children.userData?.instancesMap?.get(instanceId);
|
|
4295
|
+
if (!instanceInfo) return;
|
|
4296
|
+
const { instanceIndex } = instanceInfo;
|
|
3291
4297
|
this.removeOutlineObject(children, instanceIndex);
|
|
3292
4298
|
}
|
|
3293
4299
|
});
|
|
@@ -3340,7 +4346,9 @@ export default {
|
|
|
3340
4346
|
case 'nColor':
|
|
3341
4347
|
targetObj.forEach(children => {
|
|
3342
4348
|
if (children.isMesh) {
|
|
3343
|
-
const
|
|
4349
|
+
const instanceInfo = children.userData?.instancesMap?.get(instanceId);
|
|
4350
|
+
if (!instanceInfo) return;
|
|
4351
|
+
const { instanceIndex } = instanceInfo;
|
|
3344
4352
|
children.setColorAt(instanceIndex, children.material.userData['oColor']);
|
|
3345
4353
|
children.instanceColor.needsUpdate = true;
|
|
3346
4354
|
children.material.userData[key] = children.material.userData['oColor'];
|
|
@@ -3363,7 +4371,9 @@ export default {
|
|
|
3363
4371
|
case 'color':
|
|
3364
4372
|
obj.forEach(children => {
|
|
3365
4373
|
if (children.isMesh) {
|
|
3366
|
-
const
|
|
4374
|
+
const instanceInfo = children.userData?.instancesMap?.get(instanceId);
|
|
4375
|
+
if (!instanceInfo) return;
|
|
4376
|
+
const { instanceIndex } = instanceInfo;
|
|
3367
4377
|
children.setColorAt(instanceIndex, children.material.userData.nColor);
|
|
3368
4378
|
children.instanceColor.needsUpdate = true;
|
|
3369
4379
|
if (this.outlinePass) {
|
|
@@ -3380,6 +4390,7 @@ export default {
|
|
|
3380
4390
|
case 'visible': {
|
|
3381
4391
|
obj.forEach(children => {
|
|
3382
4392
|
const instanceInfo = children.userData.instancesMap.get(instanceId);
|
|
4393
|
+
if (!instanceInfo) return;
|
|
3383
4394
|
const { instanceIndex, copyMatrix } = instanceInfo;
|
|
3384
4395
|
if (this.isSourceVisible(instanceId, children)) {
|
|
3385
4396
|
instanceInfo.visible = true;
|
|
@@ -3400,7 +4411,9 @@ export default {
|
|
|
3400
4411
|
case 'opacity':
|
|
3401
4412
|
obj.forEach(children => {
|
|
3402
4413
|
if (children.isMesh) {
|
|
3403
|
-
const
|
|
4414
|
+
const instanceInfo = children.userData?.instancesMap?.get(instanceId);
|
|
4415
|
+
if (!instanceInfo) return;
|
|
4416
|
+
const { instanceIndex } = instanceInfo;
|
|
3404
4417
|
const opacity = children.geometry.attributes.opacity.array;
|
|
3405
4418
|
opacity[instanceIndex] = children.material.userData.nOpacity;
|
|
3406
4419
|
children.geometry.attributes.opacity.needsUpdate = true;
|
|
@@ -3411,24 +4424,56 @@ export default {
|
|
|
3411
4424
|
}
|
|
3412
4425
|
}
|
|
3413
4426
|
},
|
|
4427
|
+
expandLocateBoxByObject(box3, object) {
|
|
4428
|
+
if (!box3 || !object) return;
|
|
4429
|
+
if (object.isGroup) {
|
|
4430
|
+
object.traverseVisible(child => {
|
|
4431
|
+
if (child.isMesh || child.isLine || child.isPoints) {
|
|
4432
|
+
box3.expandByObject(child);
|
|
4433
|
+
}
|
|
4434
|
+
});
|
|
4435
|
+
return;
|
|
4436
|
+
}
|
|
4437
|
+
box3.expandByObject(object);
|
|
4438
|
+
},
|
|
4439
|
+
locateObjectByBox(object, options = {}) {
|
|
4440
|
+
if (!object) return false;
|
|
4441
|
+
const box3 = new this.THREE.Box3();
|
|
4442
|
+
this.expandLocateBoxByObject(box3, object);
|
|
4443
|
+
if (box3.isEmpty()) return false;
|
|
4444
|
+
const center = box3.getCenter(new this.THREE.Vector3());
|
|
4445
|
+
const size = box3.getSize(new this.THREE.Vector3());
|
|
4446
|
+
this.locateByCenterBox(center, size, options);
|
|
4447
|
+
return true;
|
|
4448
|
+
},
|
|
3414
4449
|
// 定位到模型
|
|
3415
|
-
// name
|
|
4450
|
+
// name 模型名称或运行态 uuid,可以是数组
|
|
3416
4451
|
locateModel(name) {
|
|
3417
|
-
if (!this.scene) return;
|
|
4452
|
+
if (!this.scene) return false;
|
|
3418
4453
|
if (Array.isArray(name)) {
|
|
3419
4454
|
const box3 = new this.THREE.Box3();
|
|
3420
4455
|
name.forEach(n => {
|
|
4456
|
+
const objectByUuid = this.getObjectByUuid(n);
|
|
4457
|
+
if (objectByUuid) {
|
|
4458
|
+
this.expandLocateBoxByObject(box3, objectByUuid);
|
|
4459
|
+
return;
|
|
4460
|
+
}
|
|
3421
4461
|
const arr = this.getObjectByName(n);
|
|
3422
4462
|
arr.forEach(o => {
|
|
3423
|
-
|
|
4463
|
+
this.expandLocateBoxByObject(box3, o);
|
|
3424
4464
|
});
|
|
3425
4465
|
});
|
|
3426
4466
|
if (!box3.isEmpty()) {
|
|
3427
4467
|
const center = box3.getCenter(new this.THREE.Vector3());
|
|
3428
4468
|
const size = box3.getSize(new this.THREE.Vector3());
|
|
3429
4469
|
this.locateByCenterBox(center, size, { viewAll: true });
|
|
4470
|
+
return true;
|
|
3430
4471
|
}
|
|
3431
|
-
return;
|
|
4472
|
+
return false;
|
|
4473
|
+
}
|
|
4474
|
+
const objectByUuid = this.getObjectByUuid(name);
|
|
4475
|
+
if (objectByUuid && this.locateObjectByBox(objectByUuid)) {
|
|
4476
|
+
return true;
|
|
3432
4477
|
}
|
|
3433
4478
|
let obj = this.getObjectByName(name)[0];
|
|
3434
4479
|
if (obj) {
|
|
@@ -3440,7 +4485,9 @@ export default {
|
|
|
3440
4485
|
let size = this.getSize(obj);
|
|
3441
4486
|
this.locateByCenterBox(center, size);
|
|
3442
4487
|
}
|
|
4488
|
+
return true;
|
|
3443
4489
|
}
|
|
4490
|
+
return false;
|
|
3444
4491
|
},
|
|
3445
4492
|
// 根据自定义参数修改模型
|
|
3446
4493
|
/*
|
|
@@ -3559,16 +4606,41 @@ export default {
|
|
|
3559
4606
|
*/
|
|
3560
4607
|
getObjectByName(name, passType = 'group') {
|
|
3561
4608
|
if (!this.scene) return [];
|
|
4609
|
+
if (Array.isArray(name)) {
|
|
4610
|
+
const result = [];
|
|
4611
|
+
const exist = new Set();
|
|
4612
|
+
name.forEach(item => {
|
|
4613
|
+
this.getObjectByName(item, passType).forEach(obj => {
|
|
4614
|
+
if (!obj || exist.has(obj.uuid)) return;
|
|
4615
|
+
exist.add(obj.uuid);
|
|
4616
|
+
result.push(obj);
|
|
4617
|
+
});
|
|
4618
|
+
});
|
|
4619
|
+
return result;
|
|
4620
|
+
}
|
|
3562
4621
|
let object = [];
|
|
4622
|
+
const added = new Set();
|
|
3563
4623
|
const instancedMeshProps = instanceToInstancedMeshMap.get(name);
|
|
3564
4624
|
this.scene.traverse(item => {
|
|
3565
4625
|
const tempName = instancedMeshProps ? instancedMeshProps.drawObjectId : name;
|
|
3566
|
-
|
|
4626
|
+
const itemType = item.type ? item.type.toLowerCase() : '';
|
|
4627
|
+
const isPassType = itemType == passType.toLowerCase();
|
|
4628
|
+
const hasTargetInstance =
|
|
4629
|
+
item.userData &&
|
|
4630
|
+
item.userData.instancesMap instanceof Map &&
|
|
4631
|
+
item.userData.instancesMap.has(name);
|
|
4632
|
+
if (!isPassType && (item.name == tempName || hasTargetInstance) && !added.has(item.uuid)) {
|
|
4633
|
+
added.add(item.uuid);
|
|
3567
4634
|
object.push(item);
|
|
3568
4635
|
}
|
|
3569
4636
|
});
|
|
3570
4637
|
return object;
|
|
3571
4638
|
},
|
|
4639
|
+
// 通过 uuid 获取实体对象
|
|
4640
|
+
getObjectByUuid(uuid) {
|
|
4641
|
+
if (!this.scene || !uuid) return null;
|
|
4642
|
+
return this.scene.getObjectByProperty('uuid', uuid) || null;
|
|
4643
|
+
},
|
|
3572
4644
|
// 通过id获取实体对象, 返回查找到的对象
|
|
3573
4645
|
getObjectById(id) {
|
|
3574
4646
|
if (!this.scene) return null;
|
|
@@ -3654,6 +4726,7 @@ export default {
|
|
|
3654
4726
|
removeAll() {
|
|
3655
4727
|
return new Promise(resolve => {
|
|
3656
4728
|
if (this.scene) {
|
|
4729
|
+
this.removeAllCustomElements();
|
|
3657
4730
|
this.removeTraverse();
|
|
3658
4731
|
this.removeModelByDocumentId();
|
|
3659
4732
|
resolve();
|
|
@@ -3693,6 +4766,16 @@ export default {
|
|
|
3693
4766
|
// 销毁场景 释放内存
|
|
3694
4767
|
destroyScene() {
|
|
3695
4768
|
cancelAnimationFrame(this.animateId);
|
|
4769
|
+
this.disposeTransformControls();
|
|
4770
|
+
|
|
4771
|
+
if (this.sceneCommandEventDisposers.length > 0) {
|
|
4772
|
+
this.sceneCommandEventDisposers.forEach(dispose => dispose && dispose());
|
|
4773
|
+
this.sceneCommandEventDisposers = [];
|
|
4774
|
+
}
|
|
4775
|
+
if (this.sceneCommandService) {
|
|
4776
|
+
this.sceneCommandService.destroy();
|
|
4777
|
+
this.sceneCommandService = null;
|
|
4778
|
+
}
|
|
3696
4779
|
|
|
3697
4780
|
if (this.noObserver && this.noObserver.outlineInstanceProxyMap) {
|
|
3698
4781
|
this.noObserver.outlineInstanceProxyMap.forEach(proxy => {
|
|
@@ -3755,12 +4838,7 @@ export default {
|
|
|
3755
4838
|
}
|
|
3756
4839
|
|
|
3757
4840
|
// 移除鼠标点击/按下事件监听器
|
|
3758
|
-
|
|
3759
|
-
this.renderer.domElement.removeEventListener('mouseup', this.mouseClick, false);
|
|
3760
|
-
this.renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
|
|
3761
|
-
this.renderer.domElement.removeEventListener('pointerup', this.mouseClick, false);
|
|
3762
|
-
this.renderer.domElement.removeEventListener('pointerdown', this.mouseDown, false);
|
|
3763
|
-
}
|
|
4841
|
+
this.unbindScenePointerEvents();
|
|
3764
4842
|
|
|
3765
4843
|
// 取消 pointer lock 并移除相关键盘事件
|
|
3766
4844
|
if (this.pointControls) {
|
|
@@ -4002,13 +5080,46 @@ export default {
|
|
|
4002
5080
|
});
|
|
4003
5081
|
return clippingPlanesConstant;
|
|
4004
5082
|
},
|
|
5083
|
+
isGlobalClippingExcludedNode(object) {
|
|
5084
|
+
if (!object) return true;
|
|
5085
|
+
const userData = object.userData || {};
|
|
5086
|
+
const nodeType = userData.nodeType || userData.rootType || '';
|
|
5087
|
+
if (nodeType === 'custom-root') return true;
|
|
5088
|
+
if (userData.transformControlHelper === true) return true;
|
|
5089
|
+
if (object.isCamera || object.isLight) return true;
|
|
5090
|
+
if (typeof object.type === 'string' && /Helper$/i.test(object.type)) return true;
|
|
5091
|
+
return object.type === 'CSS2DObject' || object.type === 'TransformControlsRoot';
|
|
5092
|
+
},
|
|
5093
|
+
getGlobalClippingRoots() {
|
|
5094
|
+
if (this.modelGroup && this.modelGroup.children && this.modelGroup.children.length) {
|
|
5095
|
+
return [this.modelGroup];
|
|
5096
|
+
}
|
|
5097
|
+
if (!this.scene || !this.scene.children || this.scene.children.length === 0) return [];
|
|
5098
|
+
return this.scene.children.filter(child => !this.isGlobalClippingExcludedNode(child));
|
|
5099
|
+
},
|
|
5100
|
+
getGlobalClippingBox() {
|
|
5101
|
+
if (!this.scene) return null;
|
|
5102
|
+
const roots = this.getGlobalClippingRoots();
|
|
5103
|
+
if (roots.length === 0) return null;
|
|
5104
|
+
const box3 = new this.THREE.Box3();
|
|
5105
|
+
roots.forEach(root => {
|
|
5106
|
+
box3.expandByObject(root);
|
|
5107
|
+
});
|
|
5108
|
+
return box3.isEmpty() ? null : box3;
|
|
5109
|
+
},
|
|
4005
5110
|
// 设置全局整体剖切
|
|
4006
5111
|
/*
|
|
4007
5112
|
先开启模型全局剖切模式, 会返回剖切值的最大最小值
|
|
4008
5113
|
剖切值变换时, 使用
|
|
4009
5114
|
*/
|
|
4010
5115
|
setGlobalClipping(flag = true) {
|
|
4011
|
-
const box3 =
|
|
5116
|
+
const box3 = this.getGlobalClippingBox();
|
|
5117
|
+
if (!box3) {
|
|
5118
|
+
return {
|
|
5119
|
+
min: null,
|
|
5120
|
+
max: null,
|
|
5121
|
+
};
|
|
5122
|
+
}
|
|
4012
5123
|
let max = box3.max;
|
|
4013
5124
|
let min = box3.min;
|
|
4014
5125
|
const clippingPlanes = [
|
|
@@ -4240,10 +5351,38 @@ export default {
|
|
|
4240
5351
|
objClipp2 && (objClipp2[4].constant = -d);
|
|
4241
5352
|
});
|
|
4242
5353
|
},
|
|
5354
|
+
getFirstPersonMoveSpeed(customMoveSpeed) {
|
|
5355
|
+
const defaultMoveSpeed = 800;
|
|
5356
|
+
const minMoveSpeed = 300;
|
|
5357
|
+
const maxMoveSpeed = 2500;
|
|
5358
|
+
const optionMoveSpeed =
|
|
5359
|
+
Number.isFinite(customMoveSpeed) && customMoveSpeed > 0
|
|
5360
|
+
? customMoveSpeed
|
|
5361
|
+
: defaultMoveSpeed;
|
|
5362
|
+
let nextMoveSpeed = defaultMoveSpeed;
|
|
5363
|
+
|
|
5364
|
+
if (
|
|
5365
|
+
this.sceneBoundingBox &&
|
|
5366
|
+
this.sceneBoundingBox.isBox3 &&
|
|
5367
|
+
!this.sceneBoundingBox.isEmpty()
|
|
5368
|
+
) {
|
|
5369
|
+
const size = this.sceneBoundingBox.getSize(new this.THREE.Vector3());
|
|
5370
|
+
const horizontalSpan = Math.max(size.x, size.z);
|
|
5371
|
+
if (Number.isFinite(horizontalSpan) && horizontalSpan > 0) {
|
|
5372
|
+
// 第一视角主要在水平面移动,优先使用场景水平范围估算移动速度
|
|
5373
|
+
nextMoveSpeed = horizontalSpan * 0.8;
|
|
5374
|
+
}
|
|
5375
|
+
}
|
|
5376
|
+
|
|
5377
|
+
return Math.min(
|
|
5378
|
+
Math.max(nextMoveSpeed, minMoveSpeed),
|
|
5379
|
+
Math.min(maxMoveSpeed, optionMoveSpeed)
|
|
5380
|
+
);
|
|
5381
|
+
},
|
|
4243
5382
|
// 开启第一视角
|
|
4244
5383
|
startFirstPer(options) {
|
|
4245
5384
|
let { moveSpeed = 200, jumpSpeed = 200 } = options || {};
|
|
4246
|
-
this.removeSpeed = moveSpeed;
|
|
5385
|
+
this.removeSpeed = this.getFirstPersonMoveSpeed(moveSpeed);
|
|
4247
5386
|
this.upSpeed = jumpSpeed;
|
|
4248
5387
|
|
|
4249
5388
|
this.clock = new this.THREE.Clock();
|
|
@@ -4280,11 +5419,11 @@ export default {
|
|
|
4280
5419
|
} catch (e) {}
|
|
4281
5420
|
// 锁定
|
|
4282
5421
|
this.pointControls.addEventListener('lock', () => {
|
|
5422
|
+
this.detachTransformControls();
|
|
4283
5423
|
this.cameraControls.enabled = false;
|
|
4284
5424
|
window.addEventListener('keydown', this.onKeyDown, false);
|
|
4285
5425
|
window.addEventListener('keyup', this.onKeyUp, false);
|
|
4286
|
-
this.
|
|
4287
|
-
this.renderer.domElement.removeEventListener('mousedown', this.mouseDown, false);
|
|
5426
|
+
this.unbindScenePointerEvents();
|
|
4288
5427
|
if (typeof this._cameraChangeObserver === 'function') {
|
|
4289
5428
|
this._cameraChangeObserver('firstPersonLock');
|
|
4290
5429
|
}
|
|
@@ -4293,6 +5432,7 @@ export default {
|
|
|
4293
5432
|
this.pointControls.addEventListener('unlock', () => {
|
|
4294
5433
|
this.firstPerSign = false;
|
|
4295
5434
|
this.cameraControls.enabled = true;
|
|
5435
|
+
console.log(this.cameraControls);
|
|
4296
5436
|
// 返回初始视角
|
|
4297
5437
|
this.home();
|
|
4298
5438
|
try {
|
|
@@ -4306,8 +5446,8 @@ export default {
|
|
|
4306
5446
|
setTimeout(() => {
|
|
4307
5447
|
window.removeEventListener('keydown', this.onKeyDown);
|
|
4308
5448
|
window.removeEventListener('keyup', this.onKeyUp);
|
|
4309
|
-
this.
|
|
4310
|
-
this.
|
|
5449
|
+
this.bindScenePointerEvents();
|
|
5450
|
+
this.ensureTransformSelectionValid();
|
|
4311
5451
|
// this.timeRender()
|
|
4312
5452
|
}, 0);
|
|
4313
5453
|
if (typeof this._cameraChangeObserver === 'function') {
|
|
@@ -4353,8 +5493,8 @@ export default {
|
|
|
4353
5493
|
this.canJump = true;
|
|
4354
5494
|
}
|
|
4355
5495
|
// 根据速度值移动控制器
|
|
4356
|
-
this.pointControls.
|
|
4357
|
-
this.pointControls.
|
|
5496
|
+
this.pointControls.moveRight(-this.velocity.x * delta);
|
|
5497
|
+
this.pointControls.moveForward(-this.velocity.z * delta);
|
|
4358
5498
|
control.position.y += this.velocity.y * delta;
|
|
4359
5499
|
// 保证控制器的y轴在平面上
|
|
4360
5500
|
if (control.position.y < 3 - 0 / 10) {
|
|
@@ -4405,9 +5545,9 @@ export default {
|
|
|
4405
5545
|
break;
|
|
4406
5546
|
// 跳跃
|
|
4407
5547
|
case 32:
|
|
4408
|
-
if (this.canJump && spaceUp) this.velocity.y += this.upSpeed;
|
|
5548
|
+
if (this.canJump && this.spaceUp) this.velocity.y += this.upSpeed;
|
|
4409
5549
|
this.canJump = false;
|
|
4410
|
-
spaceUp = false;
|
|
5550
|
+
this.spaceUp = false;
|
|
4411
5551
|
break;
|
|
4412
5552
|
}
|
|
4413
5553
|
},
|
|
@@ -4437,7 +5577,7 @@ export default {
|
|
|
4437
5577
|
break;
|
|
4438
5578
|
// 跳跃
|
|
4439
5579
|
case 32:
|
|
4440
|
-
spaceUp = true;
|
|
5580
|
+
this.spaceUp = true;
|
|
4441
5581
|
break;
|
|
4442
5582
|
}
|
|
4443
5583
|
},
|
|
@@ -4470,9 +5610,9 @@ export default {
|
|
|
4470
5610
|
/*
|
|
4471
5611
|
参数: type: '', distance、area、angle、height, 暂时只提供距离、面积、角度、高度这四种方式
|
|
4472
5612
|
*/
|
|
4473
|
-
openMeasure(type) {
|
|
5613
|
+
openMeasure(type, isClear = false) {
|
|
4474
5614
|
if (this.threeMeasure) {
|
|
4475
|
-
this.threeMeasure.close(
|
|
5615
|
+
this.threeMeasure.close(isClear);
|
|
4476
5616
|
this.threeMeasure = null;
|
|
4477
5617
|
}
|
|
4478
5618
|
this.measureFlag = true;
|
|
@@ -4533,6 +5673,20 @@ export default {
|
|
|
4533
5673
|
// 移除键盘事件监听器
|
|
4534
5674
|
document.removeEventListener('keydown', this.handleMeasureKeyDown, false);
|
|
4535
5675
|
},
|
|
5676
|
+
// 增加一个清除所有测量结果的方法 使用统一名字的
|
|
5677
|
+
clearMeasureByName() {
|
|
5678
|
+
let list = this.getObjectByName('measureObj')
|
|
5679
|
+
list.forEach(item => {
|
|
5680
|
+
if (item.geometry) {
|
|
5681
|
+
item.geometry.dispose();
|
|
5682
|
+
item.material.dispose();
|
|
5683
|
+
}
|
|
5684
|
+
if (this.scene) this.scene.remove(item);
|
|
5685
|
+
})
|
|
5686
|
+
if (this.threeMeasure) {
|
|
5687
|
+
this.threeMeasure.clear();
|
|
5688
|
+
}
|
|
5689
|
+
},
|
|
4536
5690
|
handleMeasureKeyDown(event) {
|
|
4537
5691
|
// 检查是否按下了ESC键
|
|
4538
5692
|
const keyParam = {
|
|
@@ -5002,7 +6156,7 @@ export default {
|
|
|
5002
6156
|
: this.batchLoadingState;
|
|
5003
6157
|
// 如果已经在加载中,先停止之前的加载
|
|
5004
6158
|
if (loadingState.isLoading) {
|
|
5005
|
-
this.stopBatchLoading();
|
|
6159
|
+
this.stopBatchLoading('restart');
|
|
5006
6160
|
}
|
|
5007
6161
|
|
|
5008
6162
|
// 重置instance-parser的处理状态
|
|
@@ -5337,7 +6491,7 @@ export default {
|
|
|
5337
6491
|
/**
|
|
5338
6492
|
* 停止批量加载
|
|
5339
6493
|
*/
|
|
5340
|
-
stopBatchLoading() {
|
|
6494
|
+
stopBatchLoading(reason = 'stop') {
|
|
5341
6495
|
const loadingState = this.noObserver
|
|
5342
6496
|
? this.noObserver.batchLoadingState
|
|
5343
6497
|
: this.batchLoadingState;
|
|
@@ -5345,6 +6499,9 @@ export default {
|
|
|
5345
6499
|
cancelAnimationFrame(loadingState.animationFrameId);
|
|
5346
6500
|
loadingState.animationFrameId = null;
|
|
5347
6501
|
}
|
|
6502
|
+
if (loadingState.isLoading && typeof loadingState.options?.onCancel === 'function') {
|
|
6503
|
+
loadingState.options.onCancel({ reason });
|
|
6504
|
+
}
|
|
5348
6505
|
loadingState.isLoading = false;
|
|
5349
6506
|
this.batchLoadingState.isLoading = false;
|
|
5350
6507
|
},
|
|
@@ -5592,6 +6749,7 @@ export default {
|
|
|
5592
6749
|
.fl-model-containor {
|
|
5593
6750
|
width: 100%;
|
|
5594
6751
|
height: 100%;
|
|
6752
|
+
position: relative;
|
|
5595
6753
|
cursor: pointer;
|
|
5596
6754
|
}
|
|
5597
6755
|
::v-deep .tips-label {
|