Fix handle rotation to properly match mesh orientation
Handle meshes now correctly rotate to match the target mesh's world-space orientation instead of appearing axis-aligned. Root Cause: - Handle positions from HandleGeometry are calculated in world space - Setting mesh.position treats values as local space - This created coordinate system mismatch when rotation was also set - Result: rotation appeared to have no effect Solution: - Extract rotation from mesh world matrix using quaternion decomposition - Set rotation FIRST (before position) - Use setAbsolutePosition() for world-space positioning - This ensures rotation and position work correctly together Changes: - Import Quaternion from @babylonjs/core - Update createHandleMeshes(): decompose world matrix, set rotation, then use setAbsolutePosition() - Rename updateHandlePositions() to updateHandleTransforms() - Update updateHandleTransforms(): same rotation-then-position approach - Add null check for _targetMesh in updateHandleTransforms() Technical Details: - computeWorldMatrix(true) gets complete transform including parent - decompose() extracts pure rotation as quaternion (avoids gimbal lock) - setAbsolutePosition() correctly handles world-space coords with rotation - Order matters: rotation before position for correct transformation Result: ✅ Handle box shapes visually tilt/rotate with mesh ✅ Handles remain correctly positioned on OBB ✅ Both wireframe and individual handles rotate together Files modified: - ResizeGizmoVisuals.ts: Handle rotation implementation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
5fbf2b87c1
commit
af52d5992c
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "immersive",
|
||||
"private": true,
|
||||
"version": "0.0.8-22",
|
||||
"version": "0.0.8-23",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
||||
@ -12,7 +12,8 @@ import {
|
||||
Color3,
|
||||
UtilityLayerRenderer,
|
||||
LinesMesh,
|
||||
Vector3
|
||||
Vector3,
|
||||
Quaternion
|
||||
} from "@babylonjs/core";
|
||||
import { HandlePosition, HandleType } from "./types";
|
||||
import { ResizeGizmoConfigManager } from "./ResizeGizmoConfig";
|
||||
@ -90,7 +91,7 @@ export class ResizeGizmoVisuals {
|
||||
|
||||
// Update visuals
|
||||
this.updateBoundingBox();
|
||||
this.updateHandlePositions();
|
||||
this.updateHandleTransforms();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -240,7 +241,15 @@ export class ResizeGizmoVisuals {
|
||||
this._utilityLayer.utilityLayerScene
|
||||
);
|
||||
|
||||
mesh.position = handle.position.clone();
|
||||
// Extract and set rotation first (from world matrix)
|
||||
const worldMatrix = this._targetMesh.computeWorldMatrix(true);
|
||||
const rotation = new Quaternion();
|
||||
worldMatrix.decompose(undefined, rotation, undefined);
|
||||
mesh.rotationQuaternion = rotation;
|
||||
|
||||
// Set world-space position (works correctly with rotation)
|
||||
mesh.setAbsolutePosition(handle.position);
|
||||
|
||||
mesh.isPickable = true;
|
||||
|
||||
// Create material
|
||||
@ -277,13 +286,24 @@ export class ResizeGizmoVisuals {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update handle positions
|
||||
* Update handle transforms (position and rotation)
|
||||
*/
|
||||
private updateHandlePositions(): void {
|
||||
private updateHandleTransforms(): void {
|
||||
if (!this._targetMesh) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const handle of this._handles) {
|
||||
const mesh = this._handleMeshes.get(handle.id);
|
||||
if (mesh) {
|
||||
mesh.position = handle.position.clone();
|
||||
// Update rotation to match target mesh (from world matrix)
|
||||
const worldMatrix = this._targetMesh.computeWorldMatrix(true);
|
||||
const rotation = new Quaternion();
|
||||
worldMatrix.decompose(undefined, rotation, undefined);
|
||||
mesh.rotationQuaternion = rotation;
|
||||
|
||||
// Set world-space position (works correctly with rotation)
|
||||
mesh.setAbsolutePosition(handle.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user