Skip to content

Commit

Permalink
backport [ff-three Smithsonian#3](Smithsonian/ff-three#3) in merged s…
Browse files Browse the repository at this point in the history
…ubmodules code
  • Loading branch information
sdumetz committed Aug 1, 2024
1 parent ebbda0b commit 1f85002
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 8 deletions.
41 changes: 33 additions & 8 deletions libs/ff-three/source/CameraController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import {
Vector3,
Matrix4,
Box3,
Spherical,
Euler,
Quaternion,
} from "three";

import math from "@ff/core/math";
Expand All @@ -30,6 +33,9 @@ const _mat4 = new Matrix4();
const _box3 = new Box3();
const _vec3a = new Vector3();
const _vec3b = new Vector3();
const _vec3c = new Vector3();
const _eua = new Euler();
const _quat = new Quaternion();

enum EControllerMode { Orbit, FirstPerson }
enum EManipMode { Off, Pan, Orbit, Dolly, Zoom, PanDolly, Roll }
Expand All @@ -42,6 +48,7 @@ export default class CameraController implements IManip

orbit = new Vector3(0, 0, 0);
offset = new Vector3(0, 0, 50);
pivot = new Vector3(0, 0, 0);

minOrbit = new Vector3(-90, -Infinity, -Infinity);
maxOrbit = new Vector3(90, Infinity, Infinity);
Expand Down Expand Up @@ -146,15 +153,22 @@ export default class CameraController implements IManip
this.viewportHeight = height;
}

/**
* Copy the object's matrix into the controller's properties
* effectively the inverse operation of updateCamera
*/
updateController(object?: Object3D, adaptLimits?: boolean)
{
const camera = this.camera;
object = object || camera;

const orbit = this.orbit;
const offset = this.offset;
threeMath.decomposeOrbitMatrix(object.matrix, orbit, offset);
this.orbit.multiplyScalar(threeMath.RAD2DEG);
object.matrix.decompose(_vec3b, _quat, _vec3c);
//Rotation
_eua.setFromQuaternion(_quat, "YXZ");
_vec3a.setFromEuler(_eua).multiplyScalar(threeMath.RAD2DEG);
this.orbit.copy(_vec3a);
this.offset.copy(_vec3b.sub(this.pivot).applyQuaternion(_quat.invert()));

if (adaptLimits) {
this.minOffset.min(offset);
Expand All @@ -179,12 +193,16 @@ export default class CameraController implements IManip

// rotate box to camera space
_vec3a.copy(this.orbit).multiplyScalar(math.DEG2RAD);
_quat.setFromEuler(_eua.setFromVector3(_vec3a));
_vec3b.setScalar(0);
threeMath.composeOrbitMatrix(_vec3a, _vec3b, _mat4);
_vec3c.setScalar(1);
//Ignore the pivot point for now
_mat4.compose(_vec3b, _quat, _vec3c);

_box3.copy(box).applyMatrix4(_mat4.transpose());
_box3.getSize(_vec3a);
_box3.getCenter(_vec3b);
_vec3b.sub(this.pivot);

offset.x = _vec3b.x;
offset.y = _vec3b.y;
Expand Down Expand Up @@ -221,7 +239,17 @@ export default class CameraController implements IManip
}

_vec3a.copy(this.orbit).multiplyScalar(math.DEG2RAD);
_vec3b.copy(this.offset);
_eua.setFromVector3(_vec3a, "YXZ");
_quat.setFromEuler(_eua);
//Position, relative to pivot point
_vec3b.copy(this.offset).applyEuler(_eua).add(this.pivot);
//Keep scale
_vec3c.setFromMatrixScale(object.matrix);
//Compose everything
object.matrix.compose(_vec3b, _quat, _vec3c);


object.matrixWorldNeedsUpdate = true;

if (camera.isOrthographicCamera) {
_vec3b.z = this.maxOffset.z; // fixed distance = maxOffset.z
Expand All @@ -230,9 +258,6 @@ export default class CameraController implements IManip
camera.updateProjectionMatrix();
}

threeMath.composeOrbitMatrix(_vec3a, _vec3b, object.matrix);
object.matrixWorldNeedsUpdate = true;

return true;
}

Expand Down
3 changes: 3 additions & 0 deletions libs/ff-three/source/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const math = {
DEG2RAD: 0.01745329251994329576923690768489,
RAD2DEG: 57.295779513082320876798154814105,

/**
* one-step orbit matrix composition when the pivot point is (0, 0, 0).
*/
composeOrbitMatrix: function(orientation: Vector3, offset: Vector3, result?: Matrix4): Matrix4
{
const pitch = orientation.x;
Expand Down

0 comments on commit 1f85002

Please sign in to comment.