Fix label positioning to use world space bounding boxes
Labels were incorrectly mixing local and global transform matrices, causing incorrect positioning on scaled/rotated meshes. Now properly converts world space bounding box positions to mesh local space using temporary TransformNode. Changes: - updateTextNode.ts: Use boundingBox.maximumWorld instead of boundingSphere.maximum - diagramObject.ts: Add empty object param to refreshBoundingInfo() - inputTextView.ts: Adjust input handle default position and mesh offsets 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
7849bf4eb2
commit
0b81605bdf
@ -205,7 +205,7 @@ export class DiagramObject {
|
||||
public updateLabelPosition() {
|
||||
if (this._label) {
|
||||
this._mesh.computeWorldMatrix(true);
|
||||
this._mesh.refreshBoundingInfo();
|
||||
this._mesh.refreshBoundingInfo({});
|
||||
|
||||
if (this._from && this._to) {
|
||||
// Connection labels (arrows/lines)
|
||||
|
||||
@ -31,9 +31,11 @@ export class InputTextView {
|
||||
this.handle = new Handle({
|
||||
contentMesh: this.inputMesh,
|
||||
label: 'Input',
|
||||
defaultPosition: new Vector3(0, .4, .5),
|
||||
defaultRotation: new Vector3(0, 0, 0)
|
||||
defaultPosition: new Vector3(0, .8, .7),
|
||||
defaultRotation: new Vector3(.36, 0, 0)
|
||||
});
|
||||
this.inputMesh.position.y = .02;
|
||||
this.inputMesh.position.z = .01;
|
||||
// Position is now controlled by Handle class
|
||||
this.createKeyboard();
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {AbstractMesh, Color3, DynamicTexture, Material, MeshBuilder, StandardMaterial} from "@babylonjs/core";
|
||||
import {AbstractMesh, Color3, DynamicTexture, Material, MeshBuilder, StandardMaterial, TransformNode} from "@babylonjs/core";
|
||||
import log from "loglevel";
|
||||
|
||||
|
||||
@ -63,7 +63,6 @@ export function updateTextNode(mesh: AbstractMesh, text: string) {
|
||||
|
||||
function createPlane(mat: Material, mesh: AbstractMesh, text: string, planeWidth: number, height: number): AbstractMesh {
|
||||
const plane = MeshBuilder.CreatePlane("text" + text, {width: planeWidth, height: height}, mesh.getScene());
|
||||
const yOffset = mesh.getBoundingInfo().boundingSphere.maximum.y;
|
||||
|
||||
plane.parent = mesh;
|
||||
plane.scaling.y = (1 / mesh.scaling.y);
|
||||
@ -75,9 +74,26 @@ function createPlane(mat: Material, mesh: AbstractMesh, text: string, planeWidth
|
||||
if (mesh.metadata?.template == "#connection-template") {
|
||||
plane.billboardMode = AbstractMesh.BILLBOARDMODE_Y;
|
||||
plane.position.y = mesh.position.y + .1;
|
||||
|
||||
} else {
|
||||
plane.position.y = yOffset + (height * plane.scaling.y);
|
||||
// Calculate label position using world space bounding box
|
||||
// This ensures labels are positioned correctly regardless of mesh transforms
|
||||
mesh.computeWorldMatrix(true);
|
||||
mesh.refreshBoundingInfo();
|
||||
|
||||
// Get the top of the bounding box in world space
|
||||
const top = mesh.getBoundingInfo().boundingBox.maximumWorld;
|
||||
|
||||
// Convert world space position to mesh's local space
|
||||
// Use temporary TransformNode to handle the transformation
|
||||
const temp = new TransformNode("temp", mesh.getScene());
|
||||
temp.position = top;
|
||||
temp.setParent(mesh);
|
||||
const y = temp.position.y;
|
||||
temp.dispose();
|
||||
|
||||
// Position label above the mesh with offset
|
||||
// Add additional offset for the scaled height of the label
|
||||
plane.position.y = y + 0.06 + (height * plane.scaling.y / 2);
|
||||
}
|
||||
plane.addLODLevel(3, null);
|
||||
return plane;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user