@2112-lab/central-plant 0.3.26 β 0.3.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/index.js +894 -117
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/core/centralPlantInternals.js +17 -0
- package/dist/cjs/src/core/sceneViewer.js +55 -2
- package/dist/cjs/src/managers/behaviors/IoAnimationManager.js +24 -1
- package/dist/cjs/src/managers/behaviors/IoOutlineManager.js +258 -0
- package/dist/cjs/src/managers/controls/transformControlsManager.js +319 -43
- package/dist/cjs/src/managers/scene/animationManager.js +9 -2
- package/dist/cjs/src/managers/scene/componentTooltipManager.js +190 -27
- package/dist/cjs/src/managers/scene/modelManager.js +15 -1
- package/dist/cjs/src/utils/boundingBoxUtils.js +38 -40
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/core/centralPlantInternals.js +17 -0
- package/dist/esm/src/core/sceneViewer.js +55 -2
- package/dist/esm/src/managers/behaviors/IoAnimationManager.js +24 -1
- package/dist/esm/src/managers/behaviors/IoOutlineManager.js +234 -0
- package/dist/esm/src/managers/controls/transformControlsManager.js +319 -43
- package/dist/esm/src/managers/scene/animationManager.js +9 -2
- package/dist/esm/src/managers/scene/componentTooltipManager.js +191 -28
- package/dist/esm/src/managers/scene/modelManager.js +16 -2
- package/dist/esm/src/utils/boundingBoxUtils.js +39 -42
- package/package.json +1 -1
|
@@ -94,8 +94,17 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
94
94
|
onModeChange: null,
|
|
95
95
|
onObjectRemoved: null,
|
|
96
96
|
onSelectionChanged: null,
|
|
97
|
-
onIODeviceClick: null
|
|
97
|
+
onIODeviceClick: null,
|
|
98
|
+
onIODeviceDrag: null,
|
|
99
|
+
onIODeviceDragEnd: null
|
|
98
100
|
};
|
|
101
|
+
|
|
102
|
+
// IO device drag tracking state
|
|
103
|
+
this._ioDragMesh = null;
|
|
104
|
+
this._ioDragStartX = 0;
|
|
105
|
+
this._ioDragStartY = 0;
|
|
106
|
+
this._ioDragMoved = false;
|
|
107
|
+
this._suppressNextClick = false;
|
|
99
108
|
this.init();
|
|
100
109
|
}
|
|
101
110
|
|
|
@@ -175,6 +184,12 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
175
184
|
if (callbacks.onIODeviceClick) {
|
|
176
185
|
this.callbacks.onIODeviceClick = callbacks.onIODeviceClick;
|
|
177
186
|
}
|
|
187
|
+
if (callbacks.onIODeviceDrag) {
|
|
188
|
+
this.callbacks.onIODeviceDrag = callbacks.onIODeviceDrag;
|
|
189
|
+
}
|
|
190
|
+
if (callbacks.onIODeviceDragEnd) {
|
|
191
|
+
this.callbacks.onIODeviceDragEnd = callbacks.onIODeviceDragEnd;
|
|
192
|
+
}
|
|
178
193
|
console.log('π Transform controls callbacks registered');
|
|
179
194
|
}
|
|
180
195
|
/**
|
|
@@ -381,6 +396,11 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
381
396
|
value: function setupKeyboardControls() {
|
|
382
397
|
var _this3 = this;
|
|
383
398
|
this.eventHandlers.keydown = function (event) {
|
|
399
|
+
// Restore perspective camera when pressing Escape from ortho face view
|
|
400
|
+
if (event.code === 'Escape') {
|
|
401
|
+
_this3._restorePerspectiveCamera();
|
|
402
|
+
}
|
|
403
|
+
|
|
384
404
|
// Only handle keys when transform controls are active
|
|
385
405
|
if (!_this3.transformControls.enabled || _this3.transformState.isTransforming) {
|
|
386
406
|
return;
|
|
@@ -415,9 +435,82 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
415
435
|
var raycaster = new THREE.Raycaster();
|
|
416
436
|
var mouse = new THREE.Vector2();
|
|
417
437
|
|
|
418
|
-
//
|
|
438
|
+
// ββ IO device drag ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
439
|
+
// Detect pointerdown on an IO device mesh and convert a drag gesture into
|
|
440
|
+
// state changes. Up/right = positive direction, down/left = negative.
|
|
441
|
+
this.eventHandlers.pointerdown = function (event) {
|
|
442
|
+
if (_this4.transformState.isTransforming) return;
|
|
443
|
+
if (!_this4.callbacks.onIODeviceDrag) return;
|
|
444
|
+
_this4._calculateMousePosition(event, mouse);
|
|
445
|
+
raycaster.setFromCamera(mouse, _this4.camera);
|
|
446
|
+
var allIntersects = raycaster.intersectObjects(_this4.scene.children, true);
|
|
447
|
+
var ioDeviceObject = null;
|
|
448
|
+
var _iterator = _createForOfIteratorHelper(allIntersects),
|
|
449
|
+
_step;
|
|
450
|
+
try {
|
|
451
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
452
|
+
var hit = _step.value;
|
|
453
|
+
var obj = hit.object;
|
|
454
|
+
while (obj) {
|
|
455
|
+
var _obj$userData;
|
|
456
|
+
if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) === 'io-device') {
|
|
457
|
+
ioDeviceObject = obj;
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
obj = obj.parent;
|
|
461
|
+
}
|
|
462
|
+
if (ioDeviceObject) break;
|
|
463
|
+
}
|
|
464
|
+
} catch (err) {
|
|
465
|
+
_iterator.e(err);
|
|
466
|
+
} finally {
|
|
467
|
+
_iterator.f();
|
|
468
|
+
}
|
|
469
|
+
if (!ioDeviceObject) return;
|
|
470
|
+
|
|
471
|
+
// Begin session
|
|
472
|
+
_this4._ioDragMesh = ioDeviceObject;
|
|
473
|
+
_this4._ioDragStartX = event.clientX;
|
|
474
|
+
_this4._ioDragStartY = event.clientY;
|
|
475
|
+
_this4._ioDragMoved = false;
|
|
476
|
+
if (_this4.orbitControls) _this4.orbitControls.enabled = false;
|
|
477
|
+
_this4.callbacks.onIODeviceDrag(ioDeviceObject, 0, true);
|
|
478
|
+
var onMove = function onMove(e) {
|
|
479
|
+
var dx = e.clientX - _this4._ioDragStartX;
|
|
480
|
+
var dy = e.clientY - _this4._ioDragStartY;
|
|
481
|
+
if (Math.abs(dx) > 4 || Math.abs(dy) > 4) _this4._ioDragMoved = true;
|
|
482
|
+
// Up (βscreenY) and right (+screenX) are positive
|
|
483
|
+
var signedDelta = _this4._ioDragStartY - e.clientY + (e.clientX - _this4._ioDragStartX);
|
|
484
|
+
_this4.callbacks.onIODeviceDrag(_this4._ioDragMesh, signedDelta, false);
|
|
485
|
+
};
|
|
486
|
+
var _onUp = function onUp() {
|
|
487
|
+
window.removeEventListener('pointermove', onMove);
|
|
488
|
+
window.removeEventListener('pointerup', _onUp);
|
|
489
|
+
if (_this4.orbitControls) _this4.orbitControls.enabled = true;
|
|
490
|
+
if (_this4._ioDragMoved) {
|
|
491
|
+
// Suppress the click event that will fire after this pointerup
|
|
492
|
+
_this4._suppressNextClick = true;
|
|
493
|
+
}
|
|
494
|
+
if (_this4.callbacks.onIODeviceDragEnd) {
|
|
495
|
+
_this4.callbacks.onIODeviceDragEnd(_this4._ioDragMesh);
|
|
496
|
+
}
|
|
497
|
+
_this4._ioDragMesh = null;
|
|
498
|
+
};
|
|
499
|
+
window.addEventListener('pointermove', onMove);
|
|
500
|
+
window.addEventListener('pointerup', _onUp);
|
|
501
|
+
};
|
|
502
|
+
this.renderer.domElement.addEventListener('pointerdown', this.eventHandlers.pointerdown);
|
|
503
|
+
|
|
504
|
+
// Click handler: left-click selects the object (bounding box + transform controls).
|
|
505
|
+
// Right-click on a component shows the tooltip.
|
|
419
506
|
this.eventHandlers.click = function (event) {
|
|
420
507
|
var _targetObject$userDat;
|
|
508
|
+
// Suppress click that follows an IO device drag
|
|
509
|
+
if (_this4._suppressNextClick) {
|
|
510
|
+
_this4._suppressNextClick = false;
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
421
514
|
// Skip if currently transforming
|
|
422
515
|
if (_this4.transformState.isTransforming) {
|
|
423
516
|
return;
|
|
@@ -430,15 +523,15 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
430
523
|
// Check for direct io-device mesh click (before bounding box selection)
|
|
431
524
|
if (_this4.callbacks.onIODeviceClick) {
|
|
432
525
|
var allIntersects = raycaster.intersectObjects(_this4.scene.children, true);
|
|
433
|
-
var
|
|
434
|
-
|
|
526
|
+
var _iterator2 = _createForOfIteratorHelper(allIntersects),
|
|
527
|
+
_step2;
|
|
435
528
|
try {
|
|
436
|
-
for (
|
|
437
|
-
var hit =
|
|
529
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
530
|
+
var hit = _step2.value;
|
|
438
531
|
var obj = hit.object;
|
|
439
532
|
while (obj) {
|
|
440
|
-
var _obj$
|
|
441
|
-
if (((_obj$
|
|
533
|
+
var _obj$userData2;
|
|
534
|
+
if (((_obj$userData2 = obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.objectType) === 'io-device') {
|
|
442
535
|
_this4.callbacks.onIODeviceClick(obj);
|
|
443
536
|
return;
|
|
444
537
|
}
|
|
@@ -446,9 +539,9 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
446
539
|
}
|
|
447
540
|
}
|
|
448
541
|
} catch (err) {
|
|
449
|
-
|
|
542
|
+
_iterator2.e(err);
|
|
450
543
|
} finally {
|
|
451
|
-
|
|
544
|
+
_iterator2.f();
|
|
452
545
|
}
|
|
453
546
|
}
|
|
454
547
|
|
|
@@ -483,23 +576,194 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
483
576
|
return;
|
|
484
577
|
}
|
|
485
578
|
|
|
486
|
-
//
|
|
487
|
-
|
|
488
|
-
if (isAlreadySelected) {
|
|
489
|
-
// Second click on already-selected object: Full selection including tooltips
|
|
490
|
-
_this4.selectObject(targetObject);
|
|
491
|
-
} else {
|
|
492
|
-
// First click on a new object: Transform controls and bounding box only
|
|
493
|
-
// Always deselect first (this clears tooltips via the callback)
|
|
579
|
+
// Left-click: select for transform only (bounding box, no tooltip)
|
|
580
|
+
if (!_this4.selectedObjects.includes(targetObject)) {
|
|
494
581
|
_this4.deselectObject();
|
|
495
|
-
|
|
496
|
-
// Then select the new object if there is one (this shows transform controls and bounding box)
|
|
497
|
-
if (targetObject) {
|
|
498
|
-
_this4.selectObjectForTransformOnly(targetObject);
|
|
499
|
-
}
|
|
500
582
|
}
|
|
583
|
+
_this4.selectObjectForTransformOnly(targetObject);
|
|
501
584
|
};
|
|
502
585
|
this.renderer.domElement.addEventListener('click', this.eventHandlers.click);
|
|
586
|
+
|
|
587
|
+
// Right-click handler: show tooltip for the clicked component.
|
|
588
|
+
this.eventHandlers.contextmenu = function (event) {
|
|
589
|
+
var _targetObject$userDat2;
|
|
590
|
+
event.preventDefault();
|
|
591
|
+
if (_this4.transformState.isTransforming) return;
|
|
592
|
+
_this4._calculateMousePosition(event, mouse);
|
|
593
|
+
raycaster.setFromCamera(mouse, _this4.camera);
|
|
594
|
+
var targetObject = _this4._findTargetObject(raycaster, objectFilter);
|
|
595
|
+
if (!targetObject) return;
|
|
596
|
+
var objectType = (_targetObject$userDat2 = targetObject.userData) === null || _targetObject$userDat2 === void 0 ? void 0 : _targetObject$userDat2.objectType;
|
|
597
|
+
if (objectType !== 'component' && objectType !== 'gateway' && objectType !== 'segment') return;
|
|
598
|
+
|
|
599
|
+
// Ensure the object is selected, then show the full tooltip.
|
|
600
|
+
if (!_this4.selectedObjects.includes(targetObject)) {
|
|
601
|
+
_this4.deselectObject();
|
|
602
|
+
_this4.selectObjectForTransformOnly(targetObject);
|
|
603
|
+
}
|
|
604
|
+
_this4.selectObject(targetObject);
|
|
605
|
+
};
|
|
606
|
+
this.renderer.domElement.addEventListener('contextmenu', this.eventHandlers.contextmenu);
|
|
607
|
+
|
|
608
|
+
// Double-click handler: switch to orthographic camera fixed to the clicked face.
|
|
609
|
+
// Press Escape to restore the perspective camera.
|
|
610
|
+
this.eventHandlers.dblclick = function (event) {
|
|
611
|
+
if (_this4.transformState.isTransforming) return;
|
|
612
|
+
var sv = _this4.sceneViewer;
|
|
613
|
+
if (!sv) return;
|
|
614
|
+
_this4._calculateMousePosition(event, mouse);
|
|
615
|
+
raycaster.setFromCamera(_this4.camera, _this4.camera); // ensure raycaster uses current camera
|
|
616
|
+
raycaster.setFromCamera(mouse, _this4.camera);
|
|
617
|
+
|
|
618
|
+
// Raycast directly against scene meshes to obtain the face normal
|
|
619
|
+
var allHits = raycaster.intersectObjects(_this4.scene.children, true).filter(function (h) {
|
|
620
|
+
var _h$object$userData, _h$object$userData2;
|
|
621
|
+
return !((_h$object$userData = h.object.userData) !== null && _h$object$userData !== void 0 && _h$object$userData.isTransformControls) && !((_h$object$userData2 = h.object.userData) !== null && _h$object$userData2 !== void 0 && _h$object$userData2.isBoundingBox);
|
|
622
|
+
});
|
|
623
|
+
if (!allHits.length || !allHits[0].face) return;
|
|
624
|
+
var hit = allHits[0];
|
|
625
|
+
|
|
626
|
+
// Walk up to find the component root
|
|
627
|
+
var componentObj = hit.object;
|
|
628
|
+
while (componentObj) {
|
|
629
|
+
var _componentObj$userDat;
|
|
630
|
+
if (((_componentObj$userDat = componentObj.userData) === null || _componentObj$userDat === void 0 ? void 0 : _componentObj$userDat.objectType) === 'component') break;
|
|
631
|
+
componentObj = componentObj.parent;
|
|
632
|
+
}
|
|
633
|
+
if (!componentObj) return;
|
|
634
|
+
|
|
635
|
+
// Transform face normal from local object space to world space
|
|
636
|
+
var normalMatrix = new THREE.Matrix3().getNormalMatrix(hit.object.matrixWorld);
|
|
637
|
+
var worldNormal = hit.face.normal.clone().applyMatrix3(normalMatrix).normalize();
|
|
638
|
+
|
|
639
|
+
// Snap to the closest cardinal axis (Z-up: Β±X, Β±Y, Β±Z)
|
|
640
|
+
var cardinals = [new THREE.Vector3(1, 0, 0), new THREE.Vector3(-1, 0, 0), new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, -1, 0), new THREE.Vector3(0, 0, 1), new THREE.Vector3(0, 0, -1)];
|
|
641
|
+
var faceDir = cardinals.reduce(function (best, c) {
|
|
642
|
+
return c.dot(worldNormal) > best.dot(worldNormal) ? c : best;
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
// Bounding box of the component
|
|
646
|
+
var bbox = new THREE.Box3().setFromObject(componentObj);
|
|
647
|
+
var center = bbox.getCenter(new THREE.Vector3());
|
|
648
|
+
var size = bbox.getSize(new THREE.Vector3());
|
|
649
|
+
|
|
650
|
+
// Ortho half-extents: axes perpendicular to the face direction
|
|
651
|
+
var isXFace = Math.abs(faceDir.x) > 0.5;
|
|
652
|
+
var isYFace = Math.abs(faceDir.y) > 0.5;
|
|
653
|
+
var halfW, halfH;
|
|
654
|
+
if (isXFace) {
|
|
655
|
+
halfW = size.y / 2;
|
|
656
|
+
halfH = size.z / 2;
|
|
657
|
+
} else if (isYFace) {
|
|
658
|
+
halfW = size.x / 2;
|
|
659
|
+
halfH = size.z / 2;
|
|
660
|
+
} else {
|
|
661
|
+
halfW = size.x / 2;
|
|
662
|
+
halfH = size.y / 2;
|
|
663
|
+
}
|
|
664
|
+
var padding = 1.6;
|
|
665
|
+
var domEl = sv.renderer.domElement;
|
|
666
|
+
var aspect = domEl.clientWidth / (domEl.clientHeight || 1);
|
|
667
|
+
|
|
668
|
+
// Frustum must satisfy both:
|
|
669
|
+
// frustumHalfW >= halfW * padding (object fits horizontally)
|
|
670
|
+
// frustumHalfH >= halfH * padding (object fits vertically)
|
|
671
|
+
// frustumHalfW / frustumHalfH == aspect (no squishing)
|
|
672
|
+
var minHalfH = halfH * padding;
|
|
673
|
+
var minHalfW = halfW * padding;
|
|
674
|
+
var frustumHalfH = Math.max(minHalfH, minHalfW / aspect);
|
|
675
|
+
var frustumHalfW = frustumHalfH * aspect;
|
|
676
|
+
var isZFace = Math.abs(faceDir.z) > 0.5;
|
|
677
|
+
var upVec = isZFace ? new THREE.Vector3(0, 1, 0) : new THREE.Vector3(0, 0, 1);
|
|
678
|
+
|
|
679
|
+
// Store the perspective camera snapshot on first entry
|
|
680
|
+
if (!sv._perspCameraSnapshot) {
|
|
681
|
+
var _sv$controls$target$c, _sv$controls, _sv$controls2, _sv$controls3, _sv$controls4;
|
|
682
|
+
sv._perspCameraSnapshot = {
|
|
683
|
+
camera: sv.camera,
|
|
684
|
+
controlsTarget: (_sv$controls$target$c = (_sv$controls = sv.controls) === null || _sv$controls === void 0 || (_sv$controls = _sv$controls.target) === null || _sv$controls === void 0 ? void 0 : _sv$controls.clone()) !== null && _sv$controls$target$c !== void 0 ? _sv$controls$target$c : new THREE.Vector3(),
|
|
685
|
+
controlsMinDist: (_sv$controls2 = sv.controls) === null || _sv$controls2 === void 0 ? void 0 : _sv$controls2.minDistance,
|
|
686
|
+
controlsMaxDist: (_sv$controls3 = sv.controls) === null || _sv$controls3 === void 0 ? void 0 : _sv$controls3.maxDistance,
|
|
687
|
+
controlsMaxPolar: (_sv$controls4 = sv.controls) === null || _sv$controls4 === void 0 ? void 0 : _sv$controls4.maxPolarAngle
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Build the orthographic camera
|
|
692
|
+
var ortho = new THREE.OrthographicCamera(-frustumHalfW, frustumHalfW, frustumHalfH, -frustumHalfH, 0.01, 1000);
|
|
693
|
+
ortho.up.copy(upVec);
|
|
694
|
+
var dist = Math.max(size.x, size.y, size.z) * 3;
|
|
695
|
+
ortho.position.copy(center).addScaledVector(faceDir, dist);
|
|
696
|
+
ortho.lookAt(center);
|
|
697
|
+
// Store half-extents for resize updates (pre-aspect values so resize can recompute)
|
|
698
|
+
ortho.userData._orthoHalfExtents = {
|
|
699
|
+
halfW: halfW * padding,
|
|
700
|
+
halfH: halfH * padding
|
|
701
|
+
};
|
|
702
|
+
ortho.updateProjectionMatrix();
|
|
703
|
+
sv.camera = ortho;
|
|
704
|
+
_this4.camera = ortho;
|
|
705
|
+
if (sv.controls) {
|
|
706
|
+
sv.controls.object = ortho;
|
|
707
|
+
sv.controls.target.copy(center);
|
|
708
|
+
sv.controls.minDistance = 0.1;
|
|
709
|
+
sv.controls.maxDistance = 500;
|
|
710
|
+
sv.controls.maxPolarAngle = Math.PI;
|
|
711
|
+
sv.controls.update();
|
|
712
|
+
|
|
713
|
+
// Exit ortho mode when the camera actually moves (orbit/pan/zoom).
|
|
714
|
+
// Using 'change' instead of 'start' so a simple click (e.g. io-device
|
|
715
|
+
// toggle) never triggers the exit β only real camera movement does.
|
|
716
|
+
// Skip the first 'change' that fires from controls.update() below.
|
|
717
|
+
var _skipChanges = 1;
|
|
718
|
+
var _onOrbitChange = function onOrbitChange() {
|
|
719
|
+
if (_skipChanges-- > 0) return;
|
|
720
|
+
sv.controls.removeEventListener('change', _onOrbitChange);
|
|
721
|
+
_this4._orthoOrbitStartListener = null;
|
|
722
|
+
_this4._restorePerspectiveCamera();
|
|
723
|
+
};
|
|
724
|
+
sv.controls.addEventListener('change', _onOrbitChange);
|
|
725
|
+
_this4._orthoOrbitStartListener = {
|
|
726
|
+
controls: sv.controls,
|
|
727
|
+
fn: _onOrbitChange
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
console.log('π Switched to orthographic face view:', faceDir);
|
|
731
|
+
};
|
|
732
|
+
this.renderer.domElement.addEventListener('dblclick', this.eventHandlers.dblclick);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Restore the perspective camera after an orthographic face view.
|
|
737
|
+
* Safe to call when not in ortho mode (no-op).
|
|
738
|
+
* @private
|
|
739
|
+
*/
|
|
740
|
+
}, {
|
|
741
|
+
key: "_restorePerspectiveCamera",
|
|
742
|
+
value: function _restorePerspectiveCamera() {
|
|
743
|
+
var sv = this.sceneViewer;
|
|
744
|
+
if (!(sv !== null && sv !== void 0 && sv._perspCameraSnapshot)) return;
|
|
745
|
+
|
|
746
|
+
// Clean up any pending orbit-change listener
|
|
747
|
+
if (this._orthoOrbitStartListener) {
|
|
748
|
+
var _this$_orthoOrbitStar = this._orthoOrbitStartListener,
|
|
749
|
+
controls = _this$_orthoOrbitStar.controls,
|
|
750
|
+
fn = _this$_orthoOrbitStar.fn;
|
|
751
|
+
controls.removeEventListener('change', fn);
|
|
752
|
+
this._orthoOrbitStartListener = null;
|
|
753
|
+
}
|
|
754
|
+
var snap = sv._perspCameraSnapshot;
|
|
755
|
+
sv.camera = snap.camera;
|
|
756
|
+
this.camera = snap.camera;
|
|
757
|
+
if (sv.controls) {
|
|
758
|
+
sv.controls.object = snap.camera;
|
|
759
|
+
sv.controls.target.copy(snap.controlsTarget);
|
|
760
|
+
if (snap.controlsMinDist != null) sv.controls.minDistance = snap.controlsMinDist;
|
|
761
|
+
if (snap.controlsMaxDist != null) sv.controls.maxDistance = snap.controlsMaxDist;
|
|
762
|
+
if (snap.controlsMaxPolar != null) sv.controls.maxPolarAngle = snap.controlsMaxPolar;
|
|
763
|
+
sv.controls.update();
|
|
764
|
+
}
|
|
765
|
+
sv._perspCameraSnapshot = null;
|
|
766
|
+
console.log('π Restored perspective camera from ortho face view');
|
|
503
767
|
}
|
|
504
768
|
|
|
505
769
|
/**
|
|
@@ -649,11 +913,11 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
649
913
|
var isNewSegmentHorizontal = this._isSegmentHorizontal(segment);
|
|
650
914
|
|
|
651
915
|
// Check if all existing segments have the same orientation
|
|
652
|
-
var
|
|
653
|
-
|
|
916
|
+
var _iterator3 = _createForOfIteratorHelper(existingSegments),
|
|
917
|
+
_step3;
|
|
654
918
|
try {
|
|
655
|
-
for (
|
|
656
|
-
var existingSegment =
|
|
919
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
920
|
+
var existingSegment = _step3.value;
|
|
657
921
|
var isExistingHorizontal = this._isSegmentHorizontal(existingSegment);
|
|
658
922
|
|
|
659
923
|
// Disallow mixing horizontal and vertical
|
|
@@ -662,9 +926,9 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
662
926
|
}
|
|
663
927
|
}
|
|
664
928
|
} catch (err) {
|
|
665
|
-
|
|
929
|
+
_iterator3.e(err);
|
|
666
930
|
} finally {
|
|
667
|
-
|
|
931
|
+
_iterator3.f();
|
|
668
932
|
}
|
|
669
933
|
return true;
|
|
670
934
|
}
|
|
@@ -1116,12 +1380,12 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
1116
1380
|
value: function _applyDeltaToBoundingBoxHelpers() {
|
|
1117
1381
|
if (!this._dragStartGroupPosition || this.boundingBoxHelpers.length === 0) return;
|
|
1118
1382
|
var delta = this.multiSelectionGroup.position.clone().sub(this._dragStartGroupPosition);
|
|
1119
|
-
var
|
|
1120
|
-
|
|
1383
|
+
var _iterator4 = _createForOfIteratorHelper(this.boundingBoxHelpers),
|
|
1384
|
+
_step4;
|
|
1121
1385
|
try {
|
|
1122
|
-
for (
|
|
1386
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
1123
1387
|
var _helper$geometry2;
|
|
1124
|
-
var helper =
|
|
1388
|
+
var helper = _step4.value;
|
|
1125
1389
|
var startPositions = helper.userData._dragStartPositions;
|
|
1126
1390
|
var posAttr = (_helper$geometry2 = helper.geometry) === null || _helper$geometry2 === void 0 || (_helper$geometry2 = _helper$geometry2.attributes) === null || _helper$geometry2 === void 0 ? void 0 : _helper$geometry2.position;
|
|
1127
1391
|
if (!startPositions || !posAttr) continue;
|
|
@@ -1135,9 +1399,9 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
1135
1399
|
posAttr.needsUpdate = true;
|
|
1136
1400
|
}
|
|
1137
1401
|
} catch (err) {
|
|
1138
|
-
|
|
1402
|
+
_iterator4.e(err);
|
|
1139
1403
|
} finally {
|
|
1140
|
-
|
|
1404
|
+
_iterator4.f();
|
|
1141
1405
|
}
|
|
1142
1406
|
}
|
|
1143
1407
|
|
|
@@ -1515,11 +1779,11 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
1515
1779
|
var objectFilter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
1516
1780
|
var objectsWithBounds = this.getSelectableObjectsWithBounds(objectFilter);
|
|
1517
1781
|
var intersections = [];
|
|
1518
|
-
var
|
|
1519
|
-
|
|
1782
|
+
var _iterator5 = _createForOfIteratorHelper(objectsWithBounds),
|
|
1783
|
+
_step5;
|
|
1520
1784
|
try {
|
|
1521
|
-
for (
|
|
1522
|
-
var item =
|
|
1785
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
1786
|
+
var item = _step5.value;
|
|
1523
1787
|
var object = item.object,
|
|
1524
1788
|
boundingBox = item.boundingBox;
|
|
1525
1789
|
|
|
@@ -1539,9 +1803,9 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
1539
1803
|
|
|
1540
1804
|
// Sort by distance (closest first)
|
|
1541
1805
|
} catch (err) {
|
|
1542
|
-
|
|
1806
|
+
_iterator5.e(err);
|
|
1543
1807
|
} finally {
|
|
1544
|
-
|
|
1808
|
+
_iterator5.f();
|
|
1545
1809
|
}
|
|
1546
1810
|
intersections.sort(function (a, b) {
|
|
1547
1811
|
return a.distance - b.distance;
|
|
@@ -1927,8 +2191,8 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
1927
2191
|
key: "_updateSegmentReference",
|
|
1928
2192
|
value: function _updateSegmentReference(oldSegment, newSegment, index) {
|
|
1929
2193
|
var selectedIndex = this.selectedObjects.findIndex(function (obj) {
|
|
1930
|
-
var _obj$
|
|
1931
|
-
return obj.uuid === oldSegment.uuid || ((_obj$
|
|
2194
|
+
var _obj$userData3;
|
|
2195
|
+
return obj.uuid === oldSegment.uuid || ((_obj$userData3 = obj.userData) === null || _obj$userData3 === void 0 ? void 0 : _obj$userData3.originalUuid) === oldSegment.uuid;
|
|
1932
2196
|
});
|
|
1933
2197
|
if (selectedIndex !== -1 && newSegment) {
|
|
1934
2198
|
// Clear bounding box cache
|
|
@@ -2315,9 +2579,21 @@ var TransformControlsManager = /*#__PURE__*/function () {
|
|
|
2315
2579
|
if (this.eventHandlers.keydown) {
|
|
2316
2580
|
window.removeEventListener('keydown', this.eventHandlers.keydown);
|
|
2317
2581
|
}
|
|
2582
|
+
if (this.eventHandlers.pointerdown) {
|
|
2583
|
+
this.renderer.domElement.removeEventListener('pointerdown', this.eventHandlers.pointerdown);
|
|
2584
|
+
}
|
|
2318
2585
|
if (this.eventHandlers.click) {
|
|
2319
2586
|
this.renderer.domElement.removeEventListener('click', this.eventHandlers.click);
|
|
2320
2587
|
}
|
|
2588
|
+
if (this.eventHandlers.contextmenu) {
|
|
2589
|
+
this.renderer.domElement.removeEventListener('contextmenu', this.eventHandlers.contextmenu);
|
|
2590
|
+
}
|
|
2591
|
+
if (this.eventHandlers.dblclick) {
|
|
2592
|
+
this.renderer.domElement.removeEventListener('dblclick', this.eventHandlers.dblclick);
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2595
|
+
// Restore perspective camera if disposed while in ortho face view
|
|
2596
|
+
this._restorePerspectiveCamera();
|
|
2321
2597
|
|
|
2322
2598
|
// Remove sceneViewer event listener
|
|
2323
2599
|
if (this._objectTransformedListener && this.sceneViewer && typeof this.sceneViewer.off === 'function') {
|
|
@@ -59,11 +59,18 @@ var AnimationManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
59
59
|
sceneViewer.performanceMonitorManager.beginFrame();
|
|
60
60
|
}
|
|
61
61
|
try {
|
|
62
|
+
var _sceneViewer$managers;
|
|
62
63
|
// Update controls
|
|
63
64
|
sceneViewer.controls.update();
|
|
64
65
|
|
|
65
|
-
// Render the scene
|
|
66
|
-
|
|
66
|
+
// Render the scene β route through the outline manager when active so
|
|
67
|
+
// the mask pass and screen-space composite run after the main render.
|
|
68
|
+
var ioOutline = (_sceneViewer$managers = sceneViewer.managers) === null || _sceneViewer$managers === void 0 ? void 0 : _sceneViewer$managers.ioOutlineManager;
|
|
69
|
+
if (ioOutline !== null && ioOutline !== void 0 && ioOutline.isActive) {
|
|
70
|
+
ioOutline.render();
|
|
71
|
+
} else {
|
|
72
|
+
sceneViewer.renderer.render(sceneViewer.scene, sceneViewer.camera);
|
|
73
|
+
}
|
|
67
74
|
} catch (renderError) {
|
|
68
75
|
// Catch WebGL or rendering errors to prevent the animation loop from
|
|
69
76
|
// producing a permanent white screen. Log once and continue so that
|