using Sandbox; using System; namespace VeloX.Powertrain; public abstract class PowertrainComponent : Component { protected override void OnAwake() { Vehicle ??= Components.Get( FindMode.EverythingInSelfAndAncestors ); } public const float RAD_TO_RPM = 60f / MathF.Tau; public const float RPM_TO_RAD = 1 / (60 / MathF.Tau); public const float UNITS_PER_METER = 39.37f; public const float UNITS_TO_METERS = 0.01905f; public const float KG_TO_N = 9.80665f; public const float KG_TO_KN = 0.00980665f; [Property] public VeloXBase Vehicle { get; set; } [Property] public virtual float Inertia { get; set; } = 0.02f; /// /// Input component. Set automatically. /// [Property] public PowertrainComponent Input { get => _input; set { if ( value == null || value == this ) { _input = null; return; } _input = value; } } private PowertrainComponent _input; public int InputNameHash; /// /// The PowertrainComponent this component will output to. /// [Property] public PowertrainComponent Output { get => _output; set { if ( value == this ) { _output = null; return; } _output = value; if ( _output != null ) _output.Input = this; } } private PowertrainComponent _output; public float RPM => angularVelocity * RAD_TO_RPM; protected float angularVelocity; protected float Torque; public virtual bool HasOutput => Output.IsValid(); public virtual float QueryInertia() { if ( !HasOutput ) return Inertia; return Inertia + Output.QueryInertia(); } public virtual float QueryAngularVelocity( float angularVelocity ) { if ( !HasOutput ) return angularVelocity; return Output.QueryAngularVelocity( angularVelocity ); } public virtual float ForwardStep( float torque, float inertia ) { if ( !HasOutput ) return Torque; return Output.ForwardStep( Torque, inertia + Inertia ); } }