cumulative update
This commit is contained in:
parent
e12b75be45
commit
66fcc6a2bb
@ -12,6 +12,7 @@
|
||||
"NetworkMode": 2,
|
||||
"NetworkInterpolation": true,
|
||||
"NetworkOrphaned": 0,
|
||||
"NetworkTransmit": true,
|
||||
"OwnerTransfer": 1,
|
||||
"Components": [],
|
||||
"Children": [
|
||||
@ -28,6 +29,7 @@
|
||||
"NetworkMode": 2,
|
||||
"NetworkInterpolation": true,
|
||||
"NetworkOrphaned": 0,
|
||||
"NetworkTransmit": true,
|
||||
"OwnerTransfer": 1,
|
||||
"Components": [
|
||||
{
|
||||
@ -197,7 +199,7 @@
|
||||
"FaceVelocity": false,
|
||||
"FogStrength": 1,
|
||||
"LeadingTrail": true,
|
||||
"Lighting": false,
|
||||
"Lighting": true,
|
||||
"MotionBlur": false,
|
||||
"OnComponentDestroy": null,
|
||||
"OnComponentDisabled": null,
|
||||
@ -206,6 +208,7 @@
|
||||
"OnComponentStart": null,
|
||||
"OnComponentUpdate": null,
|
||||
"Opaque": false,
|
||||
"PlaybackSpeed": 1,
|
||||
"RenderOptions": {
|
||||
"GameLayer": true,
|
||||
"OverlayLayer": false,
|
||||
@ -215,7 +218,7 @@
|
||||
"RotationOffset": 0,
|
||||
"Scale": 1,
|
||||
"Shadows": true,
|
||||
"SortMode": "Unsorted",
|
||||
"SortMode": "ByDistance",
|
||||
"Sprite": {
|
||||
"$compiler": "embed",
|
||||
"$source": null,
|
||||
@ -228,7 +231,8 @@
|
||||
"LoopMode": "Loop",
|
||||
"Frames": [
|
||||
{
|
||||
"Texture": "textures/smoketexturesheet.vtex"
|
||||
"Texture": "textures/smoketexturesheet.vtex",
|
||||
"BroadcastMessages": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -4,10 +4,10 @@ namespace VeloX;
|
||||
|
||||
public abstract partial class VeloXBase
|
||||
{
|
||||
[Feature( "Input" )] internal InputResolver Input { get; set; } = new();
|
||||
[Feature( "Input" )] public Connection Driver { get => Input.Driver; set => Input.Driver = value; }
|
||||
|
||||
internal InputResolver Input { get; set; } = new();
|
||||
public Connection Driver { get => Input.Driver; set => Input.Driver = value; }
|
||||
|
||||
public bool IsDriver => Connection.Local == Driver;
|
||||
private bool IsDriverActive => Driver is not null;
|
||||
|
||||
public Vector2 MouseDelta => IsDriverActive ? Input.MouseDelta : default;
|
||||
|
||||
@ -52,12 +52,8 @@ public abstract partial class VeloXBase
|
||||
v.BrakeTorque = HandbrakeForce;
|
||||
}
|
||||
|
||||
v.Update( this, in dt );
|
||||
v.DoPhysics( in dt );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Body.Velocity = vehVel;
|
||||
Body.AngularVelocity = vehAngVel;
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ using System;
|
||||
namespace VeloX;
|
||||
|
||||
|
||||
public abstract partial class VeloXBase : Component
|
||||
public abstract partial class VeloXBase : Component, IGameObjectNetworkEvents
|
||||
{
|
||||
[Sync, Change( nameof( OnEngineIgnitionChange ) )]
|
||||
public bool EngineIgnition { get; set; }
|
||||
@ -26,18 +26,24 @@ public abstract partial class VeloXBase : Component
|
||||
|
||||
[Sync( SyncFlags.Interpolate )] public Angles SteerAngle { get; set; }
|
||||
|
||||
public Vector3 LocalVelocity;
|
||||
[Sync( SyncFlags.Interpolate )] public Vector3 LocalVelocity { get; set; }
|
||||
[Sync( SyncFlags.Interpolate )] public Vector3 Velocity { get; set; }
|
||||
public float ForwardSpeed;
|
||||
public float TotalSpeed;
|
||||
|
||||
protected override void OnFixedUpdate()
|
||||
{
|
||||
if ( !IsProxy )
|
||||
{
|
||||
LocalVelocity = WorldTransform.PointToLocal( WorldPosition + Body.Velocity );
|
||||
Velocity = Body.Velocity;
|
||||
}
|
||||
ForwardSpeed = LocalVelocity.x;
|
||||
|
||||
TotalSpeed = LocalVelocity.Length;
|
||||
|
||||
if ( IsProxy )
|
||||
return;
|
||||
|
||||
LocalVelocity = WorldTransform.PointToLocal( WorldPosition + Body.Velocity );
|
||||
ForwardSpeed = LocalVelocity.x;
|
||||
TotalSpeed = LocalVelocity.Length;
|
||||
Body.PhysicsBody.Mass = Mass;
|
||||
|
||||
FixedUpdate();
|
||||
@ -50,4 +56,10 @@ public abstract partial class VeloXBase : Component
|
||||
PhysicsSimulate();
|
||||
}
|
||||
|
||||
//void IGameObjectNetworkEvents.NetworkOwnerChanged( Connection newOwner, Connection previousOwner )
|
||||
//{
|
||||
|
||||
// Driver = newOwner;
|
||||
// EngineIgnition = Driver is not null;
|
||||
//}
|
||||
}
|
||||
|
||||
@ -4,9 +4,6 @@ namespace VeloX;
|
||||
|
||||
public struct Friction
|
||||
{
|
||||
public float SlipCoef { get; set; }
|
||||
public float ForceCoef { get; set; }
|
||||
|
||||
public float Force { get; set; }
|
||||
public float Slip { get; set; }
|
||||
public float Speed { get; set; }
|
||||
|
||||
@ -35,8 +35,6 @@ public partial class VeloXWheel
|
||||
public float CounterTorque { get; private set; }
|
||||
|
||||
//[Property, Range( 0, 2 )] public float BrakeMult { get; set; } = 1f;
|
||||
public Friction ForwardFriction = new();
|
||||
public Friction SidewayFriction = new();
|
||||
public Vector3 FrictionForce;
|
||||
|
||||
|
||||
@ -47,20 +45,32 @@ public partial class VeloXWheel
|
||||
public Vector3 ContactRight => hitSidewaysDirection;
|
||||
public Vector3 ContactForward => hitForwardDirection;
|
||||
|
||||
public float LongitudinalSlip => ForwardFriction.Slip;
|
||||
|
||||
public float LongitudinalSpeed => ForwardFriction.Speed;
|
||||
public float LongitudinalSlip => sx;
|
||||
public float LongitudinalSpeed => vx;
|
||||
public bool IsSkiddingLongitudinally => NormalizedLongitudinalSlip > 0.35f;
|
||||
public float NormalizedLongitudinalSlip => Math.Clamp( Math.Abs( LongitudinalSlip ), 0, 1 );
|
||||
|
||||
|
||||
public float LateralSlip => SidewayFriction.Slip;
|
||||
public float LateralSpeed => SidewayFriction.Speed;
|
||||
public float LateralSlip => sy;
|
||||
public float LateralSpeed => vy;
|
||||
public bool IsSkiddingLaterally => NormalizedLateralSlip > 0.35f;
|
||||
public float NormalizedLateralSlip => Math.Clamp( Math.Abs( LateralSlip ), 0, 1 );
|
||||
|
||||
public bool IsSkidding => IsSkiddingLaterally || IsSkiddingLongitudinally;
|
||||
public float NormalizedSlip => (NormalizedLateralSlip + NormalizedLongitudinalSlip) / 2f;
|
||||
|
||||
|
||||
// speed
|
||||
[Sync] private float vx { get; set; }
|
||||
[Sync] private float vy { get; set; }
|
||||
|
||||
// force
|
||||
[Sync] private float fx { get; set; }
|
||||
[Sync] private float fy { get; set; }
|
||||
|
||||
// slip
|
||||
[Sync] private float sx { get; set; }
|
||||
[Sync] private float sy { get; set; }
|
||||
|
||||
private void UpdateHitVariables()
|
||||
{
|
||||
if ( IsOnGround )
|
||||
@ -70,13 +80,13 @@ public partial class VeloXWheel
|
||||
hitForwardDirection = ContactNormal.Cross( TransformRotationSteer.Right ).Normal;
|
||||
hitSidewaysDirection = Rotation.FromAxis( ContactNormal, 90f ) * hitForwardDirection;
|
||||
|
||||
ForwardFriction.Speed = hitContactVelocity.Dot( hitForwardDirection ).InchToMeter();
|
||||
SidewayFriction.Speed = hitContactVelocity.Dot( hitSidewaysDirection ).InchToMeter();
|
||||
vx = hitContactVelocity.Dot( hitForwardDirection ).InchToMeter();
|
||||
vy = hitContactVelocity.Dot( hitSidewaysDirection ).InchToMeter();
|
||||
}
|
||||
else
|
||||
{
|
||||
ForwardFriction = new();
|
||||
SidewayFriction = new();
|
||||
vx = 0;
|
||||
vy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,9 +122,9 @@ public partial class VeloXWheel
|
||||
float slipLoadModifier = 1f - loadPercent * 0.4f;
|
||||
|
||||
float mass = Vehicle.Body.Mass;
|
||||
float absForwardSpeed = Math.Abs( ForwardFriction.Speed );
|
||||
float absForwardSpeed = Math.Abs( vx );
|
||||
float forwardForceClamp = mass * LoadContribution * absForwardSpeed * invDt;
|
||||
float absSideSpeed = Math.Abs( SidewayFriction.Speed );
|
||||
float absSideSpeed = Math.Abs( vy );
|
||||
float sideForceClamp = mass * LoadContribution * absSideSpeed * invDt;
|
||||
|
||||
float forwardSpeedClamp = 1.5f * (dt / 0.005f);
|
||||
@ -124,7 +134,7 @@ public partial class VeloXWheel
|
||||
float peakForwardFrictionForce = 11000 * (1 - MathF.Exp( -0.00014f * forwardLoadFactor ));
|
||||
float absCombinedBrakeTorque = Math.Max( 0, brakeTorque + RollingResistanceTorque );
|
||||
|
||||
float signedCombinedBrakeTorque = absCombinedBrakeTorque * -Math.Sign( ForwardFriction.Speed );
|
||||
float signedCombinedBrakeTorque = absCombinedBrakeTorque * (vx > 0 ? -1 : 1);
|
||||
float signedCombinedBrakeForce = signedCombinedBrakeTorque * invRadius;
|
||||
float motorForce = motorTorque * invRadius;
|
||||
float forwardInputForce = motorForce + signedCombinedBrakeForce;
|
||||
@ -134,7 +144,7 @@ public partial class VeloXWheel
|
||||
float maxForwardForce = Math.Min( peakForwardFrictionForce, forwardForceClamp );
|
||||
|
||||
maxForwardForce = absMotorTorque < absBrakeTorque ? maxForwardForce : peakForwardFrictionForce;
|
||||
ForwardFriction.Force = forwardInputForce > maxForwardForce ? maxForwardForce
|
||||
fx = forwardInputForce > maxForwardForce ? maxForwardForce
|
||||
: forwardInputForce < -maxForwardForce ? -maxForwardForce : forwardInputForce;
|
||||
|
||||
wheelIsBlocked = false;
|
||||
@ -153,14 +163,14 @@ public partial class VeloXWheel
|
||||
AngularVelocity += combinedWheelForce * mRadius * invInertia * dt;
|
||||
|
||||
// Surface (corrective) force
|
||||
float noSlipAngularVelocity = ForwardFriction.Speed * invRadius;
|
||||
float noSlipAngularVelocity = vx * invRadius;
|
||||
float angularVelocityError = AngularVelocity - noSlipAngularVelocity;
|
||||
|
||||
float angularVelocityCorrectionForce = Math.Clamp( -angularVelocityError * inertia * invRadius * invDt, -maxForwardForce, maxForwardForce );
|
||||
if ( absMotorTorque < absBrakeTorque && Math.Abs( wheelForceClampOverflow ) > Math.Abs( angularVelocityCorrectionForce ) )
|
||||
{
|
||||
wheelIsBlocked = true;
|
||||
AngularVelocity += ForwardFriction.Speed > 0 ? 1e-10f : -1e-10f;
|
||||
AngularVelocity += vx > 0 ? 1e-10f : -1e-10f;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -178,24 +188,24 @@ public partial class VeloXWheel
|
||||
|
||||
float absAngularVelocity = AngularVelocity < 0 ? -AngularVelocity : AngularVelocity;
|
||||
float maxCounterTorque = inertia * absAngularVelocity;
|
||||
CounterTorque = Math.Clamp( (signedCombinedBrakeForce - ForwardFriction.Force) * mRadius, -maxCounterTorque, maxCounterTorque );
|
||||
CounterTorque = Math.Clamp( (signedCombinedBrakeForce - fx) * mRadius, -maxCounterTorque, maxCounterTorque );
|
||||
|
||||
ForwardFriction.Slip = (ForwardFriction.Speed - AngularVelocity * mRadius) / clampedAbsForwardSpeed;
|
||||
ForwardFriction.Slip *= slipLoadModifier;
|
||||
sx = (vx - AngularVelocity * mRadius) / clampedAbsForwardSpeed;
|
||||
sx *= slipLoadModifier;
|
||||
|
||||
SidewayFriction.Slip = MathF.Atan2( SidewayFriction.Speed, clampedAbsForwardSpeed );
|
||||
SidewayFriction.Slip *= slipLoadModifier;
|
||||
sy = MathF.Atan2( vy, clampedAbsForwardSpeed );
|
||||
sy *= slipLoadModifier;
|
||||
|
||||
float sideSlipSign = SidewayFriction.Slip > 0 ? 1 : -1;
|
||||
float absSideSlip = Math.Abs( SidewayFriction.Slip );
|
||||
float sideSlipSign = sy > 0 ? 1 : -1;
|
||||
float absSideSlip = Math.Abs( sy );
|
||||
float peakSideFrictionForce = 18000 * (1 - MathF.Exp( -0.0001f * sideLoadFactor ));
|
||||
|
||||
float sideForce = -sideSlipSign * Tire.Evaluate( absSideSlip ) * peakSideFrictionForce;
|
||||
SidewayFriction.Force = Math.Clamp( sideForce, -sideForceClamp, sideForceClamp );
|
||||
fy = Math.Clamp( sideForce, -sideForceClamp, sideForceClamp );
|
||||
|
||||
// Calculate effect of camber on friction
|
||||
float camberFrictionCoeff = Math.Max( 0, Vehicle.WorldRotation.Up.Dot( ContactNormal ) );
|
||||
SidewayFriction.Force *= camberFrictionCoeff;
|
||||
fy *= camberFrictionCoeff;
|
||||
|
||||
if ( IsOnGround && absForwardSpeed < 0.12f && absSideSpeed < 0.12f )
|
||||
{
|
||||
@ -225,9 +235,9 @@ public partial class VeloXWheel
|
||||
|
||||
if ( wheelIsBlocked && absAngularVelocity < 0.5f )
|
||||
{
|
||||
ForwardFriction.Force += correctiveForce.Dot( hitForwardDirection );
|
||||
fx += correctiveForce.Dot( hitForwardDirection );
|
||||
}
|
||||
SidewayFriction.Force += correctiveForce.Dot( hitSidewaysDirection );
|
||||
fy += correctiveForce.Dot( hitSidewaysDirection );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -235,52 +245,21 @@ public partial class VeloXWheel
|
||||
lowSpeedReferenceIsSet = false;
|
||||
}
|
||||
|
||||
fx = Math.Clamp( fx, -peakForwardFrictionForce, peakForwardFrictionForce );
|
||||
fy = Math.Clamp( fy, -peakSideFrictionForce, peakSideFrictionForce );
|
||||
|
||||
//float forwardSlipPercent = -ForwardFriction.Slip / Tire.GetPeakSlip();
|
||||
//float sideSlipPercent = SidewayFriction.Slip / Tire.GetPeakSlip();
|
||||
//float slipCircleLimit = MathF.Sqrt( forwardSlipPercent * forwardSlipPercent + sideSlipPercent * sideSlipPercent );
|
||||
//if ( slipCircleLimit > 1f )
|
||||
//{
|
||||
// float beta = MathF.Atan2( sideSlipPercent, forwardSlipPercent * 1.05f );
|
||||
// float sinBeta = MathF.Sin( beta );
|
||||
// float cosBeta = MathF.Cos( beta );
|
||||
|
||||
// float absForwardForce = ForwardFriction.Force < 0 ? -ForwardFriction.Force : ForwardFriction.Force;
|
||||
|
||||
// float absSideForce = SidewayFriction.Force < 0 ? -SidewayFriction.Force : SidewayFriction.Force;
|
||||
// float f = absForwardForce * cosBeta * cosBeta + absSideForce * sinBeta * sinBeta;
|
||||
|
||||
// ForwardFriction.Force = 0.5f * ForwardFriction.Force - f * cosBeta;
|
||||
// SidewayFriction.Force = 0.5f * SidewayFriction.Force - f * sinBeta;
|
||||
//}
|
||||
|
||||
//var slipVector = new Vector2(
|
||||
// ForwardFriction.Slip,
|
||||
// SidewayFriction.Slip
|
||||
//);
|
||||
//if ( slipVector.Length > 0.001f )
|
||||
//{
|
||||
// var frictionDirection = slipVector.Normal;
|
||||
|
||||
// float frictionMagnitude = MathF.Sqrt(
|
||||
// ForwardFriction.Force * ForwardFriction.Force +
|
||||
// SidewayFriction.Force * SidewayFriction.Force
|
||||
// );
|
||||
|
||||
// ForwardFriction.Force = Math.Abs( frictionDirection.x ) * frictionMagnitude * Math.Sign( ForwardFriction.Force );
|
||||
// SidewayFriction.Force = Math.Abs( frictionDirection.y ) * frictionMagnitude * Math.Sign( SidewayFriction.Force );
|
||||
//}
|
||||
|
||||
var f = MathF.Sqrt( ForwardFriction.Force * ForwardFriction.Force + SidewayFriction.Force * SidewayFriction.Force );
|
||||
var d = Math.Abs( new Vector2( ForwardFriction.Slip, SidewayFriction.Slip ).Normal.y );
|
||||
SidewayFriction.Force = f * d * Math.Sign( SidewayFriction.Force );
|
||||
|
||||
if ( absForwardSpeed > 0.01f || absAngularVelocity > 0.01f )
|
||||
{
|
||||
var f = MathF.Sqrt( fx * fx + fy * fy );
|
||||
var d = Math.Abs( new Vector2( sx, sy ).Normal.y );
|
||||
fy = f * d * Math.Sign( fy );
|
||||
|
||||
}
|
||||
if ( IsOnGround )
|
||||
{
|
||||
FrictionForce.x = (hitSidewaysDirection.x * SidewayFriction.Force + hitForwardDirection.x * ForwardFriction.Force).MeterToInch();
|
||||
FrictionForce.y = (hitSidewaysDirection.y * SidewayFriction.Force + hitForwardDirection.y * ForwardFriction.Force).MeterToInch();
|
||||
FrictionForce.z = (hitSidewaysDirection.z * SidewayFriction.Force + hitForwardDirection.z * ForwardFriction.Force).MeterToInch();
|
||||
FrictionForce.x = (hitSidewaysDirection.x * fy + hitForwardDirection.x * fx).MeterToInch();
|
||||
FrictionForce.y = (hitSidewaysDirection.y * fy + hitForwardDirection.y * fx).MeterToInch();
|
||||
FrictionForce.z = (hitSidewaysDirection.z * fy + hitForwardDirection.z * fx).MeterToInch();
|
||||
|
||||
//DebugOverlay.Normal( WorldPosition, hitSidewaysDirection * 10, overlay: true, color: Color.Red );
|
||||
//DebugOverlay.Normal( WorldPosition, hitForwardDirection * 10, overlay: true, color: Color.Green );
|
||||
|
||||
@ -34,7 +34,7 @@ public partial class VeloXWheel
|
||||
{
|
||||
GameObject go = new()
|
||||
{
|
||||
WorldPosition = ContactPosition + Vehicle.WorldRotation.Down * (Radius.MeterToInch() - 0.01f),
|
||||
WorldPosition = ContactPosition + Vehicle.WorldRotation.Down * (Radius.MeterToInch() - 1f),
|
||||
WorldRotation = Rotation.LookAt( hitSidewaysDirection )
|
||||
};
|
||||
_skidMark = go.AddComponent<LineRenderer>();
|
||||
@ -53,8 +53,7 @@ public partial class VeloXWheel
|
||||
|
||||
protected void UpdateSkid()
|
||||
{
|
||||
if ( IsProxy )
|
||||
return;
|
||||
|
||||
while ( SkidMarks.Count > MaxSkid )
|
||||
{
|
||||
SkidMarks.Dequeue()?.DestroyGameObject();
|
||||
@ -81,7 +80,7 @@ public partial class VeloXWheel
|
||||
GameObject go = new()
|
||||
{
|
||||
Parent = _skidMark.GameObject,
|
||||
WorldPosition = ContactPosition + Vehicle.WorldRotation.Down * Radius.MeterToInch(),
|
||||
WorldPosition = ContactPosition + Vehicle.WorldRotation.Down * (Radius.MeterToInch() - 1f),
|
||||
WorldRotation = Rotation.LookAt( ContactNormal.RotateAround( Vector3.Zero, Rotation.FromRoll( 90 ) ) )
|
||||
};
|
||||
go.Flags = go.Flags.WithFlag( GameObjectFlags.Hidden, true );
|
||||
|
||||
@ -8,9 +8,8 @@ namespace VeloX;
|
||||
|
||||
public partial class VeloXWheel
|
||||
{
|
||||
private static readonly GameObject SmokePrefab = GameObject.GetPrefab( "prefabs/particles/tire_smoke.prefab" );
|
||||
|
||||
private GameObject SmokeObject { get; set; }
|
||||
private GameObject SmokeObject;
|
||||
public const float MIN_DRIFT_ANGLE = 10f;
|
||||
public const float MIN_DRIFT_SPEED = 30f;
|
||||
public const float MAX_DRIFT_ANGLE = 110f;
|
||||
@ -19,11 +18,13 @@ public partial class VeloXWheel
|
||||
protected override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
if ( IsProxy )
|
||||
return;
|
||||
|
||||
if ( !SmokeObject.IsValid() )
|
||||
SmokeObject = GameObject.GetPrefab( "prefabs/particles/tire_smoke.prefab" ).Clone( new CloneConfig() { Parent = GameObject, StartEnabled = true } );
|
||||
SmokeObject.Flags = SmokeObject.Flags.WithFlag( GameObjectFlags.NotNetworked, true );
|
||||
|
||||
var emitter = SmokeObject.Components.Get<ParticleSphereEmitter>( FindMode.EverythingInSelfAndDescendants );
|
||||
emitter.Enabled = false;
|
||||
|
||||
}
|
||||
public float GetSlip()
|
||||
{
|
||||
@ -36,12 +37,8 @@ public partial class VeloXWheel
|
||||
// return val;
|
||||
return val * 5;
|
||||
}
|
||||
protected override void OnUpdate()
|
||||
private void UpdateSmoke()
|
||||
{
|
||||
base.OnUpdate();
|
||||
if ( IsProxy )
|
||||
return;
|
||||
UpdateSkid();
|
||||
SmokeObject.WorldPosition = ContactPosition + Vehicle.WorldRotation.Down * Radius.MeterToInch();
|
||||
smokeMul = Math.Max( 0, GetSlip() - 3 );
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ public partial class VeloXWheel : Component
|
||||
|
||||
public float RPM { get => AngularVelocity * 60f / MathF.Tau; set => AngularVelocity = value / (60 / MathF.Tau); }
|
||||
|
||||
private Vector3 StartPos { get; set; }
|
||||
[Sync] private Vector3 StartPos { get; set; }
|
||||
private static Rotation CylinderOffset = Rotation.FromRoll( 90 );
|
||||
|
||||
[Sync] public bool IsOnGround { get; private set; }
|
||||
@ -39,13 +39,13 @@ public partial class VeloXWheel : Component
|
||||
[Property] public float BrakeTorque { get; set; }
|
||||
|
||||
public float Compression { get; protected set; } // meters
|
||||
public float LastLength { get; protected set; } // meters
|
||||
[Sync( SyncFlags.Interpolate )] public float LastLength { get; protected set; } // meters
|
||||
public float Fz { get; protected set; } // N
|
||||
public float AngularVelocity { get; protected set; } // rad/s
|
||||
public float RollAngle { get; protected set; } // degrees
|
||||
[Sync( SyncFlags.Interpolate )] public float RollAngle { get; protected set; }
|
||||
|
||||
|
||||
private VeloXBase Vehicle;
|
||||
public VeloXBase Vehicle { get; private set; }
|
||||
[Sync] public Vector3 ContactNormal { get; protected set; }
|
||||
[Sync] public Vector3 ContactPosition { get; protected set; }
|
||||
Rotation TransformRotationSteer => Vehicle.WorldTransform.RotationToWorld( Vehicle.SteerAngle * SteerMultiplier );
|
||||
@ -59,15 +59,9 @@ public partial class VeloXWheel : Component
|
||||
Inertia = BaseInertia;
|
||||
}
|
||||
|
||||
internal void Update( VeloXBase vehicle, in float dt )
|
||||
private void UpdateVisuals()
|
||||
{
|
||||
UpdateVisuals( vehicle, dt );
|
||||
|
||||
}
|
||||
|
||||
private void UpdateVisuals( VeloXBase vehicle, in float dt )
|
||||
{
|
||||
WorldRotation = vehicle.WorldTransform.RotationToWorld( vehicle.SteerAngle * SteerMultiplier ).RotateAroundAxis( Vector3.Right, -RollAngle );
|
||||
WorldRotation = Vehicle.WorldTransform.RotationToWorld( Vehicle.SteerAngle * SteerMultiplier ).RotateAroundAxis( Vector3.Right, -RollAngle );
|
||||
LocalPosition = StartPos + Vector3.Down * LastLength.MeterToInch();
|
||||
}
|
||||
|
||||
@ -213,4 +207,15 @@ public partial class VeloXWheel : Component
|
||||
RollAngle += MathX.RadianToDegree( AngularVelocity ) * dt;
|
||||
RollAngle = (RollAngle % 360f + 360f) % 360f;
|
||||
}
|
||||
|
||||
protected override void OnFixedUpdate()
|
||||
{
|
||||
|
||||
UpdateSmoke();
|
||||
}
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
UpdateVisuals();
|
||||
UpdateSkid();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
using Sandbox;
|
||||
using System.Linq;
|
||||
using static Sandbox.Services.Inventory;
|
||||
namespace VeloX;
|
||||
|
||||
internal sealed class WheelManager : GameObjectSystem
|
||||
@ -23,17 +22,17 @@ internal sealed class WheelManager : GameObjectSystem
|
||||
if ( !wheels.Any() ) return;
|
||||
|
||||
var timeDelta = Time.Delta;
|
||||
Sandbox.Utility.Parallel.ForEach( wheels, item =>
|
||||
{
|
||||
if ( !item.IsProxy && item.IsValid() )
|
||||
item.DoPhysics( timeDelta );
|
||||
} );
|
||||
//foreach ( var item in wheels )
|
||||
//Sandbox.Utility.Parallel.ForEach( wheels, item =>
|
||||
//{
|
||||
// if ( !item.IsProxy && item.IsValid() )
|
||||
// item.DoPhysics( timeDelta );
|
||||
//} );
|
||||
foreach ( var item in wheels )
|
||||
if ( item.IsValid() && !item.IsProxy )
|
||||
item.DoPhysics( timeDelta );
|
||||
|
||||
foreach ( var wheel in wheels )
|
||||
if ( !wheel.IsProxy && wheel.IsValid() )
|
||||
if ( wheel.IsValid() && !wheel.IsProxy)
|
||||
wheel.UpdateForce();
|
||||
|
||||
//sw.Stop();
|
||||
@ -50,15 +49,15 @@ internal sealed class WheelManager : GameObjectSystem
|
||||
if ( !engines.Any() ) return;
|
||||
|
||||
var timeDelta = Time.Delta;
|
||||
Sandbox.Utility.Parallel.ForEach( engines, item =>
|
||||
{
|
||||
foreach ( var wheel in engines )
|
||||
if ( !wheel.IsProxy && wheel.IsValid() )
|
||||
wheel.UpdateEngine( timeDelta );
|
||||
} );
|
||||
//foreach ( var wheel in engines )
|
||||
//Sandbox.Utility.Parallel.ForEach( engines, item =>
|
||||
//{
|
||||
// foreach ( var wheel in engines )
|
||||
// if ( !wheel.IsProxy && wheel.IsValid() )
|
||||
// wheel.UpdateEngine( timeDelta );
|
||||
//} );
|
||||
foreach ( var wheel in engines )
|
||||
if ( wheel.IsValid() )
|
||||
wheel.UpdateEngine( timeDelta );
|
||||
|
||||
|
||||
//sw.Stop();
|
||||
|
||||
@ -7,23 +7,14 @@ namespace VeloX;
|
||||
[Title( "VeloX - Car" )]
|
||||
public partial class VeloXCar : VeloXBase
|
||||
{
|
||||
|
||||
protected override void FixedUpdate()
|
||||
{
|
||||
|
||||
UpdateInput();
|
||||
PhysicsSimulate();
|
||||
UpdateABS();
|
||||
UpdateESC();
|
||||
}
|
||||
|
||||
protected override void OnFixedUpdate()
|
||||
{
|
||||
if ( IsProxy )
|
||||
return;
|
||||
|
||||
base.OnFixedUpdate();
|
||||
|
||||
if ( IsProxy )
|
||||
return;
|
||||
UpdateABS();
|
||||
UpdateESC();
|
||||
var dt = Time.Delta;
|
||||
//EngineThink( dt );
|
||||
SimulateAerodinamics( dt );
|
||||
|
||||
@ -10,7 +10,7 @@ namespace VeloX;
|
||||
public class EngineStreamPlayer( EngineStream stream ) : IDisposable
|
||||
{
|
||||
|
||||
private static readonly Mixer EngineMixer = Mixer.FindMixerByName( "Car Engine" );
|
||||
private static readonly Mixer EngineMixer = Mixer.FindMixerByName( "Engine" );
|
||||
public EngineStream Stream { get; set; } = stream;
|
||||
|
||||
public EngineState EngineState { get; set; }
|
||||
@ -103,6 +103,7 @@ public class EngineStreamPlayer( EngineStream stream ) : IDisposable
|
||||
channel.Position = position;
|
||||
channel.ListenLocal = isLocal;
|
||||
channel.Paused = EngineSoundPaused || layer.IsMuted;
|
||||
channel.FollowParent = true;
|
||||
channel.TargetMixer = EngineMixer;
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user