Use camera Z-up coordinates without modifying GLB imports
This commit is contained in:
@@ -28,22 +28,6 @@ export const MACHINE_PART_ROLES: MachinePartRole[] = ["base", "x", "y", "z", "to
|
||||
export const roleLabel = (role: MachinePartRole, coordinates: string) => ({ base: "床身底座", x: "X 轴部件", y: "Y 轴部件", z: "Z 轴部件", tool: "主轴/刀具", tilt: `${coordinates === "XYZBC" ? "B" : "A"} 轴部件`, c: "C 轴部件", work: "工件/工作台" }[role]);
|
||||
export const expectedParentRole = (role: MachinePartRole): MachinePartRole | null => ({ base: null, x: "base", y: "x", z: "y", tool: "z", tilt: "base", c: "tilt", work: "c" }[role] as MachinePartRole | null);
|
||||
|
||||
// glTF uses Y-up. The editor exposes the machine's right-handed X/Y/Z frame
|
||||
// with Z-up: machine (x, y, z) -> Three.js (x, z, -y).
|
||||
export const machineToThree = (value: Vec3): Vec3 => [value[0], value[2], -value[1]];
|
||||
export const threeToMachine = (value: Vec3): Vec3 => [value[0], -value[2], value[1]];
|
||||
export const machineFrameQuaternion = () => new THREE.Quaternion().setFromRotationMatrix(new THREE.Matrix4().set(1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1));
|
||||
export function machineEulerToThreeQuaternion(rotationDeg: Vec3) {
|
||||
const machine = new THREE.Euler(...rotationDeg.map(THREE.MathUtils.degToRad) as Vec3, "XYZ");
|
||||
const source = new THREE.Matrix4().makeRotationFromEuler(machine);
|
||||
const frame = new THREE.Matrix4().set(1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1);
|
||||
return new THREE.Quaternion().setFromRotationMatrix(frame.clone().multiply(source).multiply(frame.clone().invert()));
|
||||
}
|
||||
export function threeQuaternionToMachineEuler(rotation: THREE.Quaternion) {
|
||||
const frame = machineFrameQuaternion();
|
||||
const machine = frame.clone().invert().multiply(rotation);
|
||||
return new THREE.Euler().setFromQuaternion(machine, "XYZ").toArray().slice(0, 3).map((radians) => THREE.MathUtils.radToDeg(Number(radians))) as Vec3;
|
||||
}
|
||||
|
||||
const finite3 = (value: Vec3, label: string) => {
|
||||
if (value.length !== 3 || value.some((number) => !Number.isFinite(number))) throw new Error(`${label}需要三个有限数值`);
|
||||
@@ -137,10 +121,10 @@ export async function buildManagedMachine(input: { coordinates: "XYZAC" | "XYZBC
|
||||
for (const role of MACHINE_PART_ROLES) {
|
||||
const part = byRole.get(role)!;
|
||||
const placement = new THREE.Group(); placement.name = `component_${part.id}`; placement.visible = part.visible;
|
||||
placement.position.fromArray(machineToThree(part.translationMm)).multiplyScalar(.001);
|
||||
placement.quaternion.copy(machineEulerToThreeQuaternion(part.rotationDeg));
|
||||
placement.position.fromArray(part.translationMm).multiplyScalar(.001);
|
||||
placement.rotation.set(...part.rotationDeg.map(THREE.MathUtils.degToRad) as Vec3);
|
||||
placement.userData.machinePart = { role, filename: part.filename, hash: part.hash, originMm: [...part.originMm] };
|
||||
const visual = cloneMachinePartScene(part.scene); visual.position.fromArray(machineToThree(part.originMm).map((value) => -value) as Vec3).multiplyScalar(.001); placement.add(visual); links[role].add(placement);
|
||||
const visual = cloneMachinePartScene(part.scene); visual.position.fromArray(part.originMm).multiplyScalar(-.001); placement.add(visual); links[role].add(placement);
|
||||
}
|
||||
links.base.userData.linuxcncMachineGeometry = metadata;
|
||||
const signature = JSON.stringify({ metadata, hashes: MACHINE_PART_ROLES.map((role) => byRole.get(role)!.hash) });
|
||||
|
||||
Reference in New Issue
Block a user