Files
doom-dm/DoomDeathmatch/src/Component/Physics/RigidbodyComponent.cs
2025-01-09 06:37:12 +03:00

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;
}
}