public bool StructureDoesntMatch(ExposedList <Attachment> attachments, ExposedList <SubmeshInstruction> instructions) { if (attachments.Count != this.attachmentsUsed.Count) { return(true); } if (instructions.Count != this.instructionsUsed.Count) { return(true); } Attachment[] items = attachments.Items; Attachment[] items2 = this.attachmentsUsed.Items; int i = 0; int count = this.attachmentsUsed.Count; while (i < count) { if (items[i] != items2[i]) { return(true); } i++; } SubmeshInstruction[] items3 = instructions.Items; SubmeshInstruction[] items4 = this.instructionsUsed.Items; int j = 0; int count2 = this.instructionsUsed.Count; while (j < count2) { SubmeshInstruction submeshInstruction = items3[j]; SubmeshInstruction submeshInstruction2 = items4[j]; if (submeshInstruction.material.GetInstanceID() != submeshInstruction2.material.GetInstanceID() || submeshInstruction.startSlot != submeshInstruction2.startSlot || submeshInstruction.endSlot != submeshInstruction2.endSlot || submeshInstruction.triangleCount != submeshInstruction2.triangleCount || submeshInstruction.vertexCount != submeshInstruction2.vertexCount || submeshInstruction.firstVertexIndex != submeshInstruction2.firstVertexIndex) { return(true); } j++; } return(false); }
public static bool EnsureTriangleBuffersSize (ExposedList<SubmeshTriangleBuffer> submeshBuffers, int targetSubmeshCount, SubmeshInstruction[] instructionItems) { bool submeshBuffersWasResized = submeshBuffers.Count < targetSubmeshCount; if (submeshBuffersWasResized) { submeshBuffers.GrowIfNeeded(targetSubmeshCount - submeshBuffers.Count); for (int i = submeshBuffers.Count; submeshBuffers.Count < targetSubmeshCount; i++) submeshBuffers.Add(new SubmeshTriangleBuffer(instructionItems[i].triangleCount)); } return submeshBuffersWasResized; }
void SetSubmesh(int submeshIndex, Spine.Unity.MeshGeneration.SubmeshInstruction submeshInstructions, ExposedList <bool> flipStates, bool isLastSubmesh) { var currentSubmesh = submeshes.Items[submeshIndex]; int[] triangles = currentSubmesh.triangles; int triangleCount = submeshInstructions.triangleCount; int firstVertex = submeshInstructions.firstVertexIndex; int trianglesCapacity = triangles.Length; if (isLastSubmesh && trianglesCapacity > triangleCount) { // Last submesh may have more triangles than required, so zero triangles to the end. for (int i = triangleCount; i < trianglesCapacity; i++) { triangles[i] = 0; } currentSubmesh.triangleCount = triangleCount; } else if (trianglesCapacity != triangleCount) { // Reallocate triangles when not the exact size needed. currentSubmesh.triangles = triangles = new int[triangleCount]; currentSubmesh.triangleCount = 0; } if (!this.renderMeshes && !this.frontFacing) { // Use stored triangles if possible. if (currentSubmesh.firstVertex != firstVertex || currentSubmesh.triangleCount < triangleCount) //|| currentSubmesh.triangleCount == 0 { currentSubmesh.triangleCount = triangleCount; currentSubmesh.firstVertex = firstVertex; for (int i = 0; i < triangleCount; i += 6, firstVertex += 4) { triangles[i] = firstVertex; triangles[i + 1] = firstVertex + 2; triangles[i + 2] = firstVertex + 1; triangles[i + 3] = firstVertex + 2; triangles[i + 4] = firstVertex + 3; triangles[i + 5] = firstVertex + 1; } } return; } var flipStatesItems = flipStates.Items; // Iterate through all slots and store their triangles. var drawOrderItems = skeleton.DrawOrder.Items; int triangleIndex = 0; // Modified by loop for (int i = submeshInstructions.startSlot, n = submeshInstructions.endSlot; i < n; i++) { Attachment attachment = drawOrderItems[i].attachment; bool flip = frontFacing && flipStatesItems[i]; // Add RegionAttachment triangles if (attachment is RegionAttachment) { if (!flip) { triangles[triangleIndex] = firstVertex; triangles[triangleIndex + 1] = firstVertex + 2; triangles[triangleIndex + 2] = firstVertex + 1; triangles[triangleIndex + 3] = firstVertex + 2; triangles[triangleIndex + 4] = firstVertex + 3; triangles[triangleIndex + 5] = firstVertex + 1; } else { triangles[triangleIndex] = firstVertex + 1; triangles[triangleIndex + 1] = firstVertex + 2; triangles[triangleIndex + 2] = firstVertex; triangles[triangleIndex + 3] = firstVertex + 1; triangles[triangleIndex + 4] = firstVertex + 3; triangles[triangleIndex + 5] = firstVertex + 2; } triangleIndex += 6; firstVertex += 4; continue; } // Add (Weighted)MeshAttachment triangles int[] attachmentTriangles; int attachmentVertexCount; var meshAttachment = attachment as MeshAttachment; if (meshAttachment != null) { attachmentVertexCount = meshAttachment.worldVerticesLength >> 1; // length/2 attachmentTriangles = meshAttachment.triangles; } else { continue; } if (flip) { for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii += 3, triangleIndex += 3) { triangles[triangleIndex + 2] = firstVertex + attachmentTriangles[ii]; triangles[triangleIndex + 1] = firstVertex + attachmentTriangles[ii + 1]; triangles[triangleIndex] = firstVertex + attachmentTriangles[ii + 2]; } } else { for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++) { triangles[triangleIndex] = firstVertex + attachmentTriangles[ii]; } } firstVertex += attachmentVertexCount; } }
void SetSubmesh(int submeshIndex, Spine.Unity.MeshGeneration.SubmeshInstruction submeshInstructions, ExposedList <bool> flipStates, bool isLastSubmesh) { #else void SetSubmesh(int submeshIndex, Spine.Unity.MeshGeneration.SubmeshInstruction submeshInstructions, bool isLastSubmesh) { #endif SubmeshTriangleBuffer currentSubmesh = submeshes.Items[submeshIndex]; int[] triangles = currentSubmesh.triangles; int triangleCount = submeshInstructions.triangleCount; int firstVertex = submeshInstructions.firstVertexIndex; int trianglesCapacity = triangles.Length; if (isLastSubmesh && trianglesCapacity > triangleCount) { // Last submesh may have more triangles than required, so zero triangles to the end. for (int i = triangleCount; i < trianglesCapacity; i++) { triangles[i] = 0; } currentSubmesh.triangleCount = triangleCount; } else if (trianglesCapacity != triangleCount) { // Reallocate triangles when not the exact size needed. currentSubmesh.triangles = triangles = new int[triangleCount]; currentSubmesh.triangleCount = 0; } #if SPINE_OPTIONAL_FRONTFACING if (!this.renderMeshes && !this.frontFacing) { #else if (!this.renderMeshes) { #endif // Use stored triangles if possible. if (currentSubmesh.firstVertex != firstVertex || currentSubmesh.triangleCount < triangleCount) //|| currentSubmesh.triangleCount == 0 { currentSubmesh.triangleCount = triangleCount; currentSubmesh.firstVertex = firstVertex; for (int i = 0; i < triangleCount; i += 6, firstVertex += 4) { triangles[i] = firstVertex; triangles[i + 1] = firstVertex + 2; triangles[i + 2] = firstVertex + 1; triangles[i + 3] = firstVertex + 2; triangles[i + 4] = firstVertex + 3; triangles[i + 5] = firstVertex + 1; } } return; } // This method caches several .Items arrays. // Never mutate their overlying ExposedList objects. #if SPINE_OPTIONAL_FRONTFACING var flipStatesItems = flipStates.Items; #endif // Iterate through all slots and store their triangles. var drawOrderItems = skeleton.DrawOrder.Items; int triangleIndex = 0; // Modified by loop for (int i = submeshInstructions.startSlot, n = submeshInstructions.endSlot; i < n; i++) { Attachment attachment = drawOrderItems[i].attachment; #if SPINE_OPTIONAL_FRONTFACING bool flip = frontFacing && flipStatesItems[i]; // Add RegionAttachment triangles if (attachment is RegionAttachment) { if (!flip) { triangles[triangleIndex] = firstVertex; triangles[triangleIndex + 1] = firstVertex + 2; triangles[triangleIndex + 2] = firstVertex + 1; triangles[triangleIndex + 3] = firstVertex + 2; triangles[triangleIndex + 4] = firstVertex + 3; triangles[triangleIndex + 5] = firstVertex + 1; } else { triangles[triangleIndex] = firstVertex + 1; triangles[triangleIndex + 1] = firstVertex + 2; triangles[triangleIndex + 2] = firstVertex; triangles[triangleIndex + 3] = firstVertex + 1; triangles[triangleIndex + 4] = firstVertex + 3; triangles[triangleIndex + 5] = firstVertex + 2; } triangleIndex += 6; firstVertex += 4; continue; } #else if (attachment is RegionAttachment) { triangles[triangleIndex] = firstVertex; triangles[triangleIndex + 1] = firstVertex + 2; triangles[triangleIndex + 2] = firstVertex + 1; triangles[triangleIndex + 3] = firstVertex + 2; triangles[triangleIndex + 4] = firstVertex + 3; triangles[triangleIndex + 5] = firstVertex + 1; triangleIndex += 6; firstVertex += 4; continue; } #endif // Add (Weighted)MeshAttachment triangles int[] attachmentTriangles; int attachmentVertexCount; var meshAttachment = attachment as MeshAttachment; if (meshAttachment != null) { attachmentVertexCount = meshAttachment.worldVerticesLength >> 1; // length/2 attachmentTriangles = meshAttachment.triangles; } else { continue; } #if SPINE_OPTIONAL_FRONTFACING if (flip) { for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii += 3, triangleIndex += 3) { triangles[triangleIndex + 2] = firstVertex + attachmentTriangles[ii]; triangles[triangleIndex + 1] = firstVertex + attachmentTriangles[ii + 1]; triangles[triangleIndex] = firstVertex + attachmentTriangles[ii + 2]; } } else { for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++) { triangles[triangleIndex] = firstVertex + attachmentTriangles[ii]; } } #else for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++) { triangles[triangleIndex] = firstVertex + attachmentTriangles[ii]; } #endif firstVertex += attachmentVertexCount; } } #if UNITY_EDITOR void OnDrawGizmos() { // Make scene view selection easier by drawing a clear gizmo over the skeleton. meshFilter = GetComponent <MeshFilter>(); if (meshFilter == null) { return; } Mesh mesh = meshFilter.sharedMesh; if (mesh == null) { return; } Bounds meshBounds = mesh.bounds; Gizmos.color = Color.clear; Gizmos.matrix = transform.localToWorldMatrix; Gizmos.DrawCube(meshBounds.center, meshBounds.size); } #endif ///<summary>This is a Mesh that also stores the instructions SkeletonRenderer generated for it.</summary> public class SmartMesh {
public MeshAndMaterials GenerateMesh(ExposedList <SubmeshInstruction> instructions, int startSubmesh, int endSubmesh) { SubmeshInstruction[] items = instructions.Items; this.currentInstructions.Clear(false); for (int i = startSubmesh; i < endSubmesh; i++) { this.currentInstructions.Add(items[i]); } SmartMesh next = this.doubleBufferedSmartMesh.GetNext(); Mesh mesh = next.mesh; int count = this.currentInstructions.Count; SubmeshInstruction[] items2 = this.currentInstructions.Items; int num = 0; for (int j = 0; j < count; j++) { items2[j].firstVertexIndex = num; num += items2[j].vertexCount; } bool flag = ArraysMeshGenerator.EnsureSize(num, ref this.meshVertices, ref this.meshUVs, ref this.meshColors32); bool flag2 = ArraysMeshGenerator.EnsureTriangleBuffersSize(this.submeshBuffers, count, items2); float zspacing = this.ZSpacing; Vector3 boundsMin; Vector3 boundsMax; if (num <= 0) { boundsMin = new Vector3(0f, 0f, 0f); boundsMax = new Vector3(0f, 0f, 0f); } else { boundsMin.x = 2.14748365E+09f; boundsMin.y = 2.14748365E+09f; boundsMax.x = -2.14748365E+09f; boundsMax.y = -2.14748365E+09f; int endSlot = items2[count - 1].endSlot; if (zspacing > 0f) { boundsMin.z = 0f; boundsMax.z = zspacing * (float)endSlot; } else { boundsMin.z = zspacing * (float)endSlot; boundsMax.z = 0f; } } ExposedList <Attachment> exposedList = this.attachmentBuffer; exposedList.Clear(false); int num2 = 0; for (int k = 0; k < count; k++) { SubmeshInstruction submeshInstruction = items2[k]; int startSlot = submeshInstruction.startSlot; int endSlot2 = submeshInstruction.endSlot; Skeleton skeleton = submeshInstruction.skeleton; Slot[] items3 = skeleton.DrawOrder.Items; for (int l = startSlot; l < endSlot2; l++) { Attachment attachment = items3[l].attachment; if (attachment != null) { exposedList.Add(attachment); } } ArraysMeshGenerator.FillVerts(skeleton, startSlot, endSlot2, zspacing, base.PremultiplyVertexColors, this.meshVertices, this.meshUVs, this.meshColors32, ref num2, ref this.attachmentVertexBuffer, ref boundsMin, ref boundsMax, true); } bool flag3 = flag || flag2 || next.StructureDoesntMatch(exposedList, this.currentInstructions); for (int m = 0; m < count; m++) { SubmeshInstruction submeshInstruction2 = items2[m]; if (flag3) { SubmeshTriangleBuffer submeshTriangleBuffer = this.submeshBuffers.Items[m]; bool isLastSubmesh = m == count - 1; ArraysMeshGenerator.FillTriangles(ref submeshTriangleBuffer.triangles, submeshInstruction2.skeleton, submeshInstruction2.triangleCount, submeshInstruction2.firstVertexIndex, submeshInstruction2.startSlot, submeshInstruction2.endSlot, isLastSubmesh); submeshTriangleBuffer.triangleCount = submeshInstruction2.triangleCount; submeshTriangleBuffer.firstVertex = submeshInstruction2.firstVertexIndex; } } if (flag3) { mesh.Clear(); this.sharedMaterials = this.currentInstructions.GetUpdatedMaterialArray(this.sharedMaterials); } next.Set(this.meshVertices, this.meshUVs, this.meshColors32, exposedList, this.currentInstructions); mesh.bounds = ArraysMeshGenerator.ToBounds(boundsMin, boundsMax); if (flag3) { mesh.subMeshCount = count; for (int n = 0; n < count; n++) { mesh.SetTriangles(this.submeshBuffers.Items[n].triangles, n); } base.TryAddNormalsTo(mesh, num); } if (this.addTangents) { ArraysMeshGenerator.SolveTangents2DEnsureSize(ref this.meshTangents, ref this.tempTanBuffer, num); int num3 = 0; int num4 = count; while (num3 < num4) { SubmeshTriangleBuffer submeshTriangleBuffer2 = this.submeshBuffers.Items[num3]; ArraysMeshGenerator.SolveTangents2DTriangles(this.tempTanBuffer, submeshTriangleBuffer2.triangles, submeshTriangleBuffer2.triangleCount, this.meshVertices, this.meshUVs, num); num3++; } ArraysMeshGenerator.SolveTangents2DBuffer(this.meshTangents, this.tempTanBuffer, num); } return(new MeshAndMaterials(next.mesh, this.sharedMaterials)); }
public MeshAndMaterials GenerateMesh(SubmeshedMeshInstruction meshInstructions) { SmartMesh next = this.doubleBufferedSmartMesh.GetNext(); Mesh mesh = next.mesh; int count = meshInstructions.submeshInstructions.Count; ExposedList <SubmeshInstruction> submeshInstructions = meshInstructions.submeshInstructions; int vertexCount = meshInstructions.vertexCount; bool flag = ArraysMeshGenerator.EnsureTriangleBuffersSize(this.submeshBuffers, count, submeshInstructions.Items); bool flag2 = ArraysMeshGenerator.EnsureSize(vertexCount, ref this.meshVertices, ref this.meshUVs, ref this.meshColors32); Vector3[] meshVertices = this.meshVertices; float zspacing = this.ZSpacing; int count2 = meshInstructions.attachmentList.Count; Vector3 boundsMin; Vector3 boundsMax; if (count2 <= 0) { boundsMin = new Vector3(0f, 0f, 0f); boundsMax = new Vector3(0f, 0f, 0f); } else { boundsMin.x = 2.14748365E+09f; boundsMin.y = 2.14748365E+09f; boundsMax.x = -2.14748365E+09f; boundsMax.y = -2.14748365E+09f; if (zspacing > 0f) { boundsMin.z = 0f; boundsMax.z = zspacing * (float)(count2 - 1); } else { boundsMin.z = zspacing * (float)(count2 - 1); boundsMax.z = 0f; } } bool flag3 = flag2 || flag || next.StructureDoesntMatch(meshInstructions); int num = 0; for (int i = 0; i < count; i++) { SubmeshInstruction submeshInstruction = submeshInstructions.Items[i]; int startSlot = submeshInstruction.startSlot; int endSlot = submeshInstruction.endSlot; Skeleton skeleton = submeshInstruction.skeleton; ArraysMeshGenerator.FillVerts(skeleton, startSlot, endSlot, zspacing, base.PremultiplyVertexColors, meshVertices, this.meshUVs, this.meshColors32, ref num, ref this.attachmentVertexBuffer, ref boundsMin, ref boundsMax, true); if (flag3) { SubmeshTriangleBuffer submeshTriangleBuffer = this.submeshBuffers.Items[i]; bool isLastSubmesh = i == count - 1; ArraysMeshGenerator.FillTriangles(ref submeshTriangleBuffer.triangles, skeleton, submeshInstruction.triangleCount, submeshInstruction.firstVertexIndex, startSlot, endSlot, isLastSubmesh); submeshTriangleBuffer.triangleCount = submeshInstruction.triangleCount; submeshTriangleBuffer.firstVertex = submeshInstruction.firstVertexIndex; } } if (flag3) { mesh.Clear(); this.sharedMaterials = meshInstructions.GetUpdatedMaterialArray(this.sharedMaterials); } next.Set(this.meshVertices, this.meshUVs, this.meshColors32, meshInstructions); mesh.bounds = ArraysMeshGenerator.ToBounds(boundsMin, boundsMax); if (flag3) { mesh.subMeshCount = count; for (int j = 0; j < count; j++) { mesh.SetTriangles(this.submeshBuffers.Items[j].triangles, j); } base.TryAddNormalsTo(mesh, vertexCount); } if (this.addTangents) { ArraysMeshGenerator.SolveTangents2DEnsureSize(ref this.meshTangents, ref this.tempTanBuffer, vertexCount); int k = 0; int num2 = count; while (k < num2) { SubmeshTriangleBuffer submeshTriangleBuffer2 = this.submeshBuffers.Items[k]; ArraysMeshGenerator.SolveTangents2DTriangles(this.tempTanBuffer, submeshTriangleBuffer2.triangles, submeshTriangleBuffer2.triangleCount, this.meshVertices, this.meshUVs, vertexCount); k++; } ArraysMeshGenerator.SolveTangents2DBuffer(this.meshTangents, this.tempTanBuffer, vertexCount); } return(new MeshAndMaterials(next.mesh, this.sharedMaterials)); }