Files
sbox-public/engine/Sandbox.Engine/Scene/Components/Render/SkinnedModelRenderer.Morphs.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

155 lines
2.6 KiB
C#

using System.Text.Json.Nodes;
namespace Sandbox;
public partial class SkinnedModelRenderer
{
MorphAccessor _morphs;
/// <summary>
/// Access to the morphs for this model
/// </summary>
[Property, Group( "Morphs", StartFolded = true ), ShowIf( "ShouldShowMorphsEditor", true )]
public MorphAccessor Morphs
{
get
{
_morphs ??= new( this );
return _morphs;
}
}
public bool ShouldShowMorphsEditor
{
get
{
if ( Model is null ) return false;
if ( Model.Morphs.Count == 0 ) return false;
// todo - should we hide if we're bone merged?
return true;
}
}
public sealed class MorphAccessor : IJsonPopulator
{
Dictionary<string, float> _values = new Dictionary<string, float>( StringComparer.OrdinalIgnoreCase );
ModelRenderer renderer;
internal MorphAccessor( ModelRenderer renderer )
{
this.renderer = renderer;
}
public string[] Names
{
get
{
if ( renderer.Model is not null )
{
return renderer.Model.Morphs.Names;
}
return null;
}
}
/// <summary>
/// Set this value
/// </summary>
public void Set( string name, float f )
{
_values[name] = f;
if ( renderer.SceneObject is SceneModel model )
{
model.Morphs.Set( name, f );
}
}
/// <summary>
/// Returns true if we have this value overridden (set). False means its value is likely
/// being driven by animation etc.
/// </summary>
public bool ContainsOverride( string name )
{
return _values.ContainsKey( name );
}
/// <summary>
/// Get this value
/// </summary>
public float Get( string name )
{
if ( _values.TryGetValue( name, out var value ) )
{
return value;
}
if ( renderer.SceneObject is SceneModel model )
{
return model.Morphs.Get( name );
}
return default;
}
/// <summary>
/// Clear this value, don't override it
/// </summary>
public void Clear( string name )
{
_values.Remove( name );
if ( renderer.SceneObject is SceneModel model )
{
model.Morphs.Reset( name );
}
}
internal void Apply()
{
if ( renderer.SceneObject is not SceneModel model )
return;
model.Morphs.ResetAll();
foreach ( var value in _values )
{
model.Morphs.Set( value.Key, value.Value );
}
}
JsonNode IJsonPopulator.Serialize()
{
var obj = new JsonObject();
foreach ( var value in _values )
{
obj.Add( value.Key, value.Value );
}
return obj;
}
void IJsonPopulator.Deserialize( JsonNode e )
{
if ( e is not JsonObject jso )
return;
_values.Clear();
foreach ( var o in jso )
{
_values[o.Key] = o.Value.GetValue<float>();
}
}
}
}