using OpenTK.Mathematics; namespace DoomDeathmatch.Component.Physics; /// /// Represents a rigidbody component that simulates physics behavior such as force, velocity, and acceleration. /// public class RigidbodyComponent : Engine.Scene.Component.Component { /// /// The mass of the rigidbody. /// public float Mass { get; set; } = 1.0f; /// /// The moment of inertia of the rigidbody. /// For simplicity, this assumes a scalar value, suitable for symmetric objects. /// public float MomentOfInertia { get; set; } = 1.0f; /// /// Indicates whether the rigidbody is static and unaffected by forces. /// public bool IsStatic { get; set; } = false; /// /// The force currently applied to the rigidbody. /// public Vector3 Force { get => _force; set { if (IsStatic) { return; } _force = value; } } /// /// The torque currently applied to the rigidbody. /// public Vector3 Torque { get => _torque; set { if (IsStatic) { return; } _torque = value; } } /// /// The velocity of the rigidbody. /// public Vector3 Velocity { get => _velocity; set { if (IsStatic) { return; } _velocity = value; } } /// /// The angular velocity of the rigidbody. /// public Vector3 AngularVelocity { get => _angularVelocity; set { if (IsStatic) { return; } _angularVelocity = value; } } /// /// The force currently applied to the rigidbody. /// private Vector3 _force = Vector3.Zero; /// /// The acceleration of the rigidbody. /// private Vector3 _acceleration = Vector3.Zero; /// /// The velocity of the rigidbody. /// private Vector3 _velocity = Vector3.Zero; /// /// The torque currently applied to the rigidbody. /// private Vector3 _torque = Vector3.Zero; /// /// The angular acceleration of the rigidbody. /// private Vector3 _angularAcceleration = Vector3.Zero; /// /// The angular velocity of the rigidbody. /// private Vector3 _angularVelocity = Vector3.Zero; public override void PostUpdate(double parDeltaTime) { if (IsStatic) { return; } ApplyForce(parDeltaTime); ApplyTorque(parDeltaTime); } /// /// Applies force to the rigidbody. /// /// The time in seconds since the last update. private void ApplyForce(double parDeltaTime) { _acceleration = Force / Mass; Velocity += _acceleration * (float)parDeltaTime; GameObject.Transform.Translation += Velocity * (float)parDeltaTime; Force = Vector3.Zero; } /// /// Applies torque to the rigidbody. /// /// The time in seconds since the last update. 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; } }