Files
gm_construct_port/code/entities/car/CarWheel.cs
2021-08-05 17:54:51 +03:00

76 lines
2.3 KiB
C#

using Sandbox;
using System;
struct CarWheel
{
private readonly CarEntity parent;
private float _previousLength;
private float _currentLength;
public CarWheel( CarEntity parent )
{
this.parent = parent;
_previousLength = 0;
_currentLength = 0;
}
public bool Raycast( float length, bool doPhysics, Vector3 offset, ref float wheel, float dt )
{
var position = parent.Position;
var rotation = parent.Rotation;
var wheelAttachPos = position + offset;
var wheelExtend = wheelAttachPos - rotation.Up * (length * parent.Scale);
var tr = Trace.Ray( wheelAttachPos, wheelExtend )
.Ignore( parent )
.Ignore( parent.driver )
.Run();
wheel = length * tr.Fraction;
var wheelRadius = (14 * parent.Scale);
if ( !doPhysics && CarEntity.debug_car )
{
var wheelPosition = tr.Hit ? tr.EndPos : wheelExtend;
wheelPosition += rotation.Up * wheelRadius;
if ( tr.Hit )
{
DebugOverlay.Circle( wheelPosition, rotation * Rotation.FromYaw( 90 ), wheelRadius, Color.Red.WithAlpha( 0.5f ), false );
DebugOverlay.Line( tr.StartPos, tr.EndPos, Color.Red, 0, false );
}
else
{
DebugOverlay.Circle( wheelPosition, rotation * Rotation.FromYaw( 90 ), wheelRadius, Color.Green.WithAlpha( 0.5f ), false );
DebugOverlay.Line( wheelAttachPos, wheelExtend, Color.Green, 0, false );
}
}
if ( !tr.Hit || !doPhysics )
{
return tr.Hit;
}
var body = parent.PhysicsBody.SelfOrParent;
_previousLength = _currentLength;
_currentLength = (length * parent.Scale) - tr.Distance;
var springVelocity = (_currentLength - _previousLength) / dt;
var springForce = body.Mass * 50.0f * _currentLength;
var damperForce = body.Mass * (1.5f + (1.0f - tr.Fraction) * 3.0f) * springVelocity;
var velocity = body.GetVelocityAtPoint( wheelAttachPos );
var speed = velocity.Length;
var speedDot = MathF.Abs( speed ) > 0.0f ? MathF.Abs( MathF.Min( Vector3.Dot( velocity, rotation.Up.Normal ) / speed, 0.0f ) ) : 0.0f;
var speedAlongNormal = speedDot * speed;
var correctionMultiplier = (1.0f - tr.Fraction) * (speedAlongNormal / 1000.0f);
var correctionForce = correctionMultiplier * 50.0f * speedAlongNormal / dt;
body.ApplyImpulseAt( wheelAttachPos, tr.Normal * (springForce + damperForce + correctionForce) * dt );
return true;
}
}