From 53a53a8f3fca980732fb3f2f90d7e9add52cf8d9 Mon Sep 17 00:00:00 2001 From: Amp Date: Fri, 21 Aug 2026 11:56:42 +0000 Subject: [PATCH] Fix arc camera controls Amp-Thread-ID: https://ampcode.com/threads/T-01a02421-6802-705a-bc0d-f0745c5902b9 Co-authored-by: Heaust Azure --- addons/handles/src/camera/ArcRotateCamera.ts | 12 ++++++++++-- addons/handles/src/camera/Camera.ts | 14 ++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/addons/handles/src/camera/ArcRotateCamera.ts b/addons/handles/src/camera/ArcRotateCamera.ts index e5e1835..6d91355 100644 --- a/addons/handles/src/camera/ArcRotateCamera.ts +++ b/addons/handles/src/camera/ArcRotateCamera.ts @@ -144,8 +144,16 @@ export class ArcRotateCamera extends Camera { if (this.#pointer.button === 2) { const row = this.cameraRow(); this.#updateTransform(() => { - row[16] -= x * (this.#controls?.panSpeed ?? 0.005); - row[17] += y * (this.#controls?.panSpeed ?? 0.005); + const speed = this.#controls?.panSpeed ?? 0.005; + const horizontal = -x * speed; + const vertical = y * speed; + const sinAlpha = Math.sin(row[13]); + const cosAlpha = Math.cos(row[13]); + const sinBeta = Math.sin(row[14]); + const cosBeta = Math.cos(row[14]); + row[16] += horizontal * cosAlpha - vertical * cosBeta * sinAlpha; + row[17] += vertical * sinBeta; + row[18] -= horizontal * sinAlpha + vertical * cosBeta * cosAlpha; }); } else { const speed = this.#controls.orbitSpeed ?? 0.005; diff --git a/addons/handles/src/camera/Camera.ts b/addons/handles/src/camera/Camera.ts index 501cbe5..158a906 100644 --- a/addons/handles/src/camera/Camera.ts +++ b/addons/handles/src/camera/Camera.ts @@ -100,12 +100,14 @@ export class Camera extends Node { const z = target[2] - position.z; const length = Math.hypot(x, y, z) || 1; const direction = [x / length, y / length, z / length]; - if (direction[2] > 0.999999) this.setRotor([0, 1, 0, 0]); - else { - const rotor = [direction[1], -direction[0], 0, 1 - direction[2]]; - const rotorLength = Math.hypot(...rotor); - this.setRotor(rotor.map((lane) => lane / rotorLength)); - } + const horizontal = Math.hypot(direction[0], direction[2]); + const yaw = horizontal > 0.000001 + ? Math.atan2(-direction[0], -direction[2]) + : 0; + const pitch = Math.atan2(direction[1], horizontal); + const sy = Math.sin(yaw / 2), cy = Math.cos(yaw / 2); + const sx = Math.sin(pitch / 2), cx = Math.cos(pitch / 2); + this.setRotor([sx * cy, cx * sy, -sx * sy, cx * cy]); return this; }