mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-04 20:38:24 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
137 lines
3.5 KiB
C#
137 lines
3.5 KiB
C#
|
|
namespace Sandbox;
|
|
|
|
partial class ModelPhysics
|
|
{
|
|
/// <summary>
|
|
/// Represents a <see cref="Rigidbody"/> attached to a specific bone with a local transform.
|
|
/// </summary>
|
|
public readonly record struct Body( Rigidbody Component, int Bone, Transform LocalTransform );
|
|
|
|
/// <summary>
|
|
/// Represents a <see cref="Sandbox.Joint"/> between two bodies with local frames for each.
|
|
/// </summary>
|
|
public readonly record struct Joint( Sandbox.Joint Component, Body Body1, Body Body2, Transform LocalFrame1, Transform LocalFrame2 );
|
|
|
|
/// <summary>
|
|
/// Networked list of bodies.
|
|
/// </summary>
|
|
[Sync, Property, Hide] public List<Body> Bodies { get; set; } = [];
|
|
|
|
/// <summary>
|
|
/// Networked list of joints.
|
|
/// </summary>
|
|
[Sync, Property, Hide] public List<Joint> Joints { get; set; } = [];
|
|
|
|
/// <summary>
|
|
/// Networked <see cref="Rigidbody"/> transforms.
|
|
/// </summary>
|
|
[Sync] private NetworkTransforms BodyTransforms { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// Sync visual transforms to physics transforms.
|
|
/// </summary>
|
|
void UpdateProxyTransforms()
|
|
{
|
|
if ( !Renderer.IsValid() )
|
|
return;
|
|
|
|
var so = Renderer.SceneModel;
|
|
if ( !so.IsValid() )
|
|
return;
|
|
|
|
Renderer.ClearPhysicsBones();
|
|
|
|
var world = WorldTransform;
|
|
|
|
foreach ( var (component, boneIndex, _) in Bodies )
|
|
{
|
|
if ( !component.IsValid() )
|
|
continue;
|
|
|
|
var body = component.PhysicsBody;
|
|
if ( !body.IsValid() )
|
|
continue;
|
|
|
|
// Set transform to lerped physics transform.
|
|
var bodyTransform = body.GetLerpedTransform( Time.Now ).WithScale( component.WorldScale );
|
|
component.WorldTransform = bodyTransform;
|
|
|
|
// Bone overrides are in modelspace, strip off our world transform from body world transform.
|
|
var boneTransform = world.ToLocal( bodyTransform );
|
|
so.SetBoneOverride( boneIndex, boneTransform );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send body transforms.
|
|
/// </summary>
|
|
void SetBodyTransforms()
|
|
{
|
|
for ( var i = 0; i < Bodies.Count; i++ )
|
|
{
|
|
var component = Bodies[i].Component;
|
|
if ( !component.IsValid() )
|
|
continue;
|
|
|
|
// If someone enabled networking on this body gameobject then it doesn't need to be sent.
|
|
if ( component.GameObject.NetworkMode == NetworkMode.Object )
|
|
continue;
|
|
|
|
var body = component.PhysicsBody;
|
|
if ( !body.IsValid() )
|
|
continue;
|
|
|
|
// Physics has gone to sleep, so it's not moving.
|
|
if ( body.Sleeping )
|
|
continue;
|
|
|
|
// Mark transform as changed so it gets networked over.
|
|
BodyTransforms.Set( i, body.Transform.WithScale( component.WorldScale ) );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Move proxy bodies to networked body transforms.
|
|
/// </summary>
|
|
void MoveProxyBodies()
|
|
{
|
|
var transforms = BodyTransforms.Entries;
|
|
|
|
foreach ( var (bodyIndex, transform) in transforms )
|
|
{
|
|
var component = Bodies[bodyIndex].Component;
|
|
if ( !component.IsValid() )
|
|
continue;
|
|
|
|
component.WorldScale = transform.Scale;
|
|
|
|
var body = component.PhysicsBody;
|
|
if ( !body.IsValid() )
|
|
continue;
|
|
|
|
// Take a bit longer to reach target to smooth it out a bit.
|
|
body.Move( transform, Time.Delta * 2.0f );
|
|
}
|
|
}
|
|
|
|
protected override void OnRefresh()
|
|
{
|
|
if ( !IsProxy )
|
|
return;
|
|
|
|
var transforms = BodyTransforms.Entries;
|
|
|
|
foreach ( var (bodyIndex, transform) in transforms )
|
|
{
|
|
var component = Bodies[bodyIndex].Component;
|
|
if ( !component.IsValid() )
|
|
continue;
|
|
|
|
// Set transform to initial networked transform so physics get created there.
|
|
component.GameObject.Flags = GameObjectFlags.Absolute;
|
|
component.WorldTransform = transform;
|
|
}
|
|
}
|
|
}
|