mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-17 18:59:27 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
372 lines
9.4 KiB
C#
372 lines
9.4 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Nodes;
|
|
|
|
namespace Sandbox;
|
|
|
|
public sealed partial class SkinnedModelRenderer
|
|
{
|
|
/// <summary>
|
|
/// If something sets parameters before the model is spawned, then we store them
|
|
/// and apply them when it does spawn. This isn't ideal, but it is what it is.
|
|
/// </summary>
|
|
readonly Dictionary<string, object> parameters = new( StringComparer.OrdinalIgnoreCase );
|
|
|
|
public void Set( string v, Vector3 value )
|
|
{
|
|
parameters[v] = value;
|
|
SceneModel?.SetAnimParameter( v, value );
|
|
}
|
|
|
|
public void Set( string v, int value )
|
|
{
|
|
parameters[v] = value;
|
|
SceneModel?.SetAnimParameter( v, value );
|
|
}
|
|
|
|
public void Set( string v, float value )
|
|
{
|
|
parameters[v] = value;
|
|
SceneModel?.SetAnimParameter( v, value );
|
|
}
|
|
public void Set( string v, bool value )
|
|
{
|
|
parameters[v] = value;
|
|
SceneModel?.SetAnimParameter( v, value );
|
|
}
|
|
|
|
public void Set( string v, Rotation value )
|
|
{
|
|
parameters[v] = value;
|
|
SceneModel?.SetAnimParameter( v, value );
|
|
}
|
|
|
|
void ApplyStoredAnimParameters()
|
|
{
|
|
foreach ( var p in parameters )
|
|
{
|
|
if ( p.Value is Vector3 v ) SceneModel.SetAnimParameter( p.Key, v );
|
|
if ( p.Value is float f ) SceneModel.SetAnimParameter( p.Key, f );
|
|
if ( p.Value is int i ) SceneModel.SetAnimParameter( p.Key, i );
|
|
if ( p.Value is bool b ) SceneModel.SetAnimParameter( p.Key, b );
|
|
if ( p.Value is Rotation r ) SceneModel.SetAnimParameter( p.Key, r );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove any stored parameters
|
|
/// </summary>
|
|
public void ClearParameters()
|
|
{
|
|
parameters.Clear();
|
|
|
|
if ( SceneModel.IsValid() )
|
|
{
|
|
SceneModel.ResetAnimParameters();
|
|
}
|
|
}
|
|
|
|
internal void ClearParameter( string name )
|
|
{
|
|
parameters.Remove( name );
|
|
}
|
|
|
|
internal bool ContainsParameter( string name )
|
|
{
|
|
return parameters.ContainsKey( name );
|
|
}
|
|
|
|
// public void Set( string v, Enum value ) => _sceneObject.SetAnimParameter( v, value );
|
|
|
|
public bool GetBool( string v ) => SceneModel?.GetBool( v ) ?? false;
|
|
public int GetInt( string v ) => SceneModel?.GetInt( v ) ?? 0;
|
|
public float GetFloat( string v ) => SceneModel?.GetFloat( v ) ?? 0.0f;
|
|
public Vector3 GetVector( string v ) => SceneModel?.GetVector3( v ) ?? Vector3.Zero;
|
|
public Rotation GetRotation( string v ) => SceneModel?.GetRotation( v ) ?? Rotation.Identity;
|
|
|
|
/// <summary>
|
|
/// Converts value to vector local to this entity's eyepos and passes it to SetAnimVector
|
|
/// </summary>
|
|
public void SetLookDirection( string name, Vector3 eyeDirectionWorld )
|
|
{
|
|
var delta = eyeDirectionWorld * WorldRotation.Inverse;
|
|
Set( name, delta );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts value to vector local to this entity's eyepos and passes it to SetAnimVector.
|
|
/// This also sets {name}_weight to the weight value.
|
|
/// </summary>
|
|
public void SetLookDirection( string name, Vector3 eyeDirectionWorld, float weight )
|
|
{
|
|
var delta = eyeDirectionWorld * WorldRotation.Inverse;
|
|
Set( name, delta );
|
|
Set( $"{name}_weight", weight );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets an IK parameter. This sets 3 variables that should be set in the animgraph:
|
|
/// 1. ik.{name}.enabled
|
|
/// 2. ik.{name}.position
|
|
/// 3. ik.{name}.rotation
|
|
/// </summary>
|
|
public void SetIk( string name, Transform tx )
|
|
{
|
|
// convert local to model
|
|
tx = WorldTransform.ToLocal( tx );
|
|
|
|
Set( $"ik.{name}.enabled", true );
|
|
Set( $"ik.{name}.position", tx.Position );
|
|
Set( $"ik.{name}.rotation", tx.Rotation );
|
|
}
|
|
|
|
/// <summary>
|
|
/// This sets ik.{name}.enabled to false.
|
|
/// </summary>
|
|
public void ClearIk( string name )
|
|
{
|
|
Set( $"ik.{name}.enabled", false );
|
|
}
|
|
|
|
ParameterAccessor _parameters;
|
|
|
|
/// <summary>
|
|
/// Access to the animgraph parameters for this model
|
|
/// </summary>
|
|
[Property, Group( "Parameters", StartFolded = true ), ShowIf( nameof( ShouldShowParametersEditor ), true )]
|
|
public ParameterAccessor Parameters
|
|
{
|
|
get
|
|
{
|
|
_parameters ??= new( this );
|
|
return _parameters;
|
|
}
|
|
}
|
|
|
|
public bool ShouldShowParametersEditor
|
|
{
|
|
get
|
|
{
|
|
if ( !UseAnimGraph ) return false;
|
|
if ( !SceneModel.IsValid() ) return false;
|
|
|
|
var graph = SceneModel.AnimationGraph;
|
|
if ( graph is null ) return false;
|
|
if ( graph.ParamCount <= 0 ) return false;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public sealed class ParameterAccessor : IJsonPopulator
|
|
{
|
|
public AnimationGraph Graph => _renderer.IsValid() && _renderer.SceneModel.IsValid() ?
|
|
_renderer.SceneModel.AnimationGraph : null;
|
|
|
|
readonly SkinnedModelRenderer _renderer;
|
|
readonly Dictionary<string, bool> _bools = new( StringComparer.OrdinalIgnoreCase );
|
|
readonly Dictionary<string, int> _ints = new( StringComparer.OrdinalIgnoreCase );
|
|
readonly Dictionary<string, float> _floats = new( StringComparer.OrdinalIgnoreCase );
|
|
readonly Dictionary<string, Vector3> _vectors = new( StringComparer.OrdinalIgnoreCase );
|
|
readonly Dictionary<string, Rotation> _rotations = new( StringComparer.OrdinalIgnoreCase );
|
|
|
|
internal ParameterAccessor( SkinnedModelRenderer renderer )
|
|
{
|
|
_renderer = renderer;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
_bools.Clear();
|
|
_ints.Clear();
|
|
_floats.Clear();
|
|
_vectors.Clear();
|
|
_rotations.Clear();
|
|
|
|
_renderer.ClearParameters();
|
|
}
|
|
|
|
public void Reset( string name )
|
|
{
|
|
var parameter = Graph.GetParameterFromList( name );
|
|
if ( parameter.IsNull )
|
|
return;
|
|
|
|
var defaultValue = parameter.GetDefaultValue();
|
|
|
|
switch ( parameter.GetParameterType() )
|
|
{
|
|
case NativeEngine.AnimParamType.Float:
|
|
Set( name, defaultValue.GetValue<float>() );
|
|
break;
|
|
case NativeEngine.AnimParamType.Int:
|
|
Set( name, defaultValue.GetValue<int>() );
|
|
break;
|
|
case NativeEngine.AnimParamType.Enum:
|
|
Set( name, defaultValue.GetValue<byte>() );
|
|
break;
|
|
case NativeEngine.AnimParamType.Bool:
|
|
Set( name, defaultValue.GetValue<bool>() );
|
|
break;
|
|
case NativeEngine.AnimParamType.Vector:
|
|
Set( name, defaultValue.GetValue<Vector3>() );
|
|
break;
|
|
case NativeEngine.AnimParamType.Rotation:
|
|
Set( name, defaultValue.GetValue<Rotation>() );
|
|
break;
|
|
default:
|
|
throw new NotSupportedException( $"Unsupported parameter type: {parameter.GetParameterType()}" );
|
|
}
|
|
}
|
|
|
|
public void Clear( string name )
|
|
{
|
|
Reset( name );
|
|
|
|
_bools.Remove( name );
|
|
_ints.Remove( name );
|
|
_floats.Remove( name );
|
|
_vectors.Remove( name );
|
|
_rotations.Remove( name );
|
|
|
|
_renderer.ClearParameter( name );
|
|
}
|
|
|
|
public bool Contains( string name )
|
|
{
|
|
return _renderer.ContainsParameter( name );
|
|
}
|
|
|
|
public bool GetBool( string v ) => _renderer.GetBool( v );
|
|
public int GetInt( string v ) => _renderer.GetInt( v );
|
|
public float GetFloat( string v ) => _renderer.GetFloat( v );
|
|
public Vector3 GetVector( string v ) => _renderer.GetVector( v );
|
|
public Rotation GetRotation( string v ) => _renderer.GetRotation( v );
|
|
|
|
public void Set( string v, Vector3 value )
|
|
{
|
|
_vectors[v] = value;
|
|
_renderer.Set( v, value );
|
|
}
|
|
|
|
public void Set( string v, int value )
|
|
{
|
|
_ints[v] = value;
|
|
_renderer.Set( v, value );
|
|
}
|
|
|
|
public void Set( string v, float value )
|
|
{
|
|
_floats[v] = value;
|
|
_renderer.Set( v, value );
|
|
}
|
|
|
|
public void Set( string v, bool value )
|
|
{
|
|
_bools[v] = value;
|
|
_renderer.Set( v, value );
|
|
}
|
|
|
|
public void Set( string v, Rotation value )
|
|
{
|
|
_rotations[v] = value;
|
|
_renderer.Set( v, value );
|
|
}
|
|
|
|
JsonNode IJsonPopulator.Serialize()
|
|
{
|
|
var obj = new JsonObject();
|
|
|
|
var boolsObj = new JsonObject();
|
|
var intsObj = new JsonObject();
|
|
var floatsObj = new JsonObject();
|
|
var vectorsObj = new JsonObject();
|
|
var rotationsObj = new JsonObject();
|
|
|
|
foreach ( var value in _bools )
|
|
{
|
|
boolsObj.Add( value.Key, value.Value );
|
|
}
|
|
|
|
foreach ( var value in _ints )
|
|
{
|
|
intsObj.Add( value.Key, value.Value );
|
|
}
|
|
|
|
foreach ( var value in _floats )
|
|
{
|
|
floatsObj.Add( value.Key, value.Value );
|
|
}
|
|
|
|
foreach ( var value in _vectors )
|
|
{
|
|
vectorsObj.Add( value.Key, JsonSerializer.SerializeToNode( value.Value ) );
|
|
}
|
|
|
|
foreach ( var value in _rotations )
|
|
{
|
|
rotationsObj.Add( value.Key, JsonSerializer.SerializeToNode( value.Value ) );
|
|
}
|
|
|
|
obj.Add( "bools", boolsObj );
|
|
obj.Add( "ints", intsObj );
|
|
obj.Add( "floats", floatsObj );
|
|
obj.Add( "vectors", vectorsObj );
|
|
obj.Add( "rotations", rotationsObj );
|
|
|
|
return obj;
|
|
}
|
|
|
|
void IJsonPopulator.Deserialize( JsonNode e )
|
|
{
|
|
if ( e is not JsonObject jso )
|
|
return;
|
|
|
|
_bools.Clear();
|
|
_ints.Clear();
|
|
_floats.Clear();
|
|
_vectors.Clear();
|
|
_rotations.Clear();
|
|
|
|
if ( jso.TryGetPropertyValue( "bools", out var boolsNode ) && boolsNode is JsonObject boolsObj )
|
|
{
|
|
foreach ( var o in boolsObj )
|
|
{
|
|
Set( o.Key, o.Value.GetValue<bool>() );
|
|
}
|
|
}
|
|
|
|
if ( jso.TryGetPropertyValue( "ints", out var intsNode ) && intsNode is JsonObject intsObj )
|
|
{
|
|
foreach ( var o in intsObj )
|
|
{
|
|
Set( o.Key, o.Value.GetValue<int>() );
|
|
}
|
|
}
|
|
|
|
if ( jso.TryGetPropertyValue( "floats", out var floatsNode ) && floatsNode is JsonObject floatsObj )
|
|
{
|
|
foreach ( var o in floatsObj )
|
|
{
|
|
Set( o.Key, o.Value.GetValue<float>() );
|
|
}
|
|
}
|
|
|
|
if ( jso.TryGetPropertyValue( "vectors", out var vectorsNode ) && vectorsNode is JsonObject vectorsObj )
|
|
{
|
|
foreach ( var o in vectorsObj )
|
|
{
|
|
Set( o.Key, JsonSerializer.Deserialize<Vector3>( o.Value ) );
|
|
}
|
|
}
|
|
|
|
if ( jso.TryGetPropertyValue( "rotations", out var rotationsNode ) && rotationsNode is JsonObject rotationsObj )
|
|
{
|
|
foreach ( var o in rotationsObj )
|
|
{
|
|
Set( o.Key, JsonSerializer.Deserialize<Rotation>( o.Value ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|