163 lines
3.7 KiB
C#
163 lines
3.7 KiB
C#
using OpenTK.Mathematics;
|
|
|
|
namespace DoomDeathmatch.Component.Physics;
|
|
|
|
/// <summary>
|
|
/// Represents a rigidbody component that simulates physics behavior such as force, velocity, and acceleration.
|
|
/// </summary>
|
|
public class RigidbodyComponent : Engine.Scene.Component.Component
|
|
{
|
|
/// <summary>
|
|
/// The mass of the rigidbody.
|
|
/// </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>
|
|
public bool IsStatic { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// The force currently applied to the rigidbody.
|
|
/// </summary>
|
|
public Vector3 Force
|
|
{
|
|
get => _force;
|
|
set
|
|
{
|
|
if (IsStatic)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_force = value;
|
|
}
|
|
}
|
|
|
|
/// <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>
|
|
public Vector3 Velocity
|
|
{
|
|
get => _velocity;
|
|
set
|
|
{
|
|
if (IsStatic)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_velocity = value;
|
|
}
|
|
}
|
|
|
|
/// <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>
|
|
private Vector3 _force = Vector3.Zero;
|
|
|
|
/// <summary>
|
|
/// The acceleration of the rigidbody.
|
|
/// </summary>
|
|
private Vector3 _acceleration = Vector3.Zero;
|
|
|
|
/// <summary>
|
|
/// The velocity of the rigidbody.
|
|
/// </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)
|
|
{
|
|
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;
|
|
|
|
GameObject.Transform.Rotation *= Quaternion.FromAxisAngle(Vector3.UnitX, AngularVelocity.X * (float)parDeltaTime);
|
|
GameObject.Transform.Rotation *= Quaternion.FromAxisAngle(Vector3.UnitY, AngularVelocity.Y * (float)parDeltaTime);
|
|
GameObject.Transform.Rotation *= Quaternion.FromAxisAngle(Vector3.UnitZ, AngularVelocity.Z * (float)parDeltaTime);
|
|
|
|
Torque = Vector3.Zero;
|
|
}
|
|
} |