Fix the character rotation on moving platforms.

This commit is contained in:
Davy Hélard
2024-12-11 22:37:39 +01:00
parent da2de649ab
commit f7625194f5
2 changed files with 34 additions and 30 deletions

View File

@@ -957,6 +957,20 @@ namespace gdjs {
);
}
moveObjectToPhysicsRotation(physicsRotation: Jolt.Quat): void {
const threeObject = this.owner3D.get3DRendererObject();
threeObject.quaternion.x = physicsRotation.GetX();
threeObject.quaternion.y = physicsRotation.GetY();
threeObject.quaternion.z = physicsRotation.GetZ();
threeObject.quaternion.w = physicsRotation.GetW();
// TODO Avoid this instantiation
const euler = new THREE.Euler(0, 0, 0, 'ZYX');
euler.setFromQuaternion(threeObject.quaternion);
this.owner3D.setRotationX(gdjs.toDegrees(euler.x));
this.owner3D.setRotationY(gdjs.toDegrees(euler.y));
this.owner3D.setAngle(gdjs.toDegrees(euler.z));
}
getWorldScale(): float {
return this._sharedData.worldScale;
}
@@ -1810,7 +1824,7 @@ namespace gdjs {
updateObjectFromBody() {
const { behavior } = this;
const { owner3D, _body } = behavior;
const { _body } = behavior;
// Copy transform from body to the GD object.
// It's possible the behavior was either deactivated or the object deleted
// just before this doStepPreEvents (for example, another behavior deleted
@@ -1818,18 +1832,7 @@ namespace gdjs {
// don't do anything (but still run the physics simulation - this is independent).
if (_body !== null) {
behavior.moveObjectToPhysicsPosition(_body.GetPosition());
const quaternion = _body.GetRotation();
const threeObject = owner3D.get3DRendererObject();
threeObject.quaternion.x = quaternion.GetX();
threeObject.quaternion.y = quaternion.GetY();
threeObject.quaternion.z = quaternion.GetZ();
threeObject.quaternion.w = quaternion.GetW();
const euler = new THREE.Euler(0, 0, 0, 'ZYX');
euler.setFromQuaternion(threeObject.quaternion);
owner3D.setRotationX(gdjs.toDegrees(euler.x));
owner3D.setRotationY(gdjs.toDegrees(euler.y));
owner3D.setAngle(gdjs.toDegrees(euler.z));
behavior.moveObjectToPhysicsRotation(_body.GetRotation());
}
}

View File

@@ -701,23 +701,21 @@ namespace gdjs {
const groundAngularVelocityZ = groundBody.GetAngularVelocity().GetZ();
if (groundAngularVelocityZ !== 0) {
// Make the character rotate with the platform on Z axis.
const rotation = Jolt.Quat.prototype.sEulerAngles(
this.getVec3(
0,
0,
characterBody
.GetRotation()
.GetRotationAngle(Jolt.Vec3.prototype.sAxisZ()) +
groundAngularVelocityZ * timeDelta
const angleDelta = groundAngularVelocityZ * timeDelta;
this.character.SetRotation(
Jolt.Quat.prototype.sEulerAngles(
this.getVec3(
0,
0,
this.character
.GetRotation()
.GetRotationAngle(Jolt.Vec3.prototype.sAxisZ()) + angleDelta
)
)
);
// TODO Should the character be used instead of the body directly?
this._sharedData.bodyInterface.SetPositionAndRotation(
characterBody.GetID(),
this.getPhysicsPosition(this.getRVec3(0, 0, 0)),
rotation,
Jolt.EActivation_Activate
);
// Also update the forward angle to make sure it stays the same
// relatively to the object angle.
this._forwardAngle += gdjs.toDegrees(angleDelta);
}
if (stillKinematicPlatform) {
groundBody.SetLinearVelocity(Jolt.Vec3.prototype.sZero());
@@ -1345,6 +1343,7 @@ namespace gdjs {
}
updateObjectFromBody() {
const { behavior } = this.characterBehavior.getPhysics3D();
const { character } = this.characterBehavior;
if (!character) {
return;
@@ -1353,7 +1352,8 @@ namespace gdjs {
this.characterBehavior.moveObjectToPhysicsPosition(
character.GetPosition()
);
// No need to update the rotation as CharacterVirtual doesn't change it.
// TODO No need to update the rotation for X and Y as CharacterVirtual doesn't change it.
behavior.moveObjectToPhysicsRotation(character.GetRotation());
}
updateBodyFromObject() {
@@ -1374,7 +1374,8 @@ namespace gdjs {
behavior._objectOldRotationY !== owner3D.getRotationY() ||
behavior._objectOldRotationZ !== owner3D.getAngle()
) {
behavior.getPhysicsRotation(
// TODO No need to update the rotation for X and Y as CharacterVirtual doesn't change it.
character.SetRotation(
behavior.getPhysicsRotation(_sharedData.getQuat(0, 0, 0, 1))
);
}