Files
sbox-public/engine/Sandbox.Engine/Scene/Components/Render/ModelRenderer.Materials.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

110 lines
2.6 KiB
C#

namespace Sandbox;
using Sandbox.Engine;
//
// TODO
//
// 1. Move MaterialOverride to Materials, somehow.
// 2. Make SetMaterialOverride with attribute targets obsolete (need to fix avatar/skin stuff)
//
public partial class ModelRenderer : MaterialAccessor.ITarget
{
[Property, MakeDirty]
public Material MaterialOverride { get; set; }
Dictionary<string, Material> taggedMaterialOverrides;
/// <summary>
/// Completely stop overriding materials
/// </summary>
public void ClearMaterialOverrides()
{
taggedMaterialOverrides = null;
MaterialOverride = null;
_sceneObject?.ClearMaterialOverride();
}
/// <summary>
/// Set a material override for a material with a specific attribute set. For example, if you have a model with lots of different materials, but one of them has an attribute "skin" set to "1", then
/// calling this with a material and "skin" will override only that material.
/// </summary>
public void SetMaterialOverride( Material material, string target )
{
if ( material is null && taggedMaterialOverrides is null )
return;
taggedMaterialOverrides ??= new Dictionary<string, Material>();
if ( material is null )
{
taggedMaterialOverrides.Remove( target );
_sceneObject?.SetMaterialOverride( null, target );
}
else
{
taggedMaterialOverrides[target] = material;
}
ApplyMaterialOverrides();
}
/// <summary>
/// Apply any saved material overrides to the scene object.
/// </summary>
void ApplyMaterialOverrides()
{
if ( !_sceneObject.IsValid() ) return;
if ( taggedMaterialOverrides is not null )
{
foreach ( var o in taggedMaterialOverrides )
{
_sceneObject.SetMaterialOverride( o.Value, o.Key );
}
}
_materialAccessor?.Apply();
}
MaterialAccessor _materialAccessor;
/// <summary>
/// Access to the materials
/// </summary>
[Property, Group( "Materials", StartFolded = true )]
public MaterialAccessor Materials => _materialAccessor ??= new MaterialAccessor( this );
int MaterialAccessor.ITarget.GetMaterialCount()
{
if ( !Model.IsValid() ) return 0;
return Model.Materials.Length;
}
Material MaterialAccessor.ITarget.Get( int index )
{
if ( !Model.IsValid() ) return default;
if ( index < 0 ) return default;
if ( index >= Model.Materials.Length ) return default;
return Model.Materials[index];
}
void MaterialAccessor.ITarget.SetOverride( int index, Material material )
{
if ( !_sceneObject.IsValid() ) return;
_sceneObject.native.SetMaterialOverrideByIndex( index, material?.native ?? default );
}
void MaterialAccessor.ITarget.ClearOverrides()
{
if ( !_sceneObject.IsValid() ) return;
_sceneObject.native.ClearMaterialOverrideList();
}
}