mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-23 02:06:46 +08:00
[unity] Cleanup: Split the file Mesh Generation/SpineMesh into 4 separate files for each contained class. No API changes.
This commit is contained in:
parent
dad97ecc06
commit
e898ff829c
@ -183,7 +183,8 @@
|
|||||||
* Moved `Modules/AnimationMatchModifier` directory to `Spine Examples/Scripts/MecanimAnimationMatchModifier`.
|
* Moved `Modules/AnimationMatchModifier` directory to `Spine Examples/Scripts/MecanimAnimationMatchModifier`.
|
||||||
* Moved `SkeletonRagdoll` and `SkeletonRagdoll2D` components from `Modules/Ragdoll` directory to `Spine Examples/Scripts/Sample Components/SkeletonUtility Modules`.
|
* Moved `SkeletonRagdoll` and `SkeletonRagdoll2D` components from `Modules/Ragdoll` directory to `Spine Examples/Scripts/Sample Components/SkeletonUtility Modules`.
|
||||||
* Moved `AttachmentTools.cs` to `Utility` directory.
|
* Moved `AttachmentTools.cs` to `Utility` directory.
|
||||||
* Split the file `AttachmentTools` into 4 new files for each contained class. No namespace or other API changes performed.
|
* Split the file `AttachmentTools` into 5 separate files for each contained class. No namespace or other API changes performed.
|
||||||
|
* Split the file `Mesh Generation/SpineMesh` into 4 separate files for each contained class. No namespace or other API changes performed.
|
||||||
* Moved `SkeletonExtensions.cs` to `Utility` directory.
|
* Moved `SkeletonExtensions.cs` to `Utility` directory.
|
||||||
* Moved `Modules/YieldInstructions` directory to `Utility/YieldInstructions`.
|
* Moved `Modules/YieldInstructions` directory to `Utility/YieldInstructions`.
|
||||||
* Moved corresponding editor scripts of the above components to restructured directories as well.
|
* Moved corresponding editor scripts of the above components to restructured directories as well.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,12 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 311447d6e56727c4dad7611d5fa5afbf
|
||||||
|
timeCreated: 1563322425
|
||||||
|
licenseType: Free
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,135 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes License Agreement
|
||||||
|
* Last updated May 1, 2019. Replaces all prior versions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||||
|
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||||
|
* "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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS 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 (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// Not for optimization. Do not disable.
|
||||||
|
#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame.
|
||||||
|
//#define SPINE_DEBUG
|
||||||
|
|
||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
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;
|
||||||
|
var sharedMaterials = this.sharedMaterials;
|
||||||
|
if (newSubmeshMaterials != sharedMaterials.Length) return true;
|
||||||
|
|
||||||
|
var submeshMaterialsItems = submeshMaterials.Items;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
var submeshMaterialsItems = submeshMaterials.Items;
|
||||||
|
var instructionsItems = instructions.Items;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
///<summary>This is a Mesh that also stores the instructions SkeletonRenderer generated for it.</summary>
|
||||||
|
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) {
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (Application.isEditor && !Application.isPlaying)
|
||||||
|
UnityEngine.Object.DestroyImmediate(mesh);
|
||||||
|
else
|
||||||
|
UnityEngine.Object.Destroy(mesh);
|
||||||
|
#else
|
||||||
|
UnityEngine.Object.Destroy(mesh);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
mesh = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b1ab80744ac17724dbc0d15fdb6f4727
|
||||||
|
timeCreated: 1563322425
|
||||||
|
licenseType: Free
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,178 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes License Agreement
|
||||||
|
* Last updated May 1, 2019. Replaces all prior versions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||||
|
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||||
|
* "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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS 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 (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// Not for optimization. Do not disable.
|
||||||
|
#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame.
|
||||||
|
//#define SPINE_DEBUG
|
||||||
|
|
||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Spine.Unity {
|
||||||
|
/// <summary>Instructions used by a SkeletonRenderer to render a mesh.</summary>
|
||||||
|
public class SkeletonRendererInstruction {
|
||||||
|
public readonly ExposedList<SubmeshInstruction> submeshInstructions = new ExposedList<SubmeshInstruction>();
|
||||||
|
|
||||||
|
public bool immutableTriangles;
|
||||||
|
#if SPINE_TRIANGLECHECK
|
||||||
|
public bool hasActiveClipping;
|
||||||
|
public int rawVertexCount = -1;
|
||||||
|
public readonly ExposedList<Attachment> attachments = new ExposedList<Attachment>();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public void Clear () {
|
||||||
|
#if SPINE_TRIANGLECHECK
|
||||||
|
this.attachments.Clear(false);
|
||||||
|
rawVertexCount = -1;
|
||||||
|
hasActiveClipping = false;
|
||||||
|
#endif
|
||||||
|
this.submeshInstructions.Clear(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose () {
|
||||||
|
attachments.Clear(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetWithSubset (ExposedList<SubmeshInstruction> instructions, int startSubmesh, int endSubmesh) {
|
||||||
|
#if SPINE_TRIANGLECHECK
|
||||||
|
int runningVertexCount = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var submeshes = this.submeshInstructions;
|
||||||
|
submeshes.Clear(false);
|
||||||
|
int submeshCount = endSubmesh - startSubmesh;
|
||||||
|
submeshes.Resize(submeshCount);
|
||||||
|
var submeshesItems = submeshes.Items;
|
||||||
|
var instructionsItems = instructions.Items;
|
||||||
|
for (int i = 0; i < submeshCount; i++) {
|
||||||
|
var instruction = instructionsItems[startSubmesh + i];
|
||||||
|
submeshesItems[i] = instruction;
|
||||||
|
#if SPINE_TRIANGLECHECK
|
||||||
|
this.hasActiveClipping |= instruction.hasClipping;
|
||||||
|
submeshesItems[i].rawFirstVertexIndex = runningVertexCount; // Ensure current instructions have correct cached values.
|
||||||
|
runningVertexCount += instruction.rawVertexCount; // vertexCount will also be used for the rest of this method.
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if SPINE_TRIANGLECHECK
|
||||||
|
this.rawVertexCount = runningVertexCount;
|
||||||
|
|
||||||
|
// assumption: instructions are contiguous. start and end are valid within instructions.
|
||||||
|
|
||||||
|
int startSlot = instructionsItems[startSubmesh].startSlot;
|
||||||
|
int endSlot = instructionsItems[endSubmesh - 1].endSlot;
|
||||||
|
attachments.Clear(false);
|
||||||
|
int attachmentCount = endSlot - startSlot;
|
||||||
|
attachments.Resize(attachmentCount);
|
||||||
|
var attachmentsItems = attachments.Items;
|
||||||
|
|
||||||
|
var drawOrderItems = instructionsItems[0].skeleton.drawOrder.Items;
|
||||||
|
for (int i = 0; i < attachmentCount; i++) {
|
||||||
|
Slot slot = drawOrderItems[startSlot + i];
|
||||||
|
if (!slot.bone.active) continue;
|
||||||
|
attachmentsItems[i] = slot.attachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set (SkeletonRendererInstruction other) {
|
||||||
|
this.immutableTriangles = other.immutableTriangles;
|
||||||
|
|
||||||
|
#if SPINE_TRIANGLECHECK
|
||||||
|
this.hasActiveClipping = other.hasActiveClipping;
|
||||||
|
this.rawVertexCount = other.rawVertexCount;
|
||||||
|
this.attachments.Clear(false);
|
||||||
|
this.attachments.EnsureCapacity(other.attachments.Capacity);
|
||||||
|
this.attachments.Count = other.attachments.Count;
|
||||||
|
other.attachments.CopyTo(this.attachments.Items);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this.submeshInstructions.Clear(false);
|
||||||
|
this.submeshInstructions.EnsureCapacity(other.submeshInstructions.Capacity);
|
||||||
|
this.submeshInstructions.Count = other.submeshInstructions.Count;
|
||||||
|
other.submeshInstructions.CopyTo(this.submeshInstructions.Items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool GeometryNotEqual (SkeletonRendererInstruction a, SkeletonRendererInstruction b) {
|
||||||
|
#if SPINE_TRIANGLECHECK
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (!Application.isPlaying)
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (a.hasActiveClipping || b.hasActiveClipping) return true; // Triangles are unpredictable when clipping is active.
|
||||||
|
|
||||||
|
// Everything below assumes the raw vertex and triangle counts were used. (ie, no clipping was done)
|
||||||
|
if (a.rawVertexCount != b.rawVertexCount) return true;
|
||||||
|
|
||||||
|
if (a.immutableTriangles != b.immutableTriangles) return true;
|
||||||
|
|
||||||
|
int attachmentCountB = b.attachments.Count;
|
||||||
|
if (a.attachments.Count != attachmentCountB) return true; // Bounds check for the looped storedAttachments count below.
|
||||||
|
|
||||||
|
// Submesh count changed
|
||||||
|
int submeshCountA = a.submeshInstructions.Count;
|
||||||
|
int submeshCountB = b.submeshInstructions.Count;
|
||||||
|
if (submeshCountA != submeshCountB) return true;
|
||||||
|
|
||||||
|
// Submesh Instruction mismatch
|
||||||
|
var submeshInstructionsItemsA = a.submeshInstructions.Items;
|
||||||
|
var submeshInstructionsItemsB = b.submeshInstructions.Items;
|
||||||
|
|
||||||
|
var attachmentsA = a.attachments.Items;
|
||||||
|
var attachmentsB = b.attachments.Items;
|
||||||
|
for (int i = 0; i < attachmentCountB; i++)
|
||||||
|
if (!System.Object.ReferenceEquals(attachmentsA[i], attachmentsB[i])) return true;
|
||||||
|
|
||||||
|
for (int i = 0; i < submeshCountB; i++) {
|
||||||
|
var submeshA = submeshInstructionsItemsA[i];
|
||||||
|
var submeshB = submeshInstructionsItemsB[i];
|
||||||
|
|
||||||
|
if (!(
|
||||||
|
submeshA.rawVertexCount == submeshB.rawVertexCount &&
|
||||||
|
submeshA.startSlot == submeshB.startSlot &&
|
||||||
|
submeshA.endSlot == submeshB.endSlot
|
||||||
|
&& submeshA.rawTriangleCount == submeshB.rawTriangleCount &&
|
||||||
|
submeshA.rawFirstVertexIndex == submeshB.rawFirstVertexIndex
|
||||||
|
))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
// In normal immutable triangle use, immutableTriangles will be initially false, forcing the smartmesh to update the first time but never again after that, unless there was an immutableTriangles flag mismatch..
|
||||||
|
if (a.immutableTriangles || b.immutableTriangles)
|
||||||
|
return (a.immutableTriangles != b.immutableTriangles);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d07866ade25bd0b44a7bb1d59bacf4cb
|
||||||
|
timeCreated: 1563322425
|
||||||
|
licenseType: Free
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user