Skip to content

Commit 4d110fb

Browse files
Eiderenxen2
authored andcommitted
fix: CharacterComponent handedness
1 parent edd099b commit 4d110fb

2 files changed

Lines changed: 15 additions & 13 deletions

File tree

sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/CharacterComponent.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,16 @@ public Vector3 Velocity
6363
set
6464
{
6565
_velocity = value;
66-
var inv = Quaternion.Invert(Orientation);
66+
67+
var inv = Quaternion.Invert(GlobalBasis);
6768
value = inv * value;
6869
MoveVector = new Vector2(value.X, value.Z) / Speed;
6970
}
7071
}
7172

7273
/// <summary>
7374
/// The current movement direction of this component, it is local to its <see cref="BodyComponent.Orientation"/>
75+
/// where +X is left, -X is right, +Y is forward and -Y is backward. This is similar to how the arrow Gizmo in the editor is laid out.
7476
/// </summary>
7577
/// <remarks>
7678
/// The input is scaled by <see cref="Speed"/> before usage<br/>
@@ -83,7 +85,7 @@ public Vector2 MoveVector
8385
set
8486
{
8587
field = value;
86-
_velocity = Orientation * new Vector3(value.X, 0, value.Y) * Speed;
88+
_velocity = GlobalBasis * new Vector3(value.X, 0, value.Y) * Speed;
8789
}
8890
}
8991

@@ -128,6 +130,8 @@ public bool IsJumping
128130
[DataMemberIgnore, Obsolete($"Contacts are no longer collected, add your own {nameof(ContactEventHandler)}")]
129131
public List<(CollidableComponent Source, Contact Contact)> Contacts { get; } = new();
130132

133+
private Quaternion GlobalBasis => Quaternion.LookRotation(Orientation * Vector3.UnitZ, Orientation * LocalUp);
134+
131135
public CharacterComponent()
132136
{
133137
InterpolationMode = InterpolationMode.Interpolated;
@@ -144,7 +148,7 @@ public CharacterComponent()
144148
public virtual void Move(Vector3 direction)
145149
{
146150
// Note that this method should be thread safe, see usage in RecastPhysicsNavigationProcessor
147-
var inv = Quaternion.Invert(Orientation);
151+
var inv = Quaternion.Invert(GlobalBasis);
148152
direction = inv * direction;
149153
MoveVector = new Vector2(direction.X, direction.Z);
150154
}
@@ -165,8 +169,6 @@ public virtual void TryJump()
165169
/// <inheritdoc/>
166170
protected override void SimulationUpdate(BepuSimulation sim, float simTimeStep, ref InternalCharacterData character, in BodyReference characterBody, out bool wakeupBody)
167171
{
168-
/*Entity.Transform.UpdateWorldMatrix();
169-
var viewDirection = (NVector3)Entity.Transform.WorldMatrix.Backward;*/
170172
var viewDirection = (NVector3)(Orientation * Vector3.UnitZ);
171173

172174
var newTargetVelocity = new System.Numerics.Vector2(MoveVector.X, MoveVector.Y) * Speed;
@@ -204,13 +206,13 @@ protected override void SimulationUpdate(BepuSimulation sim, float simTimeStep,
204206
if (!character.Supported && newTargetVelocity.LengthSquared() > 0)
205207
{
206208
QuaternionEx.Transform(character.LocalUp, characterBody.Pose.Orientation, out var characterUp);
207-
var characterRight = Vector3.Cross(character.ViewDirection, characterUp);
208-
var rightLengthSquared = characterRight.LengthSquared();
209+
var characterLeft = Vector3.Cross(characterUp, character.ViewDirection);
210+
var rightLengthSquared = characterLeft.LengthSquared();
209211
if (rightLengthSquared > 1e-10f)
210212
{
211-
characterRight /= MathF.Sqrt(rightLengthSquared);
212-
var characterForward = Vector3.Cross(characterUp, characterRight);
213-
var worldMovementDirection = characterRight * newTargetVelocity.X + characterForward * newTargetVelocity.Y;
213+
characterLeft /= MathF.Sqrt(rightLengthSquared);
214+
var characterForward = Vector3.Cross(characterLeft, characterUp);
215+
var worldMovementDirection = characterLeft * newTargetVelocity.X + characterForward * newTargetVelocity.Y;
214216
var currentVelocity = Vector3.Dot(characterBody.Velocity.Linear, worldMovementDirection);
215217
//We'll arbitrarily set air control to be a fraction of supported movement's speed/force.
216218
var airAccelerationDt = characterBody.LocalInertia.InverseMass * character.MaximumHorizontalForce * AirControlForceScale * simTimeStep;
@@ -219,7 +221,7 @@ protected override void SimulationUpdate(BepuSimulation sim, float simTimeStep,
219221
//While we shouldn't allow the character to continue accelerating in the air indefinitely, trying to move in a given direction should never slow us down in that direction.
220222
var velocityChangeAlongMovementDirection = MathF.Max(0, targetVelocity - currentVelocity);
221223
characterBody.Velocity.Linear += worldMovementDirection * velocityChangeAlongMovementDirection;
222-
Debug.Assert(characterBody.Awake, "Velocity changes don't automatically update objects; the character should have already been woken up before applying air control.");
224+
Debug.Assert(characterBody.Awake || wakeupBody, "Velocity changes don't automatically update objects; the character should have already been woken up before applying air control.");
223225
}
224226
}
225227
}

sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/Systems/Characters/CharacterMotionConstraint.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public static void Solve(in Vector3Wide positionA, in QuaternionWide orientation
239239
Symmetric2x2Wide.InvertWithoutOverlap(inverseHorizontalEffectiveMass, out var horizontalEffectiveMass);
240240

241241
Vector2Wide horizontalConstraintSpaceVelocityChange;
242-
horizontalConstraintSpaceVelocityChange.X = prestep.TargetVelocity.X - horizontalVelocity.X;
242+
horizontalConstraintSpaceVelocityChange.X = -prestep.TargetVelocity.X - horizontalVelocity.X;
243243
//The surface basis's Z axis points in the opposite direction to the view direction, so negate the target velocity along the Z axis to point it in the expected direction.
244244
horizontalConstraintSpaceVelocityChange.Y = -prestep.TargetVelocity.Y - horizontalVelocity.Y;
245245
Symmetric2x2Wide.TransformWithoutOverlap(horizontalConstraintSpaceVelocityChange, horizontalEffectiveMass, out var horizontalCorrectiveImpulse);
@@ -564,7 +564,7 @@ public static void Solve(in Vector3Wide positionA, in QuaternionWide orientation
564564
Symmetric2x2Wide.InvertWithoutOverlap(inverseHorizontalEffectiveMass, out var horizontalEffectiveMass);
565565

566566
Vector2Wide horizontalConstraintSpaceVelocityChange;
567-
horizontalConstraintSpaceVelocityChange.X = prestep.TargetVelocity.X - horizontalVelocity.X;
567+
horizontalConstraintSpaceVelocityChange.X = -prestep.TargetVelocity.X - horizontalVelocity.X;
568568
//The surface basis's Z axis points in the opposite direction to the view direction, so negate the target velocity along the Z axis to point it in the expected direction.
569569
horizontalConstraintSpaceVelocityChange.Y = -prestep.TargetVelocity.Y - horizontalVelocity.Y;
570570
Symmetric2x2Wide.TransformWithoutOverlap(horizontalConstraintSpaceVelocityChange, horizontalEffectiveMass, out var horizontalCorrectiveImpulse);

0 commit comments

Comments
 (0)