mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Per-MeshRenderer Custom Material Override
This commit is contained in:
parent
ec268a50e0
commit
1589d147f9
@ -31,6 +31,7 @@
|
|||||||
#define SPINE_OPTIONAL_NORMALS
|
#define SPINE_OPTIONAL_NORMALS
|
||||||
#define SPINE_OPTIONAL_FRONTFACING
|
#define SPINE_OPTIONAL_FRONTFACING
|
||||||
#define SPINE_OPTIONAL_RENDEROVERRIDE
|
#define SPINE_OPTIONAL_RENDEROVERRIDE
|
||||||
|
#define SPINE_OPTIONAL_MATERIALOVERRIDE
|
||||||
//#define SPINE_OPTIONAL_SUBMESHRENDERER // Deprecated
|
//#define SPINE_OPTIONAL_SUBMESHRENDERER // Deprecated
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -96,29 +97,31 @@ namespace Spine.Unity {
|
|||||||
private Spine.Unity.Modules.SkeletonUtilitySubmeshRenderer[] submeshRenderers;
|
private Spine.Unity.Modules.SkeletonUtilitySubmeshRenderer[] submeshRenderers;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SPINE_OPTIONAL_MATERIALOVERRIDE
|
||||||
|
[System.NonSerialized] readonly Dictionary<Material, Material> customMaterialOverride = new Dictionary<Material, Material>();
|
||||||
|
public Dictionary<Material, Material> CustomMaterialOverride { get { return customMaterialOverride; } }
|
||||||
|
#endif
|
||||||
|
|
||||||
// Custom Slot Material
|
// Custom Slot Material
|
||||||
[System.NonSerialized] readonly Dictionary<Slot, Material> customSlotMaterials = new Dictionary<Slot, Material>();
|
[System.NonSerialized] readonly Dictionary<Slot, Material> customSlotMaterials = new Dictionary<Slot, Material>();
|
||||||
public Dictionary<Slot, Material> CustomSlotMaterials { get { return customSlotMaterials; } }
|
public Dictionary<Slot, Material> CustomSlotMaterials { get { return customSlotMaterials; } }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
[System.NonSerialized] public bool valid;
|
|
||||||
[System.NonSerialized] public Skeleton skeleton;
|
|
||||||
|
|
||||||
MeshRenderer meshRenderer;
|
MeshRenderer meshRenderer;
|
||||||
MeshFilter meshFilter;
|
MeshFilter meshFilter;
|
||||||
|
|
||||||
|
[System.NonSerialized] public bool valid;
|
||||||
|
[System.NonSerialized] public Skeleton skeleton;
|
||||||
|
|
||||||
Spine.Unity.DoubleBuffered<SkeletonRenderer.SmartMesh> doubleBufferedMesh;
|
Spine.Unity.DoubleBuffered<SkeletonRenderer.SmartMesh> doubleBufferedMesh;
|
||||||
readonly SmartMesh.Instruction currentInstructions = new SmartMesh.Instruction();
|
readonly SmartMesh.Instruction currentInstructions = new SmartMesh.Instruction();
|
||||||
readonly ExposedList<SubmeshTriangleBuffer> submeshes = new ExposedList<SubmeshTriangleBuffer>();
|
readonly ExposedList<SubmeshTriangleBuffer> submeshes = new ExposedList<SubmeshTriangleBuffer>();
|
||||||
|
readonly ExposedList<Material> submeshMaterials = new ExposedList<Material>();
|
||||||
|
Material[] sharedMaterials = new Material[0];
|
||||||
float[] tempVertices = new float[8];
|
float[] tempVertices = new float[8];
|
||||||
Vector3[] vertices;
|
Vector3[] vertices;
|
||||||
Color32[] colors;
|
Color32[] colors;
|
||||||
Vector2[] uvs;
|
Vector2[] uvs;
|
||||||
|
|
||||||
readonly ExposedList<Material> submeshMaterials = new ExposedList<Material>();
|
|
||||||
Material[] sharedMaterials = new Material[0];
|
|
||||||
|
|
||||||
#if SPINE_OPTIONAL_NORMALS
|
#if SPINE_OPTIONAL_NORMALS
|
||||||
Vector3[] normals;
|
Vector3[] normals;
|
||||||
Vector4[] tangents;
|
Vector4[] tangents;
|
||||||
@ -254,7 +257,7 @@ namespace Spine.Unity {
|
|||||||
var workingSubmeshInstructions = workingInstruction.submeshInstructions; // Items array should not be cached. There is dynamic writing to this list.
|
var workingSubmeshInstructions = workingInstruction.submeshInstructions; // Items array should not be cached. There is dynamic writing to this list.
|
||||||
workingSubmeshInstructions.Clear(false);
|
workingSubmeshInstructions.Clear(false);
|
||||||
|
|
||||||
bool isCustomMaterialsPopulated = customSlotMaterials.Count > 0;
|
bool isCustomSlotMaterialsPopulated = customSlotMaterials.Count > 0;
|
||||||
|
|
||||||
int vertexCount = 0;
|
int vertexCount = 0;
|
||||||
int submeshVertexCount = 0;
|
int submeshVertexCount = 0;
|
||||||
@ -302,7 +305,7 @@ namespace Spine.Unity {
|
|||||||
// Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject; // For no customSlotMaterials
|
// Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject; // For no customSlotMaterials
|
||||||
|
|
||||||
Material material;
|
Material material;
|
||||||
if (isCustomMaterialsPopulated) {
|
if (isCustomSlotMaterialsPopulated) {
|
||||||
if (!customSlotMaterials.TryGetValue(slot, out material)) {
|
if (!customSlotMaterials.TryGetValue(slot, out material)) {
|
||||||
material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
|
material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
|
||||||
}
|
}
|
||||||
@ -360,6 +363,24 @@ namespace Spine.Unity {
|
|||||||
workingInstruction.frontFacing = this.frontFacing;
|
workingInstruction.frontFacing = this.frontFacing;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// STEP 1.9. Post-process workingInstructions.
|
||||||
|
|
||||||
|
#if SPINE_OPTIONAL_MATERIALOVERRIDE
|
||||||
|
// Material overrides are done here so they can be applied per submesh instead of per slot
|
||||||
|
// but they will still be passed through the GenerateMeshOverride delegate,
|
||||||
|
// and will still go through the normal material match check step in STEP 3.
|
||||||
|
if (customMaterialOverride.Count > 0) { // isCustomMaterialOverridePopulated
|
||||||
|
var workingSubmeshInstructionsItems = workingSubmeshInstructions.Items;
|
||||||
|
for (int i = 0; i < workingSubmeshInstructions.Count; i++) {
|
||||||
|
var m = workingSubmeshInstructionsItems[i].material;
|
||||||
|
Material mo;
|
||||||
|
if (customMaterialOverride.TryGetValue(m, out mo)) {
|
||||||
|
workingSubmeshInstructionsItems[i].material = mo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SPINE_OPTIONAL_RENDEROVERRIDE
|
#if SPINE_OPTIONAL_RENDEROVERRIDE
|
||||||
if (this.generateMeshOverride != null) {
|
if (this.generateMeshOverride != null) {
|
||||||
this.generateMeshOverride(workingInstruction);
|
this.generateMeshOverride(workingInstruction);
|
||||||
@ -616,6 +637,11 @@ namespace Spine.Unity {
|
|||||||
currentMesh.vertices = vertices;
|
currentMesh.vertices = vertices;
|
||||||
currentMesh.colors32 = colors;
|
currentMesh.colors32 = colors;
|
||||||
currentMesh.uv = uvs;
|
currentMesh.uv = uvs;
|
||||||
|
|
||||||
|
Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;
|
||||||
|
Vector3 meshBoundsCenter = meshBoundsMin + meshBoundsExtents * 0.5f;
|
||||||
|
currentMesh.bounds = new Bounds(meshBoundsCenter, meshBoundsExtents);
|
||||||
|
|
||||||
var currentSmartMeshInstructionUsed = currentSmartMesh.instructionUsed;
|
var currentSmartMeshInstructionUsed = currentSmartMesh.instructionUsed;
|
||||||
#if SPINE_OPTIONAL_NORMALS
|
#if SPINE_OPTIONAL_NORMALS
|
||||||
if (currentSmartMeshInstructionUsed.vertexCount < vertexCount) {
|
if (currentSmartMeshInstructionUsed.vertexCount < vertexCount) {
|
||||||
@ -660,10 +686,6 @@ namespace Spine.Unity {
|
|||||||
currentMesh.SetTriangles(submeshes.Items[i].triangles, i);
|
currentMesh.SetTriangles(submeshes.Items[i].triangles, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;
|
|
||||||
Vector3 meshBoundsCenter = meshBoundsMin + meshBoundsExtents * 0.5f;
|
|
||||||
currentMesh.bounds = new Bounds(meshBoundsCenter, meshBoundsExtents);
|
|
||||||
|
|
||||||
// CheckIfMustUpdateMaterialArray (last pushed materials vs currently parsed materials)
|
// CheckIfMustUpdateMaterialArray (last pushed materials vs currently parsed materials)
|
||||||
// Needs to check against the Working Submesh Instructions Materials instead of the cached submeshMaterials.
|
// Needs to check against the Working Submesh Instructions Materials instead of the cached submeshMaterials.
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user