Fix diagram text sync, resize handle positioning, and PouchDB delete handling
- Fix diagramObject text setter to update entity before notifying observers - Improve ResizeGizmo handle positioning directly at corners/faces with constant screen-size scaling - Fix PouchDB sync to handle deleted documents using _id field for compatibility Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
960c64984e
commit
8c2b7f9c7d
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "immersive",
|
||||
"private": true,
|
||||
"version": "0.0.8-45",
|
||||
"version": "0.0.8-46",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
||||
@ -227,13 +227,24 @@ export class DiagramObject {
|
||||
if (this._labelBack) {
|
||||
this._labelBack.dispose();
|
||||
}
|
||||
if (this._diagramEntity.text != value) {
|
||||
const textChanged = this._diagramEntity.text != value;
|
||||
|
||||
// Update the entity text FIRST (before notifying observers)
|
||||
this._diagramEntity.text = value;
|
||||
|
||||
// Also update mesh metadata to keep in sync with diagramEntity getter
|
||||
if (this._mesh && this._mesh.metadata) {
|
||||
this._mesh.metadata.text = value;
|
||||
}
|
||||
|
||||
// THEN notify observers with the UPDATED entity
|
||||
if (textChanged) {
|
||||
this._eventObservable.notifyObservers({
|
||||
type: DiagramEventType.MODIFY,
|
||||
entity: this._diagramEntity
|
||||
}, DiagramEventObserverMask.TO_DB);
|
||||
}
|
||||
this._diagramEntity.text = value;
|
||||
|
||||
this._label = createLabel(value);
|
||||
this._label.parent = this._baseTransform;
|
||||
this._labelBack = new InstancedMesh('labelBack' + value, (this._label as Mesh));
|
||||
|
||||
@ -108,6 +108,10 @@ export class ResizeGizmo {
|
||||
* Create corner and face handles
|
||||
*/
|
||||
private createHandles(): void {
|
||||
// Ensure world matrix and bounding info are current
|
||||
this._targetMesh.computeWorldMatrix(true);
|
||||
this._targetMesh.refreshBoundingInfo();
|
||||
|
||||
// Get bounding box for positioning
|
||||
const targetBoundingInfo = this._targetMesh.getBoundingInfo();
|
||||
const boundingBox = targetBoundingInfo.boundingBox;
|
||||
@ -116,10 +120,10 @@ export class ResizeGizmo {
|
||||
const innerCorners = boundingBox.vectorsWorld;
|
||||
const worldMatrix = this._targetMesh.getWorldMatrix();
|
||||
|
||||
// Calculate handle size once (based on corner distance)
|
||||
const handleSize = innerCorners[0].subtract(bboxCenter).length() * .5;
|
||||
// Unit size - actual visual size controlled by updateHandleScaling()
|
||||
const handleSize = 1.0;
|
||||
|
||||
// Create corner handles
|
||||
// Create corner handles - positioned directly at bounding box corners
|
||||
CORNER_POSITIONS.forEach((cornerDef, index) => {
|
||||
const cornerPos = innerCorners[index];
|
||||
|
||||
@ -129,10 +133,8 @@ export class ResizeGizmo {
|
||||
this._utilityLayer.utilityLayerScene
|
||||
);
|
||||
|
||||
// Position outward from center so handle corner touches bounding box corner
|
||||
const direction = cornerPos.subtract(bboxCenter).normalize();
|
||||
const offset = direction.scale(handleSize * Math.sqrt(3) / 2);
|
||||
handleMesh.position = cornerPos.add(offset);
|
||||
// Position handle at the corner (scaling will make it small)
|
||||
handleMesh.position = cornerPos.clone();
|
||||
handleMesh.rotationQuaternion = this._targetMesh.absoluteRotationQuaternion;
|
||||
handleMesh.material = this._handleMaterial;
|
||||
handleMesh.isPickable = true;
|
||||
@ -156,10 +158,8 @@ export class ResizeGizmo {
|
||||
this._utilityLayer.utilityLayerScene
|
||||
);
|
||||
|
||||
// Position outward from center so handle touches face center
|
||||
const direction = faceCenterWorld.subtract(bboxCenter).normalize();
|
||||
const offset = direction.scale(handleSize * Math.sqrt(3) / 2);
|
||||
handleMesh.position = faceCenterWorld.add(offset);
|
||||
// Position handle at the face center (scaling will make it small)
|
||||
handleMesh.position = faceCenterWorld.clone();
|
||||
handleMesh.rotationQuaternion = this._targetMesh.absoluteRotationQuaternion;
|
||||
handleMesh.material = this._handleMaterial;
|
||||
handleMesh.isPickable = true;
|
||||
@ -197,15 +197,20 @@ export class ResizeGizmo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update handle scaling based on camera distance for consistent visual size
|
||||
* Update handle scaling based on camera distance for constant screen size.
|
||||
* Handles will appear the same visual size regardless of distance.
|
||||
*/
|
||||
private updateHandleScaling(): void {
|
||||
const camera = this._scene.activeCamera;
|
||||
if (!camera) return;
|
||||
|
||||
// Target angular size - tune this for desired visual size
|
||||
// 0.03 means handles appear ~3cm at 1m distance, ~6cm at 2m, etc.
|
||||
const targetAngularSize = 0.03;
|
||||
|
||||
for (const handle of this._handles) {
|
||||
const distance = Vector3.Distance(camera.globalPosition, handle.position);
|
||||
const scaleFactor = distance; // Adjust multiplier to control visual size
|
||||
const scaleFactor = distance * targetAngularSize;
|
||||
handle.scaling = new Vector3(scaleFactor, scaleFactor, scaleFactor);
|
||||
}
|
||||
}
|
||||
@ -482,27 +487,24 @@ export class ResizeGizmo {
|
||||
* Update handle positions and sizes to match current target mesh bounding box
|
||||
*/
|
||||
private updateHandleTransforms(): void {
|
||||
// Ensure world matrix and bounding info are current
|
||||
this._targetMesh.computeWorldMatrix(true);
|
||||
this._targetMesh.refreshBoundingInfo();
|
||||
|
||||
const targetBoundingInfo = this._targetMesh.getBoundingInfo();
|
||||
const boundingBox = targetBoundingInfo.boundingBox;
|
||||
const bboxCenter = boundingBox.centerWorld;
|
||||
const extents = boundingBox.extendSize;
|
||||
const innerCorners = boundingBox.vectorsWorld;
|
||||
const worldMatrix = this._targetMesh.getWorldMatrix();
|
||||
|
||||
// Recalculate handle size based on new bounding box
|
||||
const newHandleSize = innerCorners[0].subtract(bboxCenter).length() * .2;
|
||||
|
||||
let handleIndex = 0;
|
||||
|
||||
// Update corner handles (first 8 handles)
|
||||
// Update corner handles (first 8 handles) - position at corners
|
||||
for (let i = 0; i < CORNER_POSITIONS.length; i++) {
|
||||
const handle = this._handles[handleIndex];
|
||||
const cornerPos = innerCorners[i];
|
||||
|
||||
// Update position
|
||||
const direction = cornerPos.subtract(bboxCenter).normalize();
|
||||
const offset = direction.scale(newHandleSize * Math.sqrt(3) / 2);
|
||||
handle.position = cornerPos.add(offset);
|
||||
handle.position = cornerPos.clone();
|
||||
handle.rotationQuaternion = this._targetMesh.absoluteRotationQuaternion;
|
||||
|
||||
handleIndex++;
|
||||
@ -520,10 +522,7 @@ export class ResizeGizmo {
|
||||
);
|
||||
const faceCenterWorld = Vector3.TransformCoordinates(localFacePos, worldMatrix);
|
||||
|
||||
// Update position
|
||||
const direction = faceCenterWorld.subtract(bboxCenter).normalize();
|
||||
const offset = direction.scale(newHandleSize * Math.sqrt(3) / 2);
|
||||
handle.position = faceCenterWorld.add(offset);
|
||||
handle.position = faceCenterWorld.clone();
|
||||
handle.rotationQuaternion = this._targetMesh.absoluteRotationQuaternion;
|
||||
|
||||
handleIndex++;
|
||||
|
||||
@ -61,9 +61,14 @@ export class PouchData {
|
||||
if (info.direction === 'pull' && info.change && info.change.docs) {
|
||||
info.change.docs.forEach((doc) => {
|
||||
if (doc._deleted) {
|
||||
this.onDBEntityRemoveObservable.notifyObservers(doc);
|
||||
} else if (doc.id && doc.id !== 'metadata') {
|
||||
this.onDBEntityUpdateObservable.notifyObservers(doc);
|
||||
// PouchDB deleted documents only have _id, not our custom id field
|
||||
// Create an entity with id from _id for the remove handler
|
||||
const entity = { id: doc._id, ...doc };
|
||||
this.onDBEntityRemoveObservable.notifyObservers(entity);
|
||||
} else if ((doc.id || doc._id) && (doc.id || doc._id) !== 'metadata') {
|
||||
// Accept both id and _id for compatibility
|
||||
const entity = doc.id ? doc : { id: doc._id, ...doc };
|
||||
this.onDBEntityUpdateObservable.notifyObservers(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user