diff --git a/packages/core/src/physics/joint/HingeJoint.ts b/packages/core/src/physics/joint/HingeJoint.ts index 31054b52f1..99fe911bb6 100644 --- a/packages/core/src/physics/joint/HingeJoint.ts +++ b/packages/core/src/physics/joint/HingeJoint.ts @@ -25,7 +25,7 @@ export class HingeJoint extends Joint { private _velocity = 0; /** - * The anchor rotation. + * The Direction of the axis around which the hingeJoint. */ get axis(): Vector3 { return this._axis; @@ -35,7 +35,6 @@ export class HingeJoint extends Joint { const axis = this._axis; if (value !== axis) { axis.copyFrom(value); - (this._nativeJoint)?.setAxis(axis); } } @@ -143,6 +142,9 @@ export class HingeJoint extends Joint { super(entity); this._onMotorChanged = this._onMotorChanged.bind(this); this._onLimitsChanged = this._onLimitsChanged.bind(this); + this._onAxisChanged = this._onAxisChanged.bind(this); + //@ts-ignore + this._axis._onValueChanged = this._onAxisChanged; } /** @@ -197,4 +199,14 @@ export class HingeJoint extends Joint { } } } + + @ignoreClone + private _onAxisChanged(): void { + //@ts-ignore + this._axis._onValueChanged = null; + this._axis.normalize(); + (this._nativeJoint)?.setAxis(this._axis); + //@ts-ignore + this._axis._onValueChanged = this._onAxisChanged; + } } diff --git a/packages/core/src/physics/joint/Joint.ts b/packages/core/src/physics/joint/Joint.ts index fbc9c3f4f7..ae7d90b866 100644 --- a/packages/core/src/physics/joint/Joint.ts +++ b/packages/core/src/physics/joint/Joint.ts @@ -25,8 +25,6 @@ export abstract class Joint extends Component { private _force = Infinity; private _torque = Infinity; private _automaticConnectedAnchor = true; - @ignoreClone - private _updateConnectedActualAnchor: Function; /** * The connected collider. @@ -72,26 +70,13 @@ export abstract class Joint extends Component { * The connectedAnchor is automatically calculated, if you want to set it manually, please set automaticConnectedAnchor to false */ get connectedAnchor(): Vector3 { - const connectedColliderAnchor = this._connectedColliderInfo.anchor; - if (this._automaticConnectedAnchor) { - //@ts-ignore - connectedColliderAnchor._onValueChanged = null; - this._calculateConnectedAnchor(); - //@ts-ignore - connectedColliderAnchor._onValueChanged = this._updateConnectedActualAnchor; - } - return connectedColliderAnchor; + return this._connectedColliderInfo.anchor; } set connectedAnchor(value: Vector3) { - if (this._automaticConnectedAnchor) { - console.warn("Cannot set connectedAnchor when automaticConnectedAnchor is true."); - return; - } const connectedAnchor = this._connectedColliderInfo.anchor; if (value !== connectedAnchor) { connectedAnchor.copyFrom(value); - this._updateActualAnchor(AnchorOwner.Connected); } } @@ -195,9 +180,9 @@ export abstract class Joint extends Component { super(entity); //@ts-ignore this._colliderInfo.anchor._onValueChanged = this._updateActualAnchor.bind(this, AnchorOwner.Self); - this._updateConnectedActualAnchor = this._updateActualAnchor.bind(this, AnchorOwner.Connected); + this._handleConnectedAnchorChanged = this._handleConnectedAnchorChanged.bind(this); //@ts-ignore - this._connectedColliderInfo.anchor._onValueChanged = this._updateConnectedActualAnchor; + this._connectedColliderInfo.anchor._onValueChanged = this._handleConnectedAnchorChanged.bind(this); this._onSelfTransformChanged = this._onSelfTransformChanged.bind(this); this._onConnectedTransformChanged = this._onConnectedTransformChanged.bind(this); @@ -250,6 +235,8 @@ export abstract class Joint extends Component { const connectedActualAnchor = connectedColliderInfo.actualAnchor; const connectedCollider = connectedColliderInfo.collider; + // @ts-ignore + connectedAnchor._onValueChanged = null; if (connectedCollider) { const { worldPosition: connectedPos, lossyWorldScale: connectedWorldScale } = connectedCollider.entity.transform; Vector3.subtract(selfPos, connectedPos, Joint._tempVector3); @@ -259,6 +246,18 @@ export abstract class Joint extends Component { Vector3.add(selfPos, selfActualAnchor, connectedActualAnchor); connectedAnchor.copyFrom(connectedActualAnchor); } + // @ts-ignore + connectedAnchor._onValueChanged = this._handleConnectedAnchorChanged; + this._updateActualAnchor(AnchorOwner.Connected); + } + + @ignoreClone + private _handleConnectedAnchorChanged(): void { + if (this._automaticConnectedAnchor) { + console.warn("Cannot set connectedAnchor when automaticConnectedAnchor is true."); + } else { + this._updateActualAnchor(AnchorOwner.Connected); + } } @ignoreClone diff --git a/packages/physics-physx/src/joint/PhysXHingeJoint.ts b/packages/physics-physx/src/joint/PhysXHingeJoint.ts index 7addf168dc..77f71edc8a 100644 --- a/packages/physics-physx/src/joint/PhysXHingeJoint.ts +++ b/packages/physics-physx/src/joint/PhysXHingeJoint.ts @@ -34,7 +34,6 @@ export class PhysXHingeJoint extends PhysXJoint implements IHingeJoint { const xAxis = PhysXHingeJoint._xAxis; const axisRotationQuaternion = this._axisRotationQuaternion; xAxis.set(1, 0, 0); - value.normalize(); const angle = Math.acos(Vector3.dot(xAxis, value)); Vector3.cross(xAxis, value, xAxis); Quaternion.rotationAxisAngle(xAxis, angle, axisRotationQuaternion); diff --git a/tests/src/core/physics/HingeJoint.test.ts b/tests/src/core/physics/HingeJoint.test.ts index d6f1ad12d8..4e55ab8e14 100644 --- a/tests/src/core/physics/HingeJoint.test.ts +++ b/tests/src/core/physics/HingeJoint.test.ts @@ -60,8 +60,8 @@ describe("HingeJoint", function () { joint.automaticConnectedAnchor = true; joint.connectedCollider = boxEntity2.getComponent(DynamicCollider); joint.anchor = new Vector3(0.5, 0, 0); - joint.axis = new Vector3(0, 1, 0); - + joint.axis.x = 0; + joint.axis.y = 1; expect(formatValue(joint.angle)).eq(0); collider2.applyTorque(new Vector3(0, 1000, 0)); diff --git a/tests/src/core/physics/Joint.test.ts b/tests/src/core/physics/Joint.test.ts index 0d5c59c4f5..e6746fec91 100644 --- a/tests/src/core/physics/Joint.test.ts +++ b/tests/src/core/physics/Joint.test.ts @@ -95,6 +95,11 @@ describe("Joint", function () { joint.automaticConnectedAnchor = true; joint.connectedAnchor = new Vector3(1, 1, 1); expect(consoleWarnSpy).toBeCalledTimes(1); + joint.connectedAnchor.y = 3; + expect(consoleWarnSpy).toBeCalledTimes(2); + joint.automaticConnectedAnchor = false; + joint.automaticConnectedAnchor = true; + expect(joint.connectedAnchor).deep.include({ x: 4, y: 4, z: 4 }); // @ts-ignore engine.sceneManager.activeScene.physics._update(1 / 60);