Skip to content

Commit 408f770

Browse files
committed
RH camera fixes
1 parent 5e04d30 commit 408f770

File tree

4 files changed

+40
-58
lines changed

4 files changed

+40
-58
lines changed

packages/dev/core/src/Cameras/arcRotateCamera.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1394,7 +1394,7 @@ export class ArcRotateCamera extends TargetCamera {
13941394
this._viewMatrix.addAtIndex(12, this.targetScreenOffset.x);
13951395
this._viewMatrix.addAtIndex(13, this.targetScreenOffset.y);
13961396
}
1397-
this._currentTarget = target;
1397+
this._currentTarget.copyFrom(target);
13981398
return this._viewMatrix;
13991399
}
14001400

packages/dev/core/src/Cameras/targetCamera.ts

Lines changed: 33 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ Node.AddNodeConstructor("TargetCamera", (name, scene) => {
1212
return () => new TargetCamera(name, Vector3.Zero(), scene);
1313
});
1414

15+
// Temporary cache variables to avoid allocations.
16+
const TmpMatrix = Matrix.Zero();
17+
const TmpQuaternion = Quaternion.Identity();
18+
1519
/**
1620
* A target camera takes a mesh or position as a target and continues to look at it while it moves.
1721
* This is the base of the follow, arc rotate cameras and Free camera
@@ -36,13 +40,12 @@ export class TargetCamera extends Camera {
3640
*/
3741
@serialize()
3842
public updateUpVectorFromRotation = false;
39-
private _tmpQuaternion = new Quaternion();
4043

4144
/**
4245
* Define the current rotation of the camera
4346
*/
4447
@serializeAsVector3()
45-
public rotation = new Vector3(0, 0, 0);
48+
public rotation: Vector3;
4649

4750
/**
4851
* Define the current rotation of the camera as a quaternion to prevent Gimbal lock
@@ -79,35 +82,27 @@ export class TargetCamera extends Camera {
7982
@serializeAsMeshReference("lockedTargetId")
8083
public lockedTarget: any = null;
8184

82-
/** @internal */
83-
public _currentTarget = Vector3.Zero();
84-
/** @internal */
85-
public _initialFocalDistance = 1;
86-
/** @internal */
87-
public _viewMatrix = Matrix.Zero();
88-
/** @internal */
89-
public _camMatrix = Matrix.Zero();
90-
/** @internal */
91-
public _cameraTransformMatrix = Matrix.Zero();
92-
/** @internal */
93-
public _cameraRotationMatrix = Matrix.Zero();
85+
protected readonly _currentTarget = Vector3.Zero();
86+
protected _initialFocalDistance = 1;
87+
protected readonly _viewMatrix = Matrix.Zero();
9488

9589
/** @internal */
96-
public _referencePoint = new Vector3(0, 0, 1);
90+
public readonly _cameraTransformMatrix = Matrix.Zero();
9791
/** @internal */
98-
public _transformedReferencePoint = Vector3.Zero();
92+
public readonly _cameraRotationMatrix = Matrix.Zero();
93+
94+
protected readonly _referencePoint: Vector3;
95+
protected readonly _transformedReferencePoint = Vector3.Zero();
9996

100-
protected _deferredPositionUpdate = new Vector3();
101-
protected _deferredRotationQuaternionUpdate = new Quaternion();
102-
protected _deferredRotationUpdate = new Vector3();
97+
protected readonly _deferredPositionUpdate = new Vector3();
98+
protected readonly _deferredRotationQuaternionUpdate = new Quaternion();
99+
protected readonly _deferredRotationUpdate = new Vector3();
103100
protected _deferredUpdated = false;
104101
protected _deferOnly: boolean = false;
105102

106103
/** @internal */
107104
public _reset: () => void;
108105

109-
private _defaultUp = Vector3.Up();
110-
111106
/**
112107
* Instantiates a target camera that takes a mesh or position as a target and continues to look at it while it moves.
113108
* This is the base of the follow, arc rotate cameras and Free camera
@@ -119,6 +114,11 @@ export class TargetCamera extends Camera {
119114
*/
120115
constructor(name: string, position: Vector3, scene?: Scene, setActiveOnSceneIfNoneActive = true) {
121116
super(name, position, scene, setActiveOnSceneIfNoneActive);
117+
118+
this._referencePoint = Vector3.Forward(this.getScene().useRightHandedSystem);
119+
120+
// Set the y component of the rotation to Math.PI in right-handed system for backwards compatibility.
121+
this.rotation = new Vector3(0, this.getScene().useRightHandedSystem ? Math.PI : 0, 0);
122122
}
123123

124124
/**
@@ -255,6 +255,7 @@ export class TargetCamera extends Camera {
255255
* @param target Defines the new target as a Vector
256256
*/
257257
public setTarget(target: Vector3): void {
258+
// REVIEW: why is this here?
258259
this.upVector.normalize();
259260

260261
this._initialFocalDistance = target.subtract(this.position).length();
@@ -263,38 +264,19 @@ export class TargetCamera extends Camera {
263264
this.position.z += Epsilon;
264265
}
265266

266-
this._referencePoint.normalize().scaleInPlace(this._initialFocalDistance);
267-
268-
Matrix.LookAtLHToRef(this.position, target, this._defaultUp, this._camMatrix);
269-
this._camMatrix.invert();
267+
this._referencePoint.scaleInPlace(this._initialFocalDistance);
270268

271-
this.rotation.x = Math.atan(this._camMatrix.m[6] / this._camMatrix.m[10]);
272-
273-
const vDir = target.subtract(this.position);
274-
275-
if (vDir.x >= 0.0) {
276-
this.rotation.y = -Math.atan(vDir.z / vDir.x) + Math.PI / 2.0;
269+
if (this.getScene().useRightHandedSystem) {
270+
Matrix.LookAtRHToRef(this.position, target, Vector3.UpReadOnly, TmpMatrix);
277271
} else {
278-
this.rotation.y = -Math.atan(vDir.z / vDir.x) - Math.PI / 2.0;
272+
Matrix.LookAtLHToRef(this.position, target, Vector3.UpReadOnly, TmpMatrix);
279273
}
274+
TmpMatrix.invert();
280275

281-
this.rotation.z = 0;
276+
const rotationQuaternion = this.rotationQuaternion || TmpQuaternion;
277+
Quaternion.FromRotationMatrixToRef(TmpMatrix, rotationQuaternion);
282278

283-
if (isNaN(this.rotation.x)) {
284-
this.rotation.x = 0;
285-
}
286-
287-
if (isNaN(this.rotation.y)) {
288-
this.rotation.y = 0;
289-
}
290-
291-
if (isNaN(this.rotation.z)) {
292-
this.rotation.z = 0;
293-
}
294-
295-
if (this.rotationQuaternion) {
296-
Quaternion.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this.rotationQuaternion);
297-
}
279+
rotationQuaternion.toEulerAnglesToRef(this.rotation);
298280
}
299281

300282
/**
@@ -450,7 +432,7 @@ export class TargetCamera extends Camera {
450432
* @returns the current camera
451433
*/
452434
private _rotateUpVectorWithCameraRotationMatrix(): TargetCamera {
453-
Vector3.TransformNormalToRef(this._defaultUp, this._cameraRotationMatrix, this.upVector);
435+
Vector3.TransformNormalToRef(Vector3.UpReadOnly, this._cameraRotationMatrix, this.upVector);
454436
return this;
455437
}
456438

@@ -482,8 +464,8 @@ export class TargetCamera extends Camera {
482464
if (this.rotationQuaternion) {
483465
Axis.Y.rotateByQuaternionToRef(this.rotationQuaternion, this.upVector);
484466
} else {
485-
Quaternion.FromEulerVectorToRef(this.rotation, this._tmpQuaternion);
486-
Axis.Y.rotateByQuaternionToRef(this._tmpQuaternion, this.upVector);
467+
Quaternion.FromEulerVectorToRef(this.rotation, TmpQuaternion);
468+
Axis.Y.rotateByQuaternionToRef(TmpQuaternion, this.upVector);
487469
}
488470
}
489471
this._computeViewMatrix(this.position, this._currentTarget, this.upVector);

packages/dev/loaders/src/glTF/2.0/glTFLoader.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,8 +1569,8 @@ export class GLTFLoader implements IGLTFLoader {
15691569
this._babylonScene._blockEntityCollection = false;
15701570
camera._babylonCamera = babylonCamera;
15711571

1572-
// Rotation by 180 as glTF has a different convention than Babylon.
1573-
babylonCamera.rotation.set(0, Math.PI, 0);
1572+
// glTF cameras look towards the local -Z axis.
1573+
babylonCamera.setTarget(new Vector3(0, 0, -1));
15741574

15751575
switch (camera.type) {
15761576
case CameraType.PERSPECTIVE: {

packages/tools/tests/test/visualization/config.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,25 +1055,25 @@
10551055
},
10561056
{
10571057
"title": "GLTF Serializer Camera, left-handed",
1058-
"playgroundId": "#O0M0J9#8",
1058+
"playgroundId": "#O0M0J9#20",
10591059
"replace": "//options//, roundtripCount = 1; useRightHandedSystem = false;",
10601060
"referenceImage": "glTFSerializerCameraLeftHand.png"
10611061
},
10621062
{
10631063
"title": "GLTF Serializer Camera, right-handed",
1064-
"playgroundId": "#O0M0J9#8",
1064+
"playgroundId": "#O0M0J9#20",
10651065
"replace": "//options//, roundtripCount = 1; useRightHandedSystem = true;",
10661066
"referenceImage": "glTFSerializerCameraRightHand.png"
10671067
},
10681068
{
10691069
"title": "GLTF Serializer Camera, left-handed, round trip twice",
1070-
"playgroundId": "#O0M0J9#8",
1070+
"playgroundId": "#O0M0J9#20",
10711071
"replace": "//options//, roundtripCount = 2; useRightHandedSystem = false;",
10721072
"referenceImage": "glTFSerializerCameraLeftHand.png"
10731073
},
10741074
{
10751075
"title": "GLTF Serializer Camera, right-handed, round trip twice",
1076-
"playgroundId": "#O0M0J9#8",
1076+
"playgroundId": "#O0M0J9#20",
10771077
"replace": "//options//, roundtripCount = 2; useRightHandedSystem = true;",
10781078
"referenceImage": "glTFSerializerCameraRightHand.png"
10791079
},

0 commit comments

Comments
 (0)