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;
		}
Esempio n. 3
0
        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));
        }