2024-10-23 17:55:55 +08:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Spine Runtimes License Agreement
2024-11-21 09:35:48 +08:00
* Last updated July 28 , 2023. Replaces all prior versions .
2024-10-23 17:55:55 +08:00
*
2024-11-21 09:35:48 +08:00
* Copyright ( c ) 2013 - 2023 , Esoteric Software LLC
2024-10-23 17:55:55 +08:00
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement :
* http : //esotericsoftware.com/spine-editor-license
*
2024-11-21 09:35:48 +08:00
* Otherwise , it is permitted to integrate the Spine Runtimes into software or
* otherwise create derivative works of the Spine Runtimes ( collectively ,
2024-10-23 17:55:55 +08:00
* "Products" ) , provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice .
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ,
* BUSINESS INTERRUPTION , OR LOSS OF USE , DATA , OR PROFITS ) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
2024-11-21 09:35:48 +08:00
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THE
* SPINE RUNTIMES , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
2024-10-23 17:55:55 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2024-11-21 09:35:48 +08:00
// Optimization option: Allows faster BuildMeshWithArrays call and avoids calling SetTriangles at the cost of
// checking for mesh differences (vertex counts, member-wise attachment list compare) every frame.
#define SPINE_TRIANGLECHECK
2024-10-23 17:55:55 +08:00
//#define SPINE_DEBUG
using System ;
using System.Collections.Generic ;
2024-11-21 09:35:48 +08:00
using UnityEngine ;
2024-10-23 17:55:55 +08:00
namespace Spine.Unity {
/// <summary>A double-buffered Mesh, and a shared material array, bundled for use by Spine components that need to push a Mesh and materials to a Unity MeshRenderer and MeshFilter.</summary>
public class MeshRendererBuffers : IDisposable {
DoubleBuffered < SmartMesh > doubleBufferedMesh ;
internal readonly ExposedList < Material > submeshMaterials = new ExposedList < Material > ( ) ;
internal Material [ ] sharedMaterials = new Material [ 0 ] ;
public void Initialize ( ) {
if ( doubleBufferedMesh ! = null ) {
doubleBufferedMesh . GetNext ( ) . Clear ( ) ;
doubleBufferedMesh . GetNext ( ) . Clear ( ) ;
submeshMaterials . Clear ( ) ;
} else {
doubleBufferedMesh = new DoubleBuffered < SmartMesh > ( ) ;
}
}
/// <summary>Returns a sharedMaterials array for use on a MeshRenderer.</summary>
/// <returns></returns>
public Material [ ] GetUpdatedSharedMaterialsArray ( ) {
if ( submeshMaterials . Count = = sharedMaterials . Length )
submeshMaterials . CopyTo ( sharedMaterials ) ;
else
sharedMaterials = submeshMaterials . ToArray ( ) ;
return sharedMaterials ;
}
/// <summary>Returns true if the materials were modified since the buffers were last updated.</summary>
public bool MaterialsChangedInLastUpdate ( ) {
int newSubmeshMaterials = submeshMaterials . Count ;
2024-11-21 09:35:48 +08:00
Material [ ] sharedMaterials = this . sharedMaterials ;
2024-10-23 17:55:55 +08:00
if ( newSubmeshMaterials ! = sharedMaterials . Length ) return true ;
2024-11-21 09:35:48 +08:00
Material [ ] submeshMaterialsItems = submeshMaterials . Items ;
2024-10-23 17:55:55 +08:00
for ( int i = 0 ; i < newSubmeshMaterials ; i + + )
if ( ! Material . ReferenceEquals ( submeshMaterialsItems [ i ] , sharedMaterials [ i ] ) ) return true ; //if (submeshMaterialsItems[i].GetInstanceID() != sharedMaterials[i].GetInstanceID()) return true;
return false ;
}
/// <summary>Updates the internal shared materials array with the given instruction list.</summary>
public void UpdateSharedMaterials ( ExposedList < SubmeshInstruction > instructions ) {
int newSize = instructions . Count ;
{ //submeshMaterials.Resize(instructions.Count);
if ( newSize > submeshMaterials . Items . Length )
Array . Resize ( ref submeshMaterials . Items , newSize ) ;
submeshMaterials . Count = newSize ;
}
2024-11-21 09:35:48 +08:00
Material [ ] submeshMaterialsItems = submeshMaterials . Items ;
SubmeshInstruction [ ] instructionsItems = instructions . Items ;
2024-10-23 17:55:55 +08:00
for ( int i = 0 ; i < newSize ; i + + )
submeshMaterialsItems [ i ] = instructionsItems [ i ] . material ;
}
public SmartMesh GetNextMesh ( ) {
return doubleBufferedMesh . GetNext ( ) ;
}
public void Clear ( ) {
sharedMaterials = new Material [ 0 ] ;
submeshMaterials . Clear ( ) ;
}
public void Dispose ( ) {
if ( doubleBufferedMesh = = null ) return ;
doubleBufferedMesh . GetNext ( ) . Dispose ( ) ;
doubleBufferedMesh . GetNext ( ) . Dispose ( ) ;
doubleBufferedMesh = null ;
}
2024-11-21 09:35:48 +08:00
/// <summary>This is a Mesh that also stores the instructions SkeletonRenderer generated for it.</summary>
2024-10-23 17:55:55 +08:00
public class SmartMesh : IDisposable {
public Mesh mesh = SpineMesh . NewSkeletonMesh ( ) ;
public SkeletonRendererInstruction instructionUsed = new SkeletonRendererInstruction ( ) ;
public void Clear ( ) {
mesh . Clear ( ) ;
instructionUsed . Clear ( ) ;
}
public void Dispose ( ) {
if ( mesh ! = null ) {
2024-11-21 09:35:48 +08:00
#if UNITY_EDITOR
2024-10-23 17:55:55 +08:00
if ( Application . isEditor & & ! Application . isPlaying )
UnityEngine . Object . DestroyImmediate ( mesh ) ;
else
UnityEngine . Object . Destroy ( mesh ) ;
2024-11-21 09:35:48 +08:00
#else
2024-10-23 17:55:55 +08:00
UnityEngine . Object . Destroy ( mesh ) ;
2024-11-21 09:35:48 +08:00
#endif
2024-10-23 17:55:55 +08:00
}
mesh = null ;
}
}
}
}