using Sandbox; using System; namespace VeloX; [GameResource( "Wheel Friction", "tire", "Wheel Friction", Category = "VeloX", Icon = "radio_button_checked" )] public class TirePreset : GameResource { [Property] public Pacejka Pacejka { get; set; } public float RollResistanceLin { get; set; } = 1E-3f; public float RollResistanceQuad { get; set; } = 1E-6f; public float GetRollingResistance( float velocity, float resistance_factor ) { // surface influence on rolling resistance float resistance = resistance_factor * RollResistanceLin; // heat due to tire deformation increases rolling resistance // approximate by quadratic function resistance += velocity * velocity * RollResistanceQuad; return resistance; } public static void ComputeSlip( float lon_velocity, float lat_velocity, float rot_velocity, float wheel_radius, out float slip_ratio, out float slip_angle ) { var abs_lon = Math.Max( MathF.Abs( lon_velocity ), 1e-3f ); slip_ratio = lon_velocity - rot_velocity * wheel_radius; if ( abs_lon >= 0.005f ) slip_ratio /= abs_lon; else slip_ratio *= abs_lon; if ( abs_lon >= 0.5f ) slip_angle = MathF.Atan2( -lat_velocity, abs_lon ).RadianToDegree() / 50f; else slip_angle = -lat_velocity * (0.01f / Time.Delta); slip_ratio = Math.Clamp( slip_ratio, -1, 1 ); slip_angle = Math.Clamp( slip_angle, -1, 1 ); } /// approximate asin(x) = x + x^3/6 for +-18 deg range public static float ComputeCamberAngle( float sin_camber ) { float sc = Math.Clamp( sin_camber, -0.3f, 0.3f ); return ((1 / 6.0f) * (sc * sc) + 1) * sc; } public static float ComputeCamberVelocity( float sa, float vx ) { float tansa = (1 / 3.0f * (sa * sa) + 1) * sa; return tansa * vx; } }