torque
This commit is contained in:
@@ -13,6 +13,11 @@ public class MovementComponent : Engine.Scene.Component.Component
|
||||
/// </summary>
|
||||
public float Speed { get; set; } = 10.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The rotation speed in degrees per second.
|
||||
/// </summary>
|
||||
public float RotationSpeed { get; set; } = 90.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The rigidbody component for the game object.
|
||||
/// </summary>
|
||||
@@ -40,4 +45,14 @@ public class MovementComponent : Engine.Scene.Component.Component
|
||||
{
|
||||
_rigidbody.Force += _dragComponent.Drag * Speed * parDirection.Normalized();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies rotational torque to the object around a specified axis.
|
||||
/// </summary>
|
||||
/// <param name="parAxis">The axis of rotation.</param>
|
||||
public void ApplyRotation(Vector3 parAxis)
|
||||
{
|
||||
var radiansPerSecond = MathHelper.DegreesToRadians(RotationSpeed);
|
||||
_rigidbody.Torque += _dragComponent.RotationalDrag * radiansPerSecond * parAxis.Normalized();
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,21 @@ public class DragComponent : Engine.Scene.Component.Component
|
||||
/// </summary>
|
||||
public float Drag { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// The rotational drag coefficient applied to the angular velocity of the rigidbody.
|
||||
/// </summary>
|
||||
public float RotationalDrag { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// A multiplier applied to each axis of the velocity when calculating drag.
|
||||
/// </summary>
|
||||
public Vector3 Multiplier { get; set; } = Vector3.One;
|
||||
|
||||
/// <summary>
|
||||
/// A multiplier applied to each axis of the angular velocity when calculating rotational drag.
|
||||
/// </summary>
|
||||
public Vector3 RotationalMultiplier { get; set; } = Vector3.One;
|
||||
|
||||
/// <summary>
|
||||
/// The rigidbody to apply drag to.
|
||||
/// </summary>
|
||||
@@ -31,6 +41,12 @@ public class DragComponent : Engine.Scene.Component.Component
|
||||
|
||||
public override void Update(double parDeltaTime)
|
||||
{
|
||||
if (_rigidbody.IsStatic)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_rigidbody.Force -= Drag * (_rigidbody.Velocity * Multiplier);
|
||||
_rigidbody.Torque -= RotationalDrag * (_rigidbody.AngularVelocity * RotationalMultiplier);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,12 @@ public class RigidbodyComponent : Engine.Scene.Component.Component
|
||||
/// </summary>
|
||||
public float Mass { get; set; } = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The moment of inertia of the rigidbody.
|
||||
/// For simplicity, this assumes a scalar value, suitable for symmetric objects.
|
||||
/// </summary>
|
||||
public float MomentOfInertia { get; set; } = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the rigidbody is static and unaffected by forces.
|
||||
/// </summary>
|
||||
@@ -34,6 +40,23 @@ public class RigidbodyComponent : Engine.Scene.Component.Component
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The torque currently applied to the rigidbody.
|
||||
/// </summary>
|
||||
public Vector3 Torque
|
||||
{
|
||||
get => _torque;
|
||||
set
|
||||
{
|
||||
if (IsStatic)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_torque = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The velocity of the rigidbody.
|
||||
/// </summary>
|
||||
@@ -51,6 +74,23 @@ public class RigidbodyComponent : Engine.Scene.Component.Component
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The angular velocity of the rigidbody.
|
||||
/// </summary>
|
||||
public Vector3 AngularVelocity
|
||||
{
|
||||
get => _angularVelocity;
|
||||
set
|
||||
{
|
||||
if (IsStatic)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_angularVelocity = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The force currently applied to the rigidbody.
|
||||
/// </summary>
|
||||
@@ -66,6 +106,21 @@ public class RigidbodyComponent : Engine.Scene.Component.Component
|
||||
/// </summary>
|
||||
private Vector3 _velocity = Vector3.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The torque currently applied to the rigidbody.
|
||||
/// </summary>
|
||||
private Vector3 _torque = Vector3.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The angular acceleration of the rigidbody.
|
||||
/// </summary>
|
||||
private Vector3 _angularAcceleration = Vector3.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The angular velocity of the rigidbody.
|
||||
/// </summary>
|
||||
private Vector3 _angularVelocity = Vector3.Zero;
|
||||
|
||||
public override void PostUpdate(double parDeltaTime)
|
||||
{
|
||||
if (IsStatic)
|
||||
@@ -73,10 +128,43 @@ public class RigidbodyComponent : Engine.Scene.Component.Component
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyForce(parDeltaTime);
|
||||
ApplyTorque(parDeltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies force to the rigidbody.
|
||||
/// </summary>
|
||||
/// <param name="parDeltaTime">The time in seconds since the last update.</param>
|
||||
private void ApplyForce(double parDeltaTime)
|
||||
{
|
||||
_acceleration = Force / Mass;
|
||||
Velocity += _acceleration * (float)parDeltaTime;
|
||||
GameObject.Transform.Translation += Velocity * (float)parDeltaTime;
|
||||
|
||||
Force = Vector3.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies torque to the rigidbody.
|
||||
/// </summary>
|
||||
/// <param name="parDeltaTime">The time in seconds since the last update.</param>
|
||||
private void ApplyTorque(double parDeltaTime)
|
||||
{
|
||||
_angularAcceleration = Torque / MomentOfInertia;
|
||||
AngularVelocity += _angularAcceleration * (float)parDeltaTime;
|
||||
|
||||
// Update rotation using quaternion math
|
||||
var rotation = GameObject.Transform.Rotation;
|
||||
var angularVelocityQuat = new Quaternion(AngularVelocity, 0.0f);
|
||||
|
||||
// Quaternion rotation integration: Δq = 0.5 * angularVelocityQuat * rotation
|
||||
var deltaRotation = 0.5f * angularVelocityQuat * rotation;
|
||||
rotation += deltaRotation * (float)parDeltaTime;
|
||||
rotation.Normalize(); // Ensure the quaternion remains normalized
|
||||
|
||||
GameObject.Transform.Rotation = rotation;
|
||||
|
||||
Torque = Vector3.Zero;
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,6 @@ namespace DoomDeathmatch.Component.Util;
|
||||
/// </summary>
|
||||
public class PlayerMovementComponent : Engine.Scene.Component.Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The speed at which the player rotates in degrees per second.
|
||||
/// </summary>
|
||||
public float RotationSpeed { get; set; } = 110.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Handles input from the player.
|
||||
/// </summary>
|
||||
@@ -35,7 +30,7 @@ public class PlayerMovementComponent : Engine.Scene.Component.Component
|
||||
public override void Update(double parDeltaTime)
|
||||
{
|
||||
var movement = Vector3.Zero;
|
||||
var rotation = 0.0f;
|
||||
var rotation = 0;
|
||||
|
||||
if (_inputHandler.IsKeyPressed(KeyboardButtonCode.W))
|
||||
{
|
||||
@@ -59,12 +54,12 @@ public class PlayerMovementComponent : Engine.Scene.Component.Component
|
||||
|
||||
if (_inputHandler.IsKeyPressed(KeyboardButtonCode.Q))
|
||||
{
|
||||
rotation += RotationSpeed;
|
||||
rotation = 1;
|
||||
}
|
||||
|
||||
if (_inputHandler.IsKeyPressed(KeyboardButtonCode.E))
|
||||
{
|
||||
rotation -= RotationSpeed;
|
||||
rotation = -1;
|
||||
}
|
||||
|
||||
if (movement.LengthSquared > 0)
|
||||
@@ -75,7 +70,9 @@ public class PlayerMovementComponent : Engine.Scene.Component.Component
|
||||
_movementComponent.ApplyMovement(movement);
|
||||
}
|
||||
|
||||
GameObject.Transform.Rotation *= Quaternion.FromAxisAngle(Vector3.UnitZ, MathHelper.DegreesToRadians(rotation) *
|
||||
(float)parDeltaTime);
|
||||
if (rotation != 0)
|
||||
{
|
||||
_movementComponent.ApplyRotation(Vector3.UnitZ * rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ public static class PlayerPrefab
|
||||
perspectiveCameraObject.Transform.Translation.Z = 2;
|
||||
var playerObject = GameObjectUtil.CreateGameObject(parScene, [
|
||||
new RigidbodyComponent(),
|
||||
new DragComponent { Drag = 10f, Multiplier = new Vector3(1, 1, 0) },
|
||||
new DragComponent { Drag = 10f, RotationalDrag = 10f, },
|
||||
|
||||
new AABBColliderComponent
|
||||
{
|
||||
@@ -29,8 +29,11 @@ public static class PlayerPrefab
|
||||
ExcludeColliderCollideGroups = { "player" }
|
||||
},
|
||||
|
||||
new MovementComponent { Speed = GameConstants.PLAYER_BASE_SPEED },
|
||||
new PlayerMovementComponent { RotationSpeed = GameConstants.PLAYER_BASE_ROTATION_SPEED },
|
||||
new MovementComponent
|
||||
{
|
||||
Speed = GameConstants.PLAYER_BASE_SPEED, RotationSpeed = GameConstants.PLAYER_BASE_ROTATION_SPEED
|
||||
},
|
||||
new PlayerMovementComponent(),
|
||||
|
||||
new PlayerController(perspectiveCamera),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user