示例#1
0
		static Mesh ExtractRegionAttachment (string name, RegionAttachment attachment, Mesh mesh = null) {
			var bone = GetExtractionBone();

			bone.X = -attachment.X;
			bone.Y = -attachment.Y;
			bone.UpdateWorldTransform();

			Vector2[] uvs = ExtractUV(attachment.UVs);
			float[] floatVerts = new float[8];
			attachment.ComputeWorldVertices(bone, floatVerts);
			Vector3[] verts = ExtractVerts(floatVerts);

			//unrotate verts now that they're centered
			for (int i = 0; i < verts.Length; i++) {
				verts[i] = Quaternion.Euler(0, 0, -attachment.Rotation) * verts[i];
			}

			int[] triangles = new int[6] { 1, 3, 0, 2, 3, 1 };
			Color color = new Color(attachment.R, attachment.G, attachment.B, attachment.A);

			if (mesh == null)
				mesh = new Mesh();

			mesh.triangles = new int[0];

			mesh.vertices = verts;
			mesh.uv = uvs;
			mesh.triangles = triangles;
			mesh.colors = new Color[] { color, color, color, color };
			mesh.RecalculateBounds();
			mesh.RecalculateNormals();
			mesh.name = name;

			return mesh;
		}
        // RegionAttachment
        protected void AddAttachment(Slot slot, RegionAttachment attachment)
        {
            var tempVertices = this.tempVertices;

            attachment.ComputeWorldVertices(slot.bone, tempVertices);

            float[] regionUVs = attachment.uvs;

            Color color = skeletonColor;

            color.r = color.r * attachment.r * slot.r;
            color.g = color.g * attachment.g * slot.g;
            color.b = color.b * attachment.b * slot.b;
            color.a = color.a * attachment.a * slot.a;
            if (premultiplyAlpha)
            {
                color.r *= color.a; color.g *= color.a; color.b *= color.a;
                if (slot.data.blendMode == BlendMode.additive)
                {
                    color.a = 0;
                }
            }

            int fv = positions.Count;             // first vertex index

            AddVert(new Vector3(tempVertices[RegionAttachment.X1] * scale, tempVertices[RegionAttachment.Y1] * scale), color, new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]));
            AddVert(new Vector3(tempVertices[RegionAttachment.X4] * scale, tempVertices[RegionAttachment.Y4] * scale), color, new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]));
            AddVert(new Vector3(tempVertices[RegionAttachment.X2] * scale, tempVertices[RegionAttachment.Y2] * scale), color, new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]));
            AddVert(new Vector3(tempVertices[RegionAttachment.X3] * scale, tempVertices[RegionAttachment.Y3] * scale), color, new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]));

            AddTriangle(fv, fv + 2, fv + 1);
            AddTriangle(fv + 2, fv + 3, fv + 1);
        }
        private List <Vector3> ComputeAttachmentVertices(Attachment attachment, Slot slot)
        {
            var result = new List <Vector3>();

            if (attachment is RegionAttachment)
            {
                RegionAttachment regionAttachment = attachment as RegionAttachment;
                float[]          spineVertices    = new float[8];
                regionAttachment.ComputeWorldVertices(slot.Bone, spineVertices);

                result.Add(new Vector3(
                               spineVertices[RegionAttachment.X1],
                               -spineVertices[RegionAttachment.Y1],
                               0));

                result.Add(new Vector3(
                               spineVertices[RegionAttachment.X4],
                               -spineVertices[RegionAttachment.Y4],
                               0));

                result.Add(new Vector3(
                               spineVertices[RegionAttachment.X3],
                               -spineVertices[RegionAttachment.Y3],
                               0));

                result.Add(new Vector3(
                               spineVertices[RegionAttachment.X2],
                               -spineVertices[RegionAttachment.Y2],
                               0));
            }
            else if (attachment is MeshAttachment || attachment is WeightedMeshAttachment)
            {
                float[] spineVertices;

                if (attachment is MeshAttachment)
                {
                    var mesh        = attachment as MeshAttachment;
                    var numVertices = mesh.Vertices.Length;
                    spineVertices = new float[numVertices];
                    mesh.ComputeWorldVertices(slot, spineVertices);
                }
                else
                {
                    var mesh        = attachment as WeightedMeshAttachment;
                    var numVertices = mesh.UVs.Length;
                    spineVertices = new float[numVertices];
                    mesh.ComputeWorldVertices(slot, spineVertices);
                }

                for (int v = 0; v < spineVertices.Length; v += 2)
                {
                    result.Add(new Vector3(
                                   spineVertices[v],
                                   -spineVertices[v + 1],
                                   0));
                }
            }

            return(result);
        }
示例#4
0
        //virtual cocos2d::CCTextureAtlas* getTextureAtlas (RegionAttachment regionAttachment);
        #region SpinesCocos2d

        void UpdateRegionAttachmentQuad(RegionAttachment self, Slot slot, ref CCV3F_C4B_T2F_Quad quad, bool premultipliedAlpha = false)
        {
            float[] vertices = new float[8];

            self.ComputeWorldVertices(slot.Skeleton.X, slot.Skeleton.Y, slot.Bone, vertices);

            float r = slot.Skeleton.R * slot.R * 255;
            float g = slot.Skeleton.G * slot.G * 255;
            float b = slot.Skeleton.B * slot.B * 255;

            float normalizedAlpha = slot.Skeleton.A * slot.A;

            if (premultipliedAlpha)
            {
                r *= normalizedAlpha;
                g *= normalizedAlpha;
                b *= normalizedAlpha;
            }

            float a = normalizedAlpha * 255;

            quad.BottomLeft.Colors.R  = (byte)r;
            quad.BottomLeft.Colors.G  = (byte)g;
            quad.BottomLeft.Colors.B  = (byte)b;
            quad.BottomLeft.Colors.A  = (byte)a;
            quad.TopLeft.Colors.R     = (byte)r;
            quad.TopLeft.Colors.G     = (byte)g;
            quad.TopLeft.Colors.B     = (byte)b;
            quad.TopLeft.Colors.A     = (byte)a;
            quad.TopRight.Colors.R    = (byte)r;
            quad.TopRight.Colors.G    = (byte)g;
            quad.TopRight.Colors.B    = (byte)b;
            quad.TopRight.Colors.A    = (byte)a;
            quad.BottomRight.Colors.R = (byte)r;
            quad.BottomRight.Colors.G = (byte)g;
            quad.BottomRight.Colors.B = (byte)b;
            quad.BottomRight.Colors.A = (byte)a;

            quad.BottomLeft.Vertices.X  = vertices[RegionAttachment.X1];
            quad.BottomLeft.Vertices.Y  = vertices[RegionAttachment.Y1];
            quad.TopLeft.Vertices.X     = vertices[RegionAttachment.X2];
            quad.TopLeft.Vertices.Y     = vertices[RegionAttachment.Y2];
            quad.TopRight.Vertices.X    = vertices[RegionAttachment.X3];
            quad.TopRight.Vertices.Y    = vertices[RegionAttachment.Y3];
            quad.BottomRight.Vertices.X = vertices[RegionAttachment.X4];
            quad.BottomRight.Vertices.Y = vertices[RegionAttachment.Y4];

            quad.BottomLeft.TexCoords.U  = self.UVs[RegionAttachment.X1];
            quad.BottomLeft.TexCoords.V  = self.UVs[RegionAttachment.Y1];
            quad.TopLeft.TexCoords.U     = self.UVs[RegionAttachment.X2];
            quad.TopLeft.TexCoords.V     = self.UVs[RegionAttachment.Y2];
            quad.TopRight.TexCoords.U    = self.UVs[RegionAttachment.X3];
            quad.TopRight.TexCoords.V    = self.UVs[RegionAttachment.Y3];
            quad.BottomRight.TexCoords.U = self.UVs[RegionAttachment.X4];
            quad.BottomRight.TexCoords.V = self.UVs[RegionAttachment.Y4];
        }
示例#5
0
    // update the attachment with the current slot data
    public void Update(Slot slot)
    {
        _attachment = slot.Attachment as RegionAttachment;

        //_attachment.UpdateOffset();
        //_attachment.UpdateVertices(slot.Bone);

        _attachment.ComputeWorldVertices(slot.Bone, vertices);

        element = _attachment.RendererObject as FAtlasElement;
        element = null;

        base.color = _slotCustomColor * new Color(slot.R, slot.G, slot.B, slot.A);

        UpdateLocalVertices();
    }
示例#6
0
        private void DrawSlot(Skeleton skeleton, RegionAttachment attachment, Slot slot)
        {
            var region        = (AtlasRegion)attachment.RendererObject;
            var thisMaterial  = (Material)region.page.rendererObject;
            var thisBlendMode = slot.Data.AdditiveBlending ? BlendMode.Additive : BlendMode.Normal;
            var thisBatch     = (Batch2D)renderer.FindOrCreateBatch(thisMaterial, thisBlendMode);

            if (currentBatch != null && currentBatch != thisBatch)
            {
                renderer.FlushDrawBuffer(currentBatch);
            }
            currentBatch = thisBatch;
            attachment.ComputeWorldVertices(skeleton.X, skeleton.Y, slot.Bone, vertices);
            currentColor = new Color(color.RedValue * slot.R, color.GreenValue * slot.G,
                                     color.BlueValue * slot.B, color.AlphaValue * slot.A);
            AddSlotIndicesAndVertices(attachment.UVs);
        }
        private void UpdateBounds(ref ModelBound bound, Skeleton skeleton)
        {
            float[] vertices  = new float[8];
            var     drawOrder = skeleton.DrawOrder;

            for (int i = 0, n = drawOrder.Count; i < n; i++)
            {
                Slot       slot       = drawOrder.Items[i];
                Attachment attachment = slot.Attachment;
                if (attachment is RegionAttachment)
                {
                    RegionAttachment region = (RegionAttachment)attachment;
                    region.ComputeWorldVertices(slot.Bone, vertices);
                    bound.Update(vertices, 8);
                }
                else if (attachment is MeshAttachment)
                {
                    MeshAttachment mesh        = (MeshAttachment)attachment;
                    int            vertexCount = mesh.Vertices.Length;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    mesh.ComputeWorldVertices(slot, vertices);
                    bound.Update(vertices, vertexCount);
                }
                else if (attachment is SkinnedMeshAttachment)
                {
                    SkinnedMeshAttachment mesh = (SkinnedMeshAttachment)attachment;
                    int vertexCount            = mesh.UVs.Length;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    mesh.ComputeWorldVertices(slot, vertices);
                    bound.Update(vertices, vertexCount);
                }
            }
        }
        /// <summary>
        /// Allows to perform custom drawing.
        /// </summary>
        /// <param name="gameTime">The elapsed game time.</param>
        public override void Draw(TimeSpan gameTime)
        {
            this.position.X = this.Transform2D.X;
            this.position.Y = this.Transform2D.Y;
            this.scale.X    = this.Transform2D.XScale;
            this.scale.Y    = this.Transform2D.YScale;

            if (this.viewportManager.IsActivated)
            {
                this.viewportManager.Translate(ref this.position, ref this.scale);
            }

            Quaternion.CreateFromYawPitchRoll(0, 0, this.Transform2D.Rotation, out this.orientation);
            Matrix.CreateFromQuaternion(ref this.orientation, out this.quaternionMatrix);

            this.internalScale.X = this.scale.X;
            this.internalScale.Y = this.scale.Y;
            Matrix.CreateScale(ref this.internalScale, out this.scaleMatrix);

            this.internalPosition.X = this.position.X - (this.Transform2D.Origin.X * this.Transform2D.Rectangle.Width);
            this.internalPosition.Y = this.position.Y - (this.Transform2D.Origin.Y * this.Transform2D.Rectangle.Height);
            Matrix.CreateTranslation(ref this.internalPosition, out this.translationMatrix);

            Matrix.Multiply(ref this.scaleMatrix, ref this.quaternionMatrix, out this.localWorld);
            Matrix.Multiply(ref this.localWorld, ref this.translationMatrix, out this.localWorld);

            float opacity = this.RenderManager.DebugLines ? this.DebugAlpha : this.Transform2D.Opacity;

            int numVertices   = 0;
            int numPrimitives = 0;

            // Process Mesh
            for (int i = 0; i < this.drawOrder.Count; i++)
            {
                Slot       slot       = this.drawOrder[i];
                Attachment attachment = slot.Attachment;

                float alpha = this.SkeletalAnimation.Skeleton.A * slot.A * opacity;
                byte  r     = (byte)(this.SkeletalAnimation.Skeleton.R * slot.R * 255 * alpha);
                byte  g     = (byte)(this.SkeletalAnimation.Skeleton.G * slot.G * 255 * alpha);
                byte  b     = (byte)(this.SkeletalAnimation.Skeleton.B * slot.B * 255 * alpha);
                byte  a     = (byte)(alpha * 255);
                Color color = new Color(r, g, b, a);

                if (attachment is RegionAttachment)
                {
                    RegionAttachment regionAttachment = attachment as RegionAttachment;

                    float[] spineVertices = new float[8];
                    float[] uvs           = regionAttachment.UVs;

                    AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject;
                    this.material.Texture = (Texture2D)region.page.rendererObject;

                    regionAttachment.ComputeWorldVertices(0, 0, slot.Bone, spineVertices);

                    this.vertices = new VertexPositionColorTexture[4];

                    // Vertex TL
                    this.tempVertice.Position.X = spineVertices[RegionAttachment.X1];
                    this.tempVertice.Position.Y = -spineVertices[RegionAttachment.Y1];
                    this.tempVertice.Position.Z = 0;
                    this.tempVertice.Color      = color;
                    this.tempVertice.TexCoord.X = uvs[RegionAttachment.X1];
                    this.tempVertice.TexCoord.Y = uvs[RegionAttachment.Y1];
                    this.vertices[0]            = this.tempVertice;

                    // Vertex TR
                    this.tempVertice.Position.X = spineVertices[RegionAttachment.X4];
                    this.tempVertice.Position.Y = -spineVertices[RegionAttachment.Y4];
                    this.tempVertice.Position.Z = 0;
                    this.tempVertice.Color      = color;
                    this.tempVertice.TexCoord.X = uvs[RegionAttachment.X4];
                    this.tempVertice.TexCoord.Y = uvs[RegionAttachment.Y4];
                    this.vertices[1]            = this.tempVertice;

                    // Vertex BR
                    this.tempVertice.Position.X = spineVertices[RegionAttachment.X3];
                    this.tempVertice.Position.Y = -spineVertices[RegionAttachment.Y3];
                    this.tempVertice.Position.Z = 0;
                    this.tempVertice.Color      = color;
                    this.tempVertice.TexCoord.X = uvs[RegionAttachment.X3];
                    this.tempVertice.TexCoord.Y = uvs[RegionAttachment.Y3];
                    this.vertices[2]            = this.tempVertice;

                    // Vertex BL
                    this.tempVertice.Position.X = spineVertices[RegionAttachment.X2];
                    this.tempVertice.Position.Y = -spineVertices[RegionAttachment.Y2];
                    this.tempVertice.Position.Z = 0;
                    this.tempVertice.Color      = color;
                    this.tempVertice.TexCoord.X = uvs[RegionAttachment.X2];
                    this.tempVertice.TexCoord.Y = uvs[RegionAttachment.Y2];
                    this.vertices[3]            = this.tempVertice;

                    numVertices   = 4;
                    numPrimitives = 2;
                    this.indices  = quadIndices;
                }
                else if (attachment is MeshAttachment)
                {
                    MeshAttachment mesh = (MeshAttachment)attachment;

                    numVertices   = mesh.Vertices.Length;
                    numPrimitives = numVertices / 2;
                    indices       = CopyIndices(mesh.Triangles);

                    float[] spineVertices = new float[numVertices];
                    mesh.ComputeWorldVertices(0, 0, slot, spineVertices);

                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    this.material.Texture = (Texture2D)region.page.rendererObject;

                    this.vertices = new VertexPositionColorTexture[numVertices / 2];

                    float[] uvs = mesh.UVs;
                    for (int v = 0, j = 0; v < numVertices; v += 2, j++)
                    {
                        this.tempVertice.Color      = color;
                        this.tempVertice.Position.X = spineVertices[v];
                        this.tempVertice.Position.Y = -spineVertices[v + 1];
                        this.tempVertice.Position.Z = 0;
                        this.tempVertice.TexCoord.X = uvs[v];
                        this.tempVertice.TexCoord.Y = uvs[v + 1];
                        this.vertices[j]            = this.tempVertice;
                    }
                }
                else if (attachment is SkinnedMeshAttachment)
                {
                    SkinnedMeshAttachment mesh = (SkinnedMeshAttachment)attachment;

                    numVertices   = mesh.UVs.Length;
                    numPrimitives = numVertices / 2;
                    indices       = CopyIndices(mesh.Triangles);

                    float[] spineVertices = new float[numVertices];
                    mesh.ComputeWorldVertices(0, 0, slot, spineVertices);

                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    this.material.Texture = (Texture2D)region.page.rendererObject;

                    this.vertices = new VertexPositionColorTexture[numVertices / 2];

                    float[] uvs = mesh.UVs;
                    for (int v = 0, j = 0; v < numVertices; v += 2, j++)
                    {
                        this.tempVertice.Color      = color;
                        this.tempVertice.Position.X = spineVertices[v];
                        this.tempVertice.Position.Y = -spineVertices[v + 1];
                        this.tempVertice.Position.Z = 0;
                        this.tempVertice.TexCoord.X = uvs[v];
                        this.tempVertice.TexCoord.Y = uvs[v + 1];
                        this.vertices[j]            = this.tempVertice;
                    }
                }

                if (attachment != null)
                {
                    bool reset = false;

                    if (this.spineMeshes[i] != null)
                    {
                        if (this.spineMeshes[i].VertexBuffer.VertexCount != vertices.Length ||
                            this.spineMeshes[i].IndexBuffer.Data.Length != indices.Length)
                        {
                            Mesh toDispose = this.spineMeshes[i];
                            this.GraphicsDevice.DestroyIndexBuffer(toDispose.IndexBuffer);
                            this.GraphicsDevice.DestroyVertexBuffer(toDispose.VertexBuffer);

                            reset = true;
                        }
                    }

                    if (this.spineMeshes[i] == null || reset)
                    {
                        Mesh newMesh = new Mesh(
                            0,
                            numVertices,
                            0,
                            numPrimitives,
                            new DynamicVertexBuffer(VertexPositionColorTexture.VertexFormat),
                            new DynamicIndexBuffer(indices),
                            PrimitiveType.TriangleList);

                        this.spineMeshes[i] = newMesh;
                    }

                    Mesh mesh = this.spineMeshes[i];
                    mesh.IndexBuffer.SetData(this.indices);
                    this.GraphicsDevice.BindIndexBuffer(mesh.IndexBuffer);
                    mesh.VertexBuffer.SetData(this.vertices);
                    this.GraphicsDevice.BindVertexBuffer(mesh.VertexBuffer);
                    mesh.ZOrder = this.Transform2D.DrawOrder;

                    this.RenderManager.DrawMesh(mesh, this.material, ref this.localWorld, false);
                }
            }
        }
        public void UpdateSkeletonGeometry()
        {
            skeletonGeometry.ClearInstances();
            BlendState blend;
            var        drawOrder = Skeleton.DrawOrder;
            var        drawOrderItems = Skeleton.DrawOrder.Items;
            float      skeletonR = Skeleton.R, skeletonG = Skeleton.G, skeletonB = Skeleton.B, skeletonA = Skeleton.A;
            Color      color;

            for (int i = 0, n = drawOrder.Count; i < n; i++)
            {
                Slot       slot       = drawOrderItems[i];
                Attachment attachment = slot.Attachment;
                blend = slot.Data.BlendMode == BlendMode.Additive ? BlendState.Additive :
                        PremultipliedAlpha ? BlendState.AlphaBlend : BlendState.NonPremultiplied;
                float       attachmentColorR, attachmentColorG, attachmentColorB, attachmentColorA;
                CCTexture2D texture       = null;
                int         verticesCount = 0;
                //float[] vertices = this.vertices;
                int     indicesCount = 0;
                int[]   indices      = null;
                float[] uvs          = null;

                if (attachment is RegionAttachment)
                {
                    RegionAttachment regionAttachment = (RegionAttachment)attachment;
                    attachmentColorR = regionAttachment.R; attachmentColorG = regionAttachment.G; attachmentColorB = regionAttachment.B; attachmentColorA = regionAttachment.A;
                    AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject;
                    texture       = (CCTexture2D)region.page.rendererObject;
                    verticesCount = 4;
                    regionAttachment.ComputeWorldVertices(slot.Bone, vertices, 0, 2);
                    indicesCount = 6;
                    indices      = quadTriangles;
                    uvs          = regionAttachment.UVs;
                }
                else if (attachment is MeshAttachment)
                {
                    MeshAttachment mesh = (MeshAttachment)attachment;
                    attachmentColorR = mesh.R; attachmentColorG = mesh.G; attachmentColorB = mesh.B; attachmentColorA = mesh.A;
                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    texture = (CCTexture2D)region.page.rendererObject;
                    int vertexCount = mesh.WorldVerticesLength;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    verticesCount = vertexCount >> 1;
                    mesh.ComputeWorldVertices(slot, vertices);
                    indicesCount = mesh.Triangles.Length;
                    indices      = mesh.Triangles;
                    uvs          = mesh.UVs;
                }
                else if (attachment is ClippingAttachment)
                {
                    ClippingAttachment clip = (ClippingAttachment)attachment;
                    clipper.ClipStart(slot, clip);
                    continue;
                }
                else
                {
                    continue;
                }

                // calculate color
                float a = skeletonA * slot.A * attachmentColorA;
                if (PremultipliedAlpha)
                {
                    color = new Color(
                        skeletonR * slot.R * attachmentColorR * a,
                        skeletonG * slot.G * attachmentColorG * a,
                        skeletonB * slot.B * attachmentColorB * a, a);
                }
                else
                {
                    color = new Color(
                        skeletonR * slot.R * attachmentColorR,
                        skeletonG * slot.G * attachmentColorG,
                        skeletonB * slot.B * attachmentColorB, a);
                }

                //Color darkColor = new Color();
                //if (slot.HasSecondColor)
                //{
                //      darkColor = new Color(slot.R2 * a, slot.G2 * a, slot.B2 * a);
                //}
                //darkColor.A = PremultipliedAlpha ? (byte)255 : (byte)0;

                // clip
                if (clipper.IsClipping)
                {
                    clipper.ClipTriangles(vertices, verticesCount << 1, indices, indicesCount, uvs);
                    vertices      = clipper.ClippedVertices.Items;
                    verticesCount = clipper.ClippedVertices.Count >> 1;
                    indices       = clipper.ClippedTriangles.Items;
                    indicesCount  = clipper.ClippedTriangles.Count;
                    uvs           = clipper.ClippedUVs.Items;
                }

                if (verticesCount == 0 || indicesCount == 0)
                {
                    continue;
                }

                // submit to batch
                var item = skeletonGeometry.CreateGeometryInstance(verticesCount, indicesCount);
                item.InstanceAttributes.BlendState = blend;
                item.GeometryPacket.Texture        = texture;
                for (int ii = 0, nn = indicesCount; ii < nn; ii++)
                {
                    item.GeometryPacket.Indicies[ii] = indices[ii];
                }

                var itemVertices = item.GeometryPacket.Vertices;
                for (int ii = 0, v = 0, nn = verticesCount << 1; v < nn; ii++, v += 2)
                {
                    itemVertices[ii].Colors = new CCColor4B(color.R, color.G, color.B, color.A);
                    //itemVertices[ii].Colors2 = new CCColor4B(darkColor.R, darkColor.G, darkColor.B, darkColor.A);
                    itemVertices[ii].Vertices.X  = vertices[v];
                    itemVertices[ii].Vertices.Y  = vertices[v + 1];
                    itemVertices[ii].Vertices.Z  = 0;
                    itemVertices[ii].TexCoords.U = uvs[v];
                    itemVertices[ii].TexCoords.V = uvs[v + 1];
                }

                clipper.ClipEnd(slot);
            }
            clipper.ClipEnd();
        }
    public virtual void Update()
    {
        if (skeletonDataAsset == null)
        {
            Clear();
            return;
        }

        SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);

        if (skeletonData == null)
        {
            Clear();
            return;
        }

        // Initialize fields.
        if (skeleton == null || skeleton.Data != skeletonData)
        {
            Initialize();
        }

        UpdateSkeleton(Time.deltaTime);

        // Count quads and submeshes.
        int      quadCount = 0, submeshQuadCount = 0;
        Material lastMaterial = null;

        submeshMaterials.Clear();
        List <Slot> drawOrder = skeleton.DrawOrder;

        for (int i = 0, n = drawOrder.Count; i < n; i++)
        {
            RegionAttachment regionAttachment = drawOrder[i].Attachment as RegionAttachment;
            if (regionAttachment == null)
            {
                continue;
            }

            // Add submesh when material changes.
            Material material = (Material)regionAttachment.RendererObject;
            if (lastMaterial != material && lastMaterial != null)
            {
                addSubmesh(lastMaterial, quadCount, submeshQuadCount, false);
                submeshQuadCount = 0;
            }
            lastMaterial = material;

            quadCount++;
            submeshQuadCount++;
        }
        addSubmesh(lastMaterial, quadCount, submeshQuadCount, true);

        // Set materials.
        if (submeshMaterials.Count == sharedMaterials.Length)
        {
            submeshMaterials.CopyTo(sharedMaterials);
        }
        else
        {
            sharedMaterials = submeshMaterials.ToArray();
        }
        renderer.sharedMaterials = sharedMaterials;

        // Double buffer mesh.
        Mesh mesh = useMesh1 ? mesh1 : mesh2;

        meshFilter.sharedMesh = mesh;

        // Ensure mesh data is the right size.
        Vector3[] vertices     = this.vertices;
        int       vertexCount  = quadCount * 4;
        bool      newTriangles = vertexCount > vertices.Length;

        if (newTriangles)
        {
            // Not enough vertices, increase size.
            this.vertices = vertices = new Vector3[vertexCount];
            this.colors   = new Color32[vertexCount];
            this.uvs      = new Vector2[vertexCount];
            mesh1.Clear();
            mesh2.Clear();
        }
        else
        {
            // Too many vertices, zero the extra.
            Vector3 zero = Vector3.zero;
            for (int i = vertexCount, n = lastVertexCount; i < n; i++)
            {
                vertices[i] = zero;
            }
        }
        lastVertexCount = vertexCount;

        // Setup mesh.
        float[]   vertexPositions = this.vertexPositions;
        Vector2[] uvs = this.uvs;
        Color32[] colors = this.colors;
        int       vertexIndex = 0;
        Color32   color = new Color32();
        float     a = skeleton.A * 255, r = skeleton.R, g = skeleton.G, b = skeleton.B, zSpacing = this.zSpacing;

        for (int i = 0, n = drawOrder.Count; i < n; i++)
        {
            Slot             slot             = drawOrder[i];
            RegionAttachment regionAttachment = slot.Attachment as RegionAttachment;
            if (regionAttachment == null)
            {
                continue;
            }

            regionAttachment.ComputeWorldVertices(skeleton.X, skeleton.Y, slot.Bone, vertexPositions);

            float z = i * zSpacing;
            vertices[vertexIndex]     = new Vector3(vertexPositions[RegionAttachment.X1], vertexPositions[RegionAttachment.Y1], z);
            vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4], vertexPositions[RegionAttachment.Y4], z);
            vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], z);
            vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], z);

            color.a = (byte)(a * slot.A);
            color.r = (byte)(r * slot.R * color.a);
            color.g = (byte)(g * slot.G * color.a);
            color.b = (byte)(b * slot.B * color.a);
            if (slot.Data.AdditiveBlending)
            {
                color.a = 0;
            }
            colors[vertexIndex]     = color;
            colors[vertexIndex + 1] = color;
            colors[vertexIndex + 2] = color;
            colors[vertexIndex + 3] = color;

            float[] regionUVs = regionAttachment.UVs;
            uvs[vertexIndex]     = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]);
            uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]);
            uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]);
            uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]);

            vertexIndex += 4;
        }

        mesh.vertices = vertices;
        mesh.colors32 = colors;
        mesh.uv       = uvs;

        int submeshCount = submeshMaterials.Count;

        mesh.subMeshCount = submeshCount;
        for (int i = 0; i < submeshCount; ++i)
        {
            mesh.SetTriangles(submeshes[i].indexes, i);
        }
        mesh.RecalculateBounds();

        if (newTriangles && calculateNormals)
        {
            Vector3[] normals = new Vector3[vertexCount];
            Vector3   normal  = new Vector3(0, 0, -1);
            for (int i = 0; i < vertexCount; i++)
            {
                normals[i] = normal;
            }
            (useMesh1 ? mesh2 : mesh1).vertices = vertices;             // Set other mesh vertices.
            mesh1.normals = normals;
            mesh2.normals = normals;

            if (calculateTangents)
            {
                Vector4[] tangents = new Vector4[vertexCount];
                Vector3   tangent  = new Vector3(0, 0, 1);
                for (int i = 0; i < vertexCount; i++)
                {
                    tangents[i] = tangent;
                }
                mesh1.tangents = tangents;
                mesh2.tangents = tangents;
            }
        }

        useMesh1 = !useMesh1;
    }
示例#11
0
        public static void FillVerts(Skeleton skeleton, int startSlot, int endSlot, float zSpacing, bool pmaColors, Vector3[] verts, Vector2[] uvs, Color32[] colors, ref int vertexIndex, ref float[] tempVertBuffer, ref Vector3 boundsMin, ref Vector3 boundsMax, bool renderMeshes = true)
        {
            Color32 color = new Color32(0, 0, 0, 0);

            Slot[] items = skeleton.DrawOrder.Items;
            float  num   = skeleton.a * 255f;
            float  r     = skeleton.r;
            float  g     = skeleton.g;
            float  b     = skeleton.b;
            int    num2  = vertexIndex;

            float[] array   = tempVertBuffer;
            Vector3 vector  = boundsMin;
            Vector3 vector2 = boundsMax;

            for (int i = startSlot; i < endSlot; i++)
            {
                Slot             slot             = items[i];
                Attachment       attachment       = slot.attachment;
                float            z                = (float)i * zSpacing;
                RegionAttachment regionAttachment = attachment as RegionAttachment;
                if (regionAttachment != null)
                {
                    regionAttachment.ComputeWorldVertices(slot.bone, array);
                    float num3  = array[0];
                    float num4  = array[1];
                    float num5  = array[2];
                    float num6  = array[3];
                    float num7  = array[4];
                    float num8  = array[5];
                    float num9  = array[6];
                    float num10 = array[7];
                    verts[num2].x     = num3;
                    verts[num2].y     = num4;
                    verts[num2].z     = z;
                    verts[num2 + 1].x = num9;
                    verts[num2 + 1].y = num10;
                    verts[num2 + 1].z = z;
                    verts[num2 + 2].x = num5;
                    verts[num2 + 2].y = num6;
                    verts[num2 + 2].z = z;
                    verts[num2 + 3].x = num7;
                    verts[num2 + 3].y = num8;
                    verts[num2 + 3].z = z;
                    if (pmaColors)
                    {
                        color.a = (byte)(num * slot.a * regionAttachment.a);
                        color.r = (byte)(r * slot.r * regionAttachment.r * (float)color.a);
                        color.g = (byte)(g * slot.g * regionAttachment.g * (float)color.a);
                        color.b = (byte)(b * slot.b * regionAttachment.b * (float)color.a);
                        if (slot.data.blendMode == BlendMode.additive)
                        {
                            color.a = 0;
                        }
                    }
                    else
                    {
                        color.a = (byte)(num * slot.a * regionAttachment.a);
                        color.r = (byte)(r * slot.r * regionAttachment.r * 255f);
                        color.g = (byte)(g * slot.g * regionAttachment.g * 255f);
                        color.b = (byte)(b * slot.b * regionAttachment.b * 255f);
                    }
                    colors[num2]     = color;
                    colors[num2 + 1] = color;
                    colors[num2 + 2] = color;
                    colors[num2 + 3] = color;
                    float[] uvs2 = regionAttachment.uvs;
                    uvs[num2].x     = uvs2[0];
                    uvs[num2].y     = uvs2[1];
                    uvs[num2 + 1].x = uvs2[6];
                    uvs[num2 + 1].y = uvs2[7];
                    uvs[num2 + 2].x = uvs2[2];
                    uvs[num2 + 2].y = uvs2[3];
                    uvs[num2 + 3].x = uvs2[4];
                    uvs[num2 + 3].y = uvs2[5];
                    if (num3 < vector.x)
                    {
                        vector.x = num3;
                    }
                    else if (num3 > vector2.x)
                    {
                        vector2.x = num3;
                    }
                    if (num5 < vector.x)
                    {
                        vector.x = num5;
                    }
                    else if (num5 > vector2.x)
                    {
                        vector2.x = num5;
                    }
                    if (num7 < vector.x)
                    {
                        vector.x = num7;
                    }
                    else if (num7 > vector2.x)
                    {
                        vector2.x = num7;
                    }
                    if (num9 < vector.x)
                    {
                        vector.x = num9;
                    }
                    else if (num9 > vector2.x)
                    {
                        vector2.x = num9;
                    }
                    if (num4 < vector.y)
                    {
                        vector.y = num4;
                    }
                    else if (num4 > vector2.y)
                    {
                        vector2.y = num4;
                    }
                    if (num6 < vector.y)
                    {
                        vector.y = num6;
                    }
                    else if (num6 > vector2.y)
                    {
                        vector2.y = num6;
                    }
                    if (num8 < vector.y)
                    {
                        vector.y = num8;
                    }
                    else if (num8 > vector2.y)
                    {
                        vector2.y = num8;
                    }
                    if (num10 < vector.y)
                    {
                        vector.y = num10;
                    }
                    else if (num10 > vector2.y)
                    {
                        vector2.y = num10;
                    }
                    num2 += 4;
                }
                else if (renderMeshes)
                {
                    MeshAttachment meshAttachment = attachment as MeshAttachment;
                    if (meshAttachment != null)
                    {
                        int worldVerticesLength = meshAttachment.worldVerticesLength;
                        if (array.Length < worldVerticesLength)
                        {
                            array = new float[worldVerticesLength];
                        }
                        meshAttachment.ComputeWorldVertices(slot, array);
                        if (pmaColors)
                        {
                            color.a = (byte)(num * slot.a * meshAttachment.a);
                            color.r = (byte)(r * slot.r * meshAttachment.r * (float)color.a);
                            color.g = (byte)(g * slot.g * meshAttachment.g * (float)color.a);
                            color.b = (byte)(b * slot.b * meshAttachment.b * (float)color.a);
                            if (slot.data.blendMode == BlendMode.additive)
                            {
                                color.a = 0;
                            }
                        }
                        else
                        {
                            color.a = (byte)(num * slot.a * meshAttachment.a);
                            color.r = (byte)(r * slot.r * meshAttachment.r * 255f);
                            color.g = (byte)(g * slot.g * meshAttachment.g * 255f);
                            color.b = (byte)(b * slot.b * meshAttachment.b * 255f);
                        }
                        float[] uvs3 = meshAttachment.uvs;
                        for (int j = 0; j < worldVerticesLength; j += 2)
                        {
                            float num11 = array[j];
                            float num12 = array[j + 1];
                            verts[num2].x = num11;
                            verts[num2].y = num12;
                            verts[num2].z = z;
                            colors[num2]  = color;
                            uvs[num2].x   = uvs3[j];
                            uvs[num2].y   = uvs3[j + 1];
                            if (num11 < vector.x)
                            {
                                vector.x = num11;
                            }
                            else if (num11 > vector2.x)
                            {
                                vector2.x = num11;
                            }
                            if (num12 < vector.y)
                            {
                                vector.y = num12;
                            }
                            else if (num12 > vector2.y)
                            {
                                vector2.y = num12;
                            }
                            num2++;
                        }
                    }
                }
            }
            vertexIndex    = num2;
            tempVertBuffer = array;
            boundsMin      = vector;
            boundsMax      = vector2;
        }
示例#12
0
        public virtual void LateUpdate()
        {
            if (!valid)
            {
                return;
            }

            if (cpuOptimizationLevel != 0)
            {
                skipFramesLateUpdate--;
                if (skipFramesLateUpdate > 0)
                {
                    return;
                }
                skipFramesLateUpdate = cpuOptimizationLevel + UnityEngine.Random.Range(0, cpuOptimizationLevel);
            }

            if (
                (
                    !meshRenderer.enabled

                )
                                #if SPINE_OPTIONAL_RENDEROVERRIDE
                && this.generateMeshOverride == null
                                #endif

                                #if SPINE_OPTIONAL_SUBMESHRENDERER
                && submeshRenderers.Length > 0
                                #endif

                )
            {
                return;
            }



            // STEP 1. Determine a SmartMesh.Instruction. Split up instructions into submeshes.

            // This method caches several .Items arrays.
            // Never mutate their overlying ExposedList objects.
            ExposedList <Slot> drawOrder = skeleton.drawOrder;
            var  drawOrderItems          = drawOrder.Items;
            int  drawOrderCount          = drawOrder.Count;
            int  separatorSlotCount      = separatorSlots.Count;
            bool renderMeshes            = this.renderMeshes;

            // Clear last state of attachments and submeshes
            var workingInstruction = this.currentInstructions;
            var workingAttachments = workingInstruction.attachments;
            workingAttachments.Clear(false);
            workingAttachments.GrowIfNeeded(drawOrderCount);
            workingAttachments.Count = drawOrderCount;
            var workingAttachmentsItems = workingInstruction.attachments.Items;

                        #if SPINE_OPTIONAL_FRONTFACING
            var workingFlips = workingInstruction.attachmentFlips;
            workingFlips.Clear(false);
            workingFlips.GrowIfNeeded(drawOrderCount);
            workingFlips.Count = drawOrderCount;
            var workingFlipsItems = workingFlips.Items;
                        #endif

            var workingSubmeshInstructions = workingInstruction.submeshInstructions;                    // Items array should not be cached. There is dynamic writing to this list.
            workingSubmeshInstructions.Clear(false);

                        #if !SPINE_TK2D
            bool isCustomSlotMaterialsPopulated = customSlotMaterials.Count > 0;
                        #endif

            int      vertexCount = 0;
            int      submeshVertexCount = 0;
            int      submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
            Material lastMaterial = null;
            for (int i = 0; i < drawOrderCount; i++)
            {
                Slot       slot       = drawOrderItems[i];
                Attachment attachment = slot.attachment;

                workingAttachmentsItems[i] = attachment;

                                #if SPINE_OPTIONAL_FRONTFACING
                bool flip = frontFacing && (slot.bone.WorldSignX != slot.bone.WorldSignY);
                workingFlipsItems[i] = flip;
                                #endif

                object rendererObject;                 // An AtlasRegion in plain Spine-Unity. Spine-TK2D hooks into TK2D's system. eventual source of Material object.
                int    attachmentVertexCount, attachmentTriangleCount;

                var regionAttachment = attachment as RegionAttachment;
                if (regionAttachment != null)
                {
                    rendererObject          = regionAttachment.RendererObject;
                    attachmentVertexCount   = 4;
                    attachmentTriangleCount = 6;
                }
                else
                {
                    if (!renderMeshes)
                    {
                        continue;
                    }
                    var meshAttachment = attachment as MeshAttachment;
                    if (meshAttachment != null)
                    {
                        rendererObject          = meshAttachment.RendererObject;
                        attachmentVertexCount   = meshAttachment.worldVerticesLength >> 1;
                        attachmentTriangleCount = meshAttachment.triangles.Length;
                    }
                    else
                    {
                        continue;
                    }
                }

                                #if !SPINE_TK2D
                // Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject; // For no customSlotMaterials

                Material material;
                if (isCustomSlotMaterialsPopulated)
                {
                    if (!customSlotMaterials.TryGetValue(slot, out material))
                    {
                        material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                    }
                }
                else
                {
                    material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                }
                                #else
                Material material = (rendererObject.GetType() == typeof(Material)) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject;
                                #endif

                // Create a new SubmeshInstruction when material changes. (or when forced to separate by a submeshSeparator)
                bool forceSeparate = (separatorSlotCount > 0 && separatorSlots.Contains(slot));
                if ((vertexCount > 0 && lastMaterial.GetInstanceID() != material.GetInstanceID()) || forceSeparate)
                {
                    workingSubmeshInstructions.Add(
                        new Spine.Unity.MeshGeneration.SubmeshInstruction {
                        skeleton         = this.skeleton,
                        material         = lastMaterial,
                        startSlot        = submeshStartSlotIndex,
                        endSlot          = i,
                        triangleCount    = submeshTriangleCount,
                        firstVertexIndex = submeshFirstVertex,
                        vertexCount      = submeshVertexCount,
                        forceSeparate    = forceSeparate
                    }
                        );

                    submeshTriangleCount  = 0;
                    submeshVertexCount    = 0;
                    submeshFirstVertex    = vertexCount;
                    submeshStartSlotIndex = i;
                }
                lastMaterial = material;

                submeshTriangleCount += attachmentTriangleCount;
                vertexCount          += attachmentVertexCount;
                submeshVertexCount   += attachmentVertexCount;
            }

            if (submeshVertexCount != 0)
            {
                workingSubmeshInstructions.Add(
                    new Spine.Unity.MeshGeneration.SubmeshInstruction {
                    skeleton         = this.skeleton,
                    material         = lastMaterial,
                    startSlot        = submeshStartSlotIndex,
                    endSlot          = drawOrderCount,
                    triangleCount    = submeshTriangleCount,
                    firstVertexIndex = submeshFirstVertex,
                    vertexCount      = submeshVertexCount,
                    forceSeparate    = false
                }
                    );
            }

            workingInstruction.vertexCount        = vertexCount;
            workingInstruction.immutableTriangles = this.immutableTriangles;
                        #if SPINE_OPTIONAL_FRONTFACING
            workingInstruction.frontFacing = this.frontFacing;
                        #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 (this.generateMeshOverride != null)
            {
                this.generateMeshOverride(workingInstruction);

                if (disableRenderingOnOverride)
                {
                    return;
                }
            }
                        #endif

            // STEP 2. Update vertex buffer based on verts from the attachments.
            // Uses values that were also stored in workingInstruction.
            Vector3[] vertices             = this.vertices;
            bool      vertexCountIncreased = vertexCount > vertices.Length;

            if (vertexCountIncreased)
            {
                this.vertices = vertices = new Vector3[vertexCount];
                this.colors   = new Color32[vertexCount];
                this.uvs      = new Vector2[vertexCount];

                                #if SPINE_OPTIONAL_NORMALS
                if (calculateNormals)
                {
                    Vector3[] localNormals = this.normals = new Vector3[vertexCount];
                    Vector3   normal       = new Vector3(0, 0, -1);
                    for (int i = 0; i < vertexCount; i++)
                    {
                        localNormals[i] = normal;
                    }
                }

                // For dynamic tangent calculation, you can remove the tangent-filling logic and add tangent calculation logic below.
                if (calculateTangents)
                {
                    Vector4[] localTangents = this.tangents = new Vector4[vertexCount];
                    Vector4   tangent       = new Vector4(1, 0, 0, -1);
                    for (int i = 0; i < vertexCount; i++)
                    {
                        localTangents[i] = tangent;
                    }
                }
                                #endif
            }
            else
            {
                Vector3 zero = Vector3.zero;
                for (int i = vertexCount, n = vertices.Length; i < n; i++)
                {
                    vertices[i] = zero;
                }
            }

            float     zSpacing        = this.zSpacing;
            float[]   tempVertices    = this.tempVertices;
            Vector2[] uvs             = this.uvs;
            Color32[] colors          = this.colors;
            int       vertexIndex     = 0;
            bool      pmaVertexColors = this.pmaVertexColors;
            Color32   color;
            float     a = skeleton.a * 255, r = skeleton.r, g = skeleton.g, b = skeleton.b;

            Vector3 meshBoundsMin;
            Vector3 meshBoundsMax;
            if (vertexCount == 0)
            {
                meshBoundsMin = new Vector3(0, 0, 0);
                meshBoundsMax = new Vector3(0, 0, 0);
            }
            else
            {
                meshBoundsMin.x = int.MaxValue;
                meshBoundsMin.y = int.MaxValue;
                meshBoundsMax.x = int.MinValue;
                meshBoundsMax.y = int.MinValue;
                if (zSpacing > 0f)
                {
                    meshBoundsMin.z = 0f;
                    meshBoundsMax.z = zSpacing * (drawOrderCount - 1);
                }
                else
                {
                    meshBoundsMin.z = zSpacing * (drawOrderCount - 1);
                    meshBoundsMax.z = 0f;
                }
                int i = 0;
                do
                {
                    Slot             slot             = drawOrderItems[i];
                    Attachment       attachment       = slot.attachment;
                    RegionAttachment regionAttachment = attachment as RegionAttachment;
                    if (regionAttachment != null)
                    {
                        regionAttachment.ComputeWorldVertices(slot.bone, tempVertices);

                        float z = i * zSpacing;
                        float x1 = tempVertices[RegionAttachment.X1], y1 = tempVertices[RegionAttachment.Y1];
                        float x2 = tempVertices[RegionAttachment.X2], y2 = tempVertices[RegionAttachment.Y2];
                        float x3 = tempVertices[RegionAttachment.X3], y3 = tempVertices[RegionAttachment.Y3];
                        float x4 = tempVertices[RegionAttachment.X4], y4 = tempVertices[RegionAttachment.Y4];
                        vertices[vertexIndex].x     = x1;
                        vertices[vertexIndex].y     = y1;
                        vertices[vertexIndex].z     = z;
                        vertices[vertexIndex + 1].x = x4;
                        vertices[vertexIndex + 1].y = y4;
                        vertices[vertexIndex + 1].z = z;
                        vertices[vertexIndex + 2].x = x2;
                        vertices[vertexIndex + 2].y = y2;
                        vertices[vertexIndex + 2].z = z;
                        vertices[vertexIndex + 3].x = x3;
                        vertices[vertexIndex + 3].y = y3;
                        vertices[vertexIndex + 3].z = z;

                        if (pmaVertexColors)
                        {
                            color.a = (byte)(a * slot.a * regionAttachment.a);
                            color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
                            color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
                            color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
                            if (slot.data.blendMode == BlendMode.additive)
                            {
                                color.a = 0;
                            }
                        }
                        else
                        {
                            color.a = (byte)(a * slot.a * regionAttachment.a);
                            color.r = (byte)(r * slot.r * regionAttachment.r * 255);
                            color.g = (byte)(g * slot.g * regionAttachment.g * 255);
                            color.b = (byte)(b * slot.b * regionAttachment.b * 255);
                        }

                        colors[vertexIndex]     = color;
                        colors[vertexIndex + 1] = color;
                        colors[vertexIndex + 2] = color;
                        colors[vertexIndex + 3] = color;

                        float[] regionUVs = regionAttachment.uvs;
                        uvs[vertexIndex].x     = regionUVs[RegionAttachment.X1];
                        uvs[vertexIndex].y     = regionUVs[RegionAttachment.Y1];
                        uvs[vertexIndex + 1].x = regionUVs[RegionAttachment.X4];
                        uvs[vertexIndex + 1].y = regionUVs[RegionAttachment.Y4];
                        uvs[vertexIndex + 2].x = regionUVs[RegionAttachment.X2];
                        uvs[vertexIndex + 2].y = regionUVs[RegionAttachment.Y2];
                        uvs[vertexIndex + 3].x = regionUVs[RegionAttachment.X3];
                        uvs[vertexIndex + 3].y = regionUVs[RegionAttachment.Y3];

                        // Calculate min/max X
                        if (x1 < meshBoundsMin.x)
                        {
                            meshBoundsMin.x = x1;
                        }
                        else if (x1 > meshBoundsMax.x)
                        {
                            meshBoundsMax.x = x1;
                        }
                        if (x2 < meshBoundsMin.x)
                        {
                            meshBoundsMin.x = x2;
                        }
                        else if (x2 > meshBoundsMax.x)
                        {
                            meshBoundsMax.x = x2;
                        }
                        if (x3 < meshBoundsMin.x)
                        {
                            meshBoundsMin.x = x3;
                        }
                        else if (x3 > meshBoundsMax.x)
                        {
                            meshBoundsMax.x = x3;
                        }
                        if (x4 < meshBoundsMin.x)
                        {
                            meshBoundsMin.x = x4;
                        }
                        else if (x4 > meshBoundsMax.x)
                        {
                            meshBoundsMax.x = x4;
                        }

                        // Calculate min/max Y
                        if (y1 < meshBoundsMin.y)
                        {
                            meshBoundsMin.y = y1;
                        }
                        else if (y1 > meshBoundsMax.y)
                        {
                            meshBoundsMax.y = y1;
                        }
                        if (y2 < meshBoundsMin.y)
                        {
                            meshBoundsMin.y = y2;
                        }
                        else if (y2 > meshBoundsMax.y)
                        {
                            meshBoundsMax.y = y2;
                        }
                        if (y3 < meshBoundsMin.y)
                        {
                            meshBoundsMin.y = y3;
                        }
                        else if (y3 > meshBoundsMax.y)
                        {
                            meshBoundsMax.y = y3;
                        }
                        if (y4 < meshBoundsMin.y)
                        {
                            meshBoundsMin.y = y4;
                        }
                        else if (y4 > meshBoundsMax.y)
                        {
                            meshBoundsMax.y = y4;
                        }

                        vertexIndex += 4;
                    }
                    else
                    {
                        if (!renderMeshes)
                        {
                            continue;
                        }
                        MeshAttachment meshAttachment = attachment as MeshAttachment;
                        if (meshAttachment != null)
                        {
                            int meshVertexCount = meshAttachment.worldVerticesLength;
                            if (tempVertices.Length < meshVertexCount)
                            {
                                this.tempVertices = tempVertices = new float[meshVertexCount];
                            }
                            meshAttachment.ComputeWorldVertices(slot, tempVertices);

                            if (pmaVertexColors)
                            {
                                color.a = (byte)(a * slot.a * meshAttachment.a);
                                color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
                                color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
                                color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
                                if (slot.data.blendMode == BlendMode.additive)
                                {
                                    color.a = 0;
                                }
                            }
                            else
                            {
                                color.a = (byte)(a * slot.a * meshAttachment.a);
                                color.r = (byte)(r * slot.r * meshAttachment.r * 255);
                                color.g = (byte)(g * slot.g * meshAttachment.g * 255);
                                color.b = (byte)(b * slot.b * meshAttachment.b * 255);
                            }

                            float[] meshUVs = meshAttachment.uvs;
                            float   z       = i * zSpacing;
                            for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                            {
                                float x = tempVertices[ii], y = tempVertices[ii + 1];
                                vertices[vertexIndex].x = x;
                                vertices[vertexIndex].y = y;
                                vertices[vertexIndex].z = z;
                                colors[vertexIndex]     = color;
                                uvs[vertexIndex].x      = meshUVs[ii];
                                uvs[vertexIndex].y      = meshUVs[ii + 1];

                                if (x < meshBoundsMin.x)
                                {
                                    meshBoundsMin.x = x;
                                }
                                else if (x > meshBoundsMax.x)
                                {
                                    meshBoundsMax.x = x;
                                }
                                if (y < meshBoundsMin.y)
                                {
                                    meshBoundsMin.y = y;
                                }
                                else if (y > meshBoundsMax.y)
                                {
                                    meshBoundsMax.y = y;
                                }
                            }
                        }
                    }
                } while (++i < drawOrderCount);
            }

            // Step 3. Move the mesh data into a UnityEngine.Mesh
            var currentSmartMesh = doubleBufferedMesh.GetNext();                // Double-buffer for performance.
            var currentMesh      = currentSmartMesh.mesh;

            currentMesh.vertices = vertices;
            currentMesh.colors32 = colors;
            currentMesh.uv       = uvs;

            Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;
            Vector3 meshBoundsCenter  = meshBoundsMin + meshBoundsExtents * 0.5f;
            currentMesh.bounds = new Bounds(meshBoundsCenter, meshBoundsExtents);

            var currentSmartMeshInstructionUsed = currentSmartMesh.instructionUsed;
                        #if SPINE_OPTIONAL_NORMALS
            if (currentSmartMeshInstructionUsed.vertexCount < vertexCount)
            {
                if (calculateNormals)
                {
                    currentMesh.normals = normals;
                }

                // For dynamic calculated tangents, this needs to be moved out of the vertexCount check block when replacing the logic, also ensuring the size.
                if (calculateTangents)
                {
                    currentMesh.tangents = this.tangents;
                }
            }
                        #endif

            // Check if the triangles should also be updated.
            // This thorough structure check is cheaper than updating triangles every frame.
            bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(workingInstruction, currentSmartMeshInstructionUsed);
            if (mustUpdateMeshStructure)
            {
                var thisSubmeshMaterials = this.submeshMaterials;
                thisSubmeshMaterials.Clear(false);

                int submeshCount    = workingSubmeshInstructions.Count;
                int oldSubmeshCount = submeshes.Count;

                submeshes.Capacity = submeshCount;
                for (int i = oldSubmeshCount; i < submeshCount; i++)
                {
                    submeshes.Items[i] = new SubmeshTriangleBuffer();
                }

                var mutableTriangles = !workingInstruction.immutableTriangles;
                for (int i = 0, last = submeshCount - 1; i < submeshCount; i++)
                {
                    var submeshInstruction = workingSubmeshInstructions.Items[i];
                    if (mutableTriangles || i >= oldSubmeshCount)
                    {
                        SetSubmesh(i, submeshInstruction,
                                                        #if SPINE_OPTIONAL_FRONTFACING
                                   currentInstructions.attachmentFlips,
                                                        #endif
                                   i == last);
                    }
                    thisSubmeshMaterials.Add(submeshInstruction.material);
                }

                currentMesh.subMeshCount = submeshCount;

                for (int i = 0; i < submeshCount; ++i)
                {
                    currentMesh.SetTriangles(submeshes.Items[i].triangles, i);
                }
            }

            // CheckIfMustUpdateMaterialArray (last pushed materials vs currently parsed materials)
            // Needs to check against the Working Submesh Instructions Materials instead of the cached submeshMaterials.
            {
                var  lastPushedMaterials         = this.sharedMaterials;
                bool mustUpdateRendererMaterials = mustUpdateMeshStructure ||
                                                   (lastPushedMaterials.Length != workingSubmeshInstructions.Count);

                if (!mustUpdateRendererMaterials)
                {
                    var workingSubmeshInstructionsItems = workingSubmeshInstructions.Items;
                    for (int i = 0, n = lastPushedMaterials.Length; i < n; i++)
                    {
                        if (lastPushedMaterials[i].GetInstanceID() != workingSubmeshInstructionsItems[i].material.GetInstanceID())                             // Bounds check is implied above.
                        {
                            mustUpdateRendererMaterials = true;
                            break;
                        }
                    }
                }

                if (mustUpdateRendererMaterials)
                {
                    if (submeshMaterials.Count == sharedMaterials.Length)
                    {
                        submeshMaterials.CopyTo(sharedMaterials);
                    }
                    else
                    {
                        sharedMaterials = submeshMaterials.ToArray();
                    }

                    meshRenderer.sharedMaterials = sharedMaterials;
                }
            }

            // Step 4. The UnityEngine.Mesh is ready. Set it as the MeshFilter's mesh. Store the instructions used for that mesh.
            meshFilter.sharedMesh = currentMesh;
            currentSmartMesh.instructionUsed.Set(workingInstruction);


            // Step 5. Miscellaneous
            // Add stuff here if you want

                        #if SPINE_OPTIONAL_SUBMESHRENDERER
            if (submeshRenderers.Length > 0)
            {
                for (int i = 0; i < submeshRenderers.Length; i++)
                {
                    var submeshRenderer = submeshRenderers[i];
                    if (submeshRenderer.submeshIndex < sharedMaterials.Length)
                    {
                        submeshRenderer.SetMesh(meshRenderer, currentMesh, sharedMaterials[submeshRenderer.submeshIndex]);
                    }
                    else
                    {
                        submeshRenderer.GetComponent <Renderer>().enabled = false;
                    }
                }
            }
                        #endif
        }
        // RegionAttachment
        protected void AddAttachment(Slot slot, RegionAttachment attachment)
        {
            var tempVertices = this.tempVertices;
            attachment.ComputeWorldVertices(slot.bone, tempVertices);

            float[] regionUVs = attachment.uvs;

            Color color = skeletonColor;
            color.r = color.r * attachment.r * slot.r;
            color.g = color.g * attachment.g * slot.g;
            color.b = color.b * attachment.b * slot.b;
            color.a = color.a * attachment.a * slot.a;
            if (premultiplyAlpha) {
                color.r *= color.a; color.g *= color.a; color.b *= color.a;
                if (slot.data.blendMode == BlendMode.additive) color.a = 0;
            }

            int fv = positions.Count; // first vertex index
            AddVert(new Vector3(tempVertices[RegionAttachment.X1] * scale, tempVertices[RegionAttachment.Y1] * scale), color, new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]));
            AddVert(new Vector3(tempVertices[RegionAttachment.X4] * scale, tempVertices[RegionAttachment.Y4] * scale), color, new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]));
            AddVert(new Vector3(tempVertices[RegionAttachment.X2] * scale, tempVertices[RegionAttachment.Y2] * scale), color, new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]));
            AddVert(new Vector3(tempVertices[RegionAttachment.X3] * scale, tempVertices[RegionAttachment.Y3] * scale), color, new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]));

            AddTriangle(fv, fv+2, fv+1);
            AddTriangle(fv+2, fv+3, fv+1);
        }
示例#14
0
        public void AddSubmesh(SubmeshInstruction instruction, bool updateTriangles = true)
        {
            Settings settings = this.settings;

            if (submeshes.Count - 1 < submeshIndex)
            {
                submeshes.Resize(submeshIndex + 1);
                if (submeshes.Items[submeshIndex] == null)
                {
                    submeshes.Items[submeshIndex] = new ExposedList <int>();
                }
            }
            ExposedList <int> exposedList = submeshes.Items[submeshIndex];

            exposedList.Clear(clearArray: false);
            Skeleton skeleton = instruction.skeleton;

            Slot[]  items           = skeleton.drawOrder.Items;
            Color32 color           = default(Color32);
            float   num             = skeleton.a * 255f;
            float   r               = skeleton.r;
            float   g               = skeleton.g;
            float   b               = skeleton.b;
            Vector2 vector          = meshBoundsMin;
            Vector2 vector2         = meshBoundsMax;
            float   zSpacing        = settings.zSpacing;
            bool    pmaVertexColors = settings.pmaVertexColors;
            bool    tintBlack       = settings.tintBlack;
            bool    flag            = settings.useClipping && instruction.hasClipping;

            if (flag && instruction.preActiveClippingSlotSource >= 0)
            {
                Slot slot = items[instruction.preActiveClippingSlotSource];
                clipper.ClipStart(slot, slot.attachment as ClippingAttachment);
            }
            for (int i = instruction.startSlot; i < instruction.endSlot; i++)
            {
                Slot             slot2            = items[i];
                Attachment       attachment       = slot2.attachment;
                float            z                = zSpacing * (float)i;
                float[]          array            = tempVerts;
                Color            color2           = default(Color);
                RegionAttachment regionAttachment = attachment as RegionAttachment;
                float[]          array2;
                int[]            array3;
                int num2;
                int num3;
                if (regionAttachment != null)
                {
                    regionAttachment.ComputeWorldVertices(slot2.bone, array, 0);
                    array2   = regionAttachment.uvs;
                    array3   = regionTriangles;
                    color2.r = regionAttachment.r;
                    color2.g = regionAttachment.g;
                    color2.b = regionAttachment.b;
                    color2.a = regionAttachment.a;
                    num2     = 4;
                    num3     = 6;
                }
                else
                {
                    MeshAttachment meshAttachment = attachment as MeshAttachment;
                    if (meshAttachment == null)
                    {
                        if (flag)
                        {
                            ClippingAttachment clippingAttachment = attachment as ClippingAttachment;
                            if (clippingAttachment != null)
                            {
                                clipper.ClipStart(slot2, clippingAttachment);
                            }
                        }
                        continue;
                    }
                    int worldVerticesLength = meshAttachment.worldVerticesLength;
                    if (array.Length < worldVerticesLength)
                    {
                        array = (tempVerts = new float[worldVerticesLength]);
                    }
                    meshAttachment.ComputeWorldVertices(slot2, 0, worldVerticesLength, array, 0);
                    array2   = meshAttachment.uvs;
                    array3   = meshAttachment.triangles;
                    color2.r = meshAttachment.r;
                    color2.g = meshAttachment.g;
                    color2.b = meshAttachment.b;
                    color2.a = meshAttachment.a;
                    num2     = worldVerticesLength >> 1;
                    num3     = meshAttachment.triangles.Length;
                }
                if (pmaVertexColors)
                {
                    color.a = (byte)(num * slot2.a * color2.a);
                    color.r = (byte)(r * slot2.r * color2.r * (float)(int)color.a);
                    color.g = (byte)(g * slot2.g * color2.g * (float)(int)color.a);
                    color.b = (byte)(b * slot2.b * color2.b * (float)(int)color.a);
                    if (slot2.data.blendMode == BlendMode.Additive)
                    {
                        color.a = 0;
                    }
                }
                else
                {
                    color.a = (byte)(num * slot2.a * color2.a);
                    color.r = (byte)(r * slot2.r * color2.r * 255f);
                    color.g = (byte)(g * slot2.g * color2.g * 255f);
                    color.b = (byte)(b * slot2.b * color2.b * 255f);
                }
                if (flag && clipper.IsClipping())
                {
                    clipper.ClipTriangles(array, num2 << 1, array3, num3, array2);
                    array  = clipper.clippedVertices.Items;
                    num2   = clipper.clippedVertices.Count >> 1;
                    array3 = clipper.clippedTriangles.Items;
                    num3   = clipper.clippedTriangles.Count;
                    array2 = clipper.clippedUVs.Items;
                }
                if (num2 != 0 && num3 != 0)
                {
                    if (tintBlack)
                    {
                        AddAttachmentTintBlack(slot2.r2, slot2.g2, slot2.b2, num2);
                    }
                    int count = vertexBuffer.Count;
                    int num4  = count + num2;
                    if (num4 > vertexBuffer.Items.Length)
                    {
                        Array.Resize(ref vertexBuffer.Items, num4);
                        Array.Resize(ref uvBuffer.Items, num4);
                        Array.Resize(ref colorBuffer.Items, num4);
                    }
                    vertexBuffer.Count = (uvBuffer.Count = (colorBuffer.Count = num4));
                    Vector3[] items2 = vertexBuffer.Items;
                    Vector2[] items3 = uvBuffer.Items;
                    Color32[] items4 = colorBuffer.Items;
                    if (count == 0)
                    {
                        for (int j = 0; j < num2; j++)
                        {
                            int   num5 = count + j;
                            int   num6 = j << 1;
                            float num7 = array[num6];
                            float num8 = array[num6 + 1];
                            items2[num5].x = num7;
                            items2[num5].y = num8;
                            items2[num5].z = z;
                            items3[num5].x = array2[num6];
                            items3[num5].y = array2[num6 + 1];
                            items4[num5]   = color;
                            if (num7 < vector.x)
                            {
                                vector.x = num7;
                            }
                            if (num7 > vector2.x)
                            {
                                vector2.x = num7;
                            }
                            if (num8 < vector.y)
                            {
                                vector.y = num8;
                            }
                            if (num8 > vector2.y)
                            {
                                vector2.y = num8;
                            }
                        }
                    }
                    else
                    {
                        for (int k = 0; k < num2; k++)
                        {
                            int   num9  = count + k;
                            int   num10 = k << 1;
                            float num11 = array[num10];
                            float num12 = array[num10 + 1];
                            items2[num9].x = num11;
                            items2[num9].y = num12;
                            items2[num9].z = z;
                            items3[num9].x = array2[num10];
                            items3[num9].y = array2[num10 + 1];
                            items4[num9]   = color;
                            if (num11 < vector.x)
                            {
                                vector.x = num11;
                            }
                            else if (num11 > vector2.x)
                            {
                                vector2.x = num11;
                            }
                            if (num12 < vector.y)
                            {
                                vector.y = num12;
                            }
                            else if (num12 > vector2.y)
                            {
                                vector2.y = num12;
                            }
                        }
                    }
                    if (updateTriangles)
                    {
                        int count2 = exposedList.Count;
                        int num13  = count2 + num3;
                        if (num13 > exposedList.Items.Length)
                        {
                            Array.Resize(ref exposedList.Items, num13);
                        }
                        exposedList.Count = num13;
                        int[] items5 = exposedList.Items;
                        for (int l = 0; l < num3; l++)
                        {
                            items5[count2 + l] = array3[l] + count;
                        }
                    }
                }
                clipper.ClipEnd(slot2);
            }
            clipper.ClipEnd();
            meshBoundsMin       = vector;
            meshBoundsMax       = vector2;
            meshBoundsThickness = (float)instruction.endSlot * zSpacing;
            int[] items6 = exposedList.Items;
            int   m      = exposedList.Count;

            for (int num14 = items6.Length; m < num14; m++)
            {
                items6[m] = 0;
            }
            submeshIndex++;
        }
示例#15
0
    public virtual void LateUpdate()
    {
        if (!valid)
        {
            return;
        }

        // Exit early if there is nothing to render
        if (!meshRenderer.enabled && submeshRenderers.Length == 0)
        {
            return;
        }

        // This method caches several .Items arrays. Whenever it does, there should be no mutations done on the overlying ExposedList object.

        // Count vertices and submesh triangles.
        int vertexCount = 0;

        int                submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
        Material           lastMaterial               = null;
        ExposedList <Slot> drawOrder                  = skeleton.drawOrder;
        var                drawOrderItems             = drawOrder.Items;
        int                drawOrderCount             = drawOrder.Count;
        int                submeshSeparatorSlotsCount = submeshSeparatorSlots.Count;
        bool               renderMeshes               = this.renderMeshes;

        // Clear last state of attachments and submeshes
        MeshState.SingleMeshState workingState = meshState.buffer;
        var workingAttachments = workingState.attachments;

        workingAttachments.Clear(true);
        workingState.UpdateAttachmentCount(drawOrderCount);
        var workingAttachmentsItems = workingAttachments.Items;

        var workingFlips      = workingState.attachmentsFlipState;
        var workingFlipsItems = workingState.attachmentsFlipState.Items;

        var workingSubmeshArguments = workingState.addSubmeshArguments;         // Items array should not be cached. There is dynamic writing to this object.

        workingSubmeshArguments.Clear(false);

        MeshState.SingleMeshState storedState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2;
        var storedAttachments      = storedState.attachments;
        var storedAttachmentsItems = storedAttachments.Items;

        var storedFlips      = storedState.attachmentsFlipState;
        var storedFlipsItems = storedFlips.Items;

        bool mustUpdateMeshStructure = storedState.requiresUpdate ||                         // Force update if the mesh was cleared. (prevents flickering due to incorrect state)
                                       drawOrderCount != storedAttachments.Count ||          // Number of slots changed (when does this happen?)
                                       immutableTriangles != storedState.immutableTriangles; // Immutable Triangles flag changed.

        bool isCustomMaterialsPopulated = customSlotMaterials.Count > 0;

        for (int i = 0; i < drawOrderCount; i++)
        {
            Slot       slot       = drawOrderItems[i];
            Bone       bone       = slot.bone;
            Attachment attachment = slot.attachment;

            object rendererObject;             // An AtlasRegion in plain Spine-Unity. Spine-TK2D hooks into TK2D's system. eventual source of Material object.
            int    attachmentVertexCount, attachmentTriangleCount;

            // Handle flipping for triangle winding (for lighting?).
            bool flip = frontFacing && (bone.WorldSignX != bone.WorldSignY);

            workingFlipsItems[i]       = flip;
            workingAttachmentsItems[i] = attachment;

            mustUpdateMeshStructure = mustUpdateMeshStructure ||                   // Always prefer short circuited or. || and not |=.
                                      (attachment != storedAttachmentsItems[i]) || // Attachment order changed. // This relies on the drawOrder.Count != storedAttachments.Count check above as a bounds check.
                                      (flip != storedFlipsItems[i]);               // Flip states changed.

            var regionAttachment = attachment as RegionAttachment;
            if (regionAttachment != null)
            {
                rendererObject          = regionAttachment.RendererObject;
                attachmentVertexCount   = 4;
                attachmentTriangleCount = 6;
            }
            else
            {
                if (!renderMeshes)
                {
                    continue;
                }
                var meshAttachment = attachment as MeshAttachment;
                if (meshAttachment != null)
                {
                    rendererObject          = meshAttachment.RendererObject;
                    attachmentVertexCount   = meshAttachment.vertices.Length >> 1;
                    attachmentTriangleCount = meshAttachment.triangles.Length;
                }
                else
                {
                    var skinnedMeshAttachment = attachment as WeightedMeshAttachment;
                    if (skinnedMeshAttachment != null)
                    {
                        rendererObject          = skinnedMeshAttachment.RendererObject;
                        attachmentVertexCount   = skinnedMeshAttachment.uvs.Length >> 1;
                        attachmentTriangleCount = skinnedMeshAttachment.triangles.Length;
                    }
                    else
                    {
                        continue;
                    }
                }
            }

                        #if !SPINE_TK2D
            // Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject; // For no customSlotMaterials

            Material material;
            if (isCustomMaterialsPopulated)
            {
                if (!customSlotMaterials.TryGetValue(slot, out material))
                {
                    material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                }
            }
            else
            {
                material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
            }
                        #else
            Material material = (rendererObject.GetType() == typeof(Material)) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject;
                        #endif

            // Populate submesh when material changes. (or when forced to separate by a submeshSeparator)
            if ((vertexCount > 0 && lastMaterial.GetInstanceID() != material.GetInstanceID()) ||
                (submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot)))
            {
                workingSubmeshArguments.Add(
                    new MeshState.AddSubmeshArguments {
                    material      = lastMaterial,
                    startSlot     = submeshStartSlotIndex,
                    endSlot       = i,
                    triangleCount = submeshTriangleCount,
                    firstVertex   = submeshFirstVertex,
                    isLastSubmesh = false
                }
                    );

                submeshTriangleCount  = 0;
                submeshFirstVertex    = vertexCount;
                submeshStartSlotIndex = i;
            }
            lastMaterial = material;

            submeshTriangleCount += attachmentTriangleCount;
            vertexCount          += attachmentVertexCount;
        }


        workingSubmeshArguments.Add(
            new MeshState.AddSubmeshArguments {
            material      = lastMaterial,
            startSlot     = submeshStartSlotIndex,
            endSlot       = drawOrderCount,
            triangleCount = submeshTriangleCount,
            firstVertex   = submeshFirstVertex,
            isLastSubmesh = true
        }
            );

        mustUpdateMeshStructure = mustUpdateMeshStructure ||
                                  this.sharedMaterials.Length != workingSubmeshArguments.Count || // Material array changed in size
                                  CheckIfMustUpdateMeshStructure(workingSubmeshArguments);        // Submesh Argument Array changed.

        // CheckIfMustUpdateMaterialArray (workingMaterials, sharedMaterials)
        if (!mustUpdateMeshStructure)
        {
            // Narrow phase material array check.
            var workingMaterials = workingSubmeshArguments.Items;
            for (int i = 0, n = sharedMaterials.Length; i < n; i++)
            {
                if (this.sharedMaterials[i] != workingMaterials[i].material)                    // Bounds check is implied above.
                {
                    mustUpdateMeshStructure = true;
                    break;
                }
            }
        }

        // NOT ELSE

        if (mustUpdateMeshStructure)
        {
            this.submeshMaterials.Clear();

            var workingSubmeshArgumentsItems = workingSubmeshArguments.Items;
            for (int i = 0, n = workingSubmeshArguments.Count; i < n; i++)
            {
                AddSubmesh(workingSubmeshArgumentsItems[i], workingFlips);
            }

            // Set materials.
            if (submeshMaterials.Count == sharedMaterials.Length)
            {
                submeshMaterials.CopyTo(sharedMaterials);
            }
            else
            {
                sharedMaterials = submeshMaterials.ToArray();
            }

            meshRenderer.sharedMaterials = sharedMaterials;
        }


        // Ensure mesh data is the right size.
        Vector3[] vertices     = this.vertices;
        bool      newTriangles = vertexCount > vertices.Length;
        if (newTriangles)
        {
            // Not enough vertices, increase size.
            this.vertices = vertices = new Vector3[vertexCount];
            this.colors   = new Color32[vertexCount];
            this.uvs      = new Vector2[vertexCount];

            mesh1.Clear();
            mesh2.Clear();
            meshState.stateMesh1.requiresUpdate = true;
            meshState.stateMesh2.requiresUpdate = true;
        }
        else
        {
            // Too many vertices, zero the extra.
            Vector3 zero = Vector3.zero;
            for (int i = vertexCount, n = meshState.vertexCount; i < n; i++)
            {
                vertices[i] = zero;
            }
        }
        meshState.vertexCount = vertexCount;

        // Setup mesh.
        float     zSpacing     = this.zSpacing;
        float[]   tempVertices = this.tempVertices;
        Vector2[] uvs          = this.uvs;
        Color32[] colors       = this.colors;
        int       vertexIndex  = 0;
        Color32   color;
        float     a = skeleton.a * 255, r = skeleton.r, g = skeleton.g, b = skeleton.b;

        Vector3 meshBoundsMin;
        Vector3 meshBoundsMax;
        if (vertexCount == 0)
        {
            meshBoundsMin = new Vector3(0, 0, 0);
            meshBoundsMax = new Vector3(0, 0, 0);
        }
        else
        {
            meshBoundsMin.x = int.MaxValue;
            meshBoundsMin.y = int.MaxValue;
            meshBoundsMax.x = int.MinValue;
            meshBoundsMax.y = int.MinValue;
            if (zSpacing > 0f)
            {
                meshBoundsMin.z = 0f;
                meshBoundsMax.z = zSpacing * (drawOrderCount - 1);
            }
            else
            {
                meshBoundsMin.z = zSpacing * (drawOrderCount - 1);
                meshBoundsMax.z = 0f;
            }
            int i = 0;
            do
            {
                Slot             slot             = drawOrderItems[i];
                Attachment       attachment       = slot.attachment;
                RegionAttachment regionAttachment = attachment as RegionAttachment;
                if (regionAttachment != null)
                {
                    regionAttachment.ComputeWorldVertices(slot.bone, tempVertices);

                    float z = i * zSpacing;
                    float x1 = tempVertices[RegionAttachment.X1], y1 = tempVertices[RegionAttachment.Y1];
                    float x2 = tempVertices[RegionAttachment.X2], y2 = tempVertices[RegionAttachment.Y2];
                    float x3 = tempVertices[RegionAttachment.X3], y3 = tempVertices[RegionAttachment.Y3];
                    float x4 = tempVertices[RegionAttachment.X4], y4 = tempVertices[RegionAttachment.Y4];
                    vertices[vertexIndex].x     = x1;
                    vertices[vertexIndex].y     = y1;
                    vertices[vertexIndex].z     = z;
                    vertices[vertexIndex + 1].x = x4;
                    vertices[vertexIndex + 1].y = y4;
                    vertices[vertexIndex + 1].z = z;
                    vertices[vertexIndex + 2].x = x2;
                    vertices[vertexIndex + 2].y = y2;
                    vertices[vertexIndex + 2].z = z;
                    vertices[vertexIndex + 3].x = x3;
                    vertices[vertexIndex + 3].y = y3;
                    vertices[vertexIndex + 3].z = z;

                    color.a = (byte)(a * slot.a * regionAttachment.a);
                    color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
                    color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
                    color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
                    if (slot.data.blendMode == BlendMode.additive)
                    {
                        color.a = 0;
                    }
                    colors[vertexIndex]     = color;
                    colors[vertexIndex + 1] = color;
                    colors[vertexIndex + 2] = color;
                    colors[vertexIndex + 3] = color;

                    float[] regionUVs = regionAttachment.uvs;
                    uvs[vertexIndex].x     = regionUVs[RegionAttachment.X1];
                    uvs[vertexIndex].y     = regionUVs[RegionAttachment.Y1];
                    uvs[vertexIndex + 1].x = regionUVs[RegionAttachment.X4];
                    uvs[vertexIndex + 1].y = regionUVs[RegionAttachment.Y4];
                    uvs[vertexIndex + 2].x = regionUVs[RegionAttachment.X2];
                    uvs[vertexIndex + 2].y = regionUVs[RegionAttachment.Y2];
                    uvs[vertexIndex + 3].x = regionUVs[RegionAttachment.X3];
                    uvs[vertexIndex + 3].y = regionUVs[RegionAttachment.Y3];

                    // Calculate min/max X
                    if (x1 < meshBoundsMin.x)
                    {
                        meshBoundsMin.x = x1;
                    }
                    else if (x1 > meshBoundsMax.x)
                    {
                        meshBoundsMax.x = x1;
                    }
                    if (x2 < meshBoundsMin.x)
                    {
                        meshBoundsMin.x = x2;
                    }
                    else if (x2 > meshBoundsMax.x)
                    {
                        meshBoundsMax.x = x2;
                    }
                    if (x3 < meshBoundsMin.x)
                    {
                        meshBoundsMin.x = x3;
                    }
                    else if (x3 > meshBoundsMax.x)
                    {
                        meshBoundsMax.x = x3;
                    }
                    if (x4 < meshBoundsMin.x)
                    {
                        meshBoundsMin.x = x4;
                    }
                    else if (x4 > meshBoundsMax.x)
                    {
                        meshBoundsMax.x = x4;
                    }

                    // Calculate min/max Y
                    if (y1 < meshBoundsMin.y)
                    {
                        meshBoundsMin.y = y1;
                    }
                    else if (y1 > meshBoundsMax.y)
                    {
                        meshBoundsMax.y = y1;
                    }
                    if (y2 < meshBoundsMin.y)
                    {
                        meshBoundsMin.y = y2;
                    }
                    else if (y2 > meshBoundsMax.y)
                    {
                        meshBoundsMax.y = y2;
                    }
                    if (y3 < meshBoundsMin.y)
                    {
                        meshBoundsMin.y = y3;
                    }
                    else if (y3 > meshBoundsMax.y)
                    {
                        meshBoundsMax.y = y3;
                    }
                    if (y4 < meshBoundsMin.y)
                    {
                        meshBoundsMin.y = y4;
                    }
                    else if (y4 > meshBoundsMax.y)
                    {
                        meshBoundsMax.y = y4;
                    }

                    vertexIndex += 4;
                }
                else
                {
                    if (!renderMeshes)
                    {
                        continue;
                    }
                    MeshAttachment meshAttachment = attachment as MeshAttachment;
                    if (meshAttachment != null)
                    {
                        int meshVertexCount = meshAttachment.vertices.Length;
                        if (tempVertices.Length < meshVertexCount)
                        {
                            this.tempVertices = tempVertices = new float[meshVertexCount];
                        }
                        meshAttachment.ComputeWorldVertices(slot, tempVertices);

                        color.a = (byte)(a * slot.a * meshAttachment.a);
                        color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
                        color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
                        color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
                        if (slot.data.blendMode == BlendMode.additive)
                        {
                            color.a = 0;
                        }

                        float[] meshUVs = meshAttachment.uvs;
                        float   z       = i * zSpacing;
                        for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                        {
                            float x = tempVertices[ii], y = tempVertices[ii + 1];
                            vertices[vertexIndex].x = x;
                            vertices[vertexIndex].y = y;
                            vertices[vertexIndex].z = z;
                            colors[vertexIndex]     = color;
                            uvs[vertexIndex].x      = meshUVs[ii];
                            uvs[vertexIndex].y      = meshUVs[ii + 1];

                            if (x < meshBoundsMin.x)
                            {
                                meshBoundsMin.x = x;
                            }
                            else if (x > meshBoundsMax.x)
                            {
                                meshBoundsMax.x = x;
                            }
                            if (y < meshBoundsMin.y)
                            {
                                meshBoundsMin.y = y;
                            }
                            else if (y > meshBoundsMax.y)
                            {
                                meshBoundsMax.y = y;
                            }
                        }
                    }
                    else
                    {
                        WeightedMeshAttachment weightedMeshAttachment = attachment as WeightedMeshAttachment;
                        if (weightedMeshAttachment != null)
                        {
                            int meshVertexCount = weightedMeshAttachment.uvs.Length;
                            if (tempVertices.Length < meshVertexCount)
                            {
                                this.tempVertices = tempVertices = new float[meshVertexCount];
                            }
                            weightedMeshAttachment.ComputeWorldVertices(slot, tempVertices);

                            color.a = (byte)(a * slot.a * weightedMeshAttachment.a);
                            color.r = (byte)(r * slot.r * weightedMeshAttachment.r * color.a);
                            color.g = (byte)(g * slot.g * weightedMeshAttachment.g * color.a);
                            color.b = (byte)(b * slot.b * weightedMeshAttachment.b * color.a);
                            if (slot.data.blendMode == BlendMode.additive)
                            {
                                color.a = 0;
                            }

                            float[] meshUVs = weightedMeshAttachment.uvs;
                            float   z       = i * zSpacing;
                            for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                            {
                                float x = tempVertices[ii], y = tempVertices[ii + 1];
                                vertices[vertexIndex].x = x;
                                vertices[vertexIndex].y = y;
                                vertices[vertexIndex].z = z;
                                colors[vertexIndex]     = color;
                                uvs[vertexIndex].x      = meshUVs[ii];
                                uvs[vertexIndex].y      = meshUVs[ii + 1];

                                if (x < meshBoundsMin.x)
                                {
                                    meshBoundsMin.x = x;
                                }
                                else if (x > meshBoundsMax.x)
                                {
                                    meshBoundsMax.x = x;
                                }
                                if (y < meshBoundsMin.y)
                                {
                                    meshBoundsMin.y = y;
                                }
                                else if (y > meshBoundsMax.y)
                                {
                                    meshBoundsMax.y = y;
                                }
                            }
                        }
                    }
                }
            } while (++i < drawOrderCount);
        }

        // Double buffer mesh.
        Mesh mesh = useMesh1 ? mesh1 : mesh2;
        meshFilter.sharedMesh = mesh;

        mesh.vertices = vertices;
        mesh.colors32 = colors;
        mesh.uv       = uvs;

        if (mustUpdateMeshStructure)
        {
            int submeshCount = submeshMaterials.Count;
            mesh.subMeshCount = submeshCount;
            for (int i = 0; i < submeshCount; ++i)
            {
                mesh.SetTriangles(submeshes.Items[i].triangles, i);
            }

            // Done updating mesh.
            storedState.requiresUpdate = false;
        }

        Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;
        Vector3 meshBoundsCenter  = meshBoundsMin + meshBoundsExtents * 0.5f;
        mesh.bounds = new Bounds(meshBoundsCenter, meshBoundsExtents);

        if (newTriangles && calculateNormals)
        {
            Vector3[] normals = new Vector3[vertexCount];
            Vector3   normal  = new Vector3(0, 0, -1);
            for (int i = 0; i < vertexCount; i++)
            {
                normals[i] = normal;
            }
            (useMesh1 ? mesh2 : mesh1).vertices = vertices;             // Set other mesh vertices.
            mesh1.normals = normals;
            mesh2.normals = normals;

            if (calculateTangents)
            {
                Vector4[] tangents = new Vector4[vertexCount];
                Vector4   tangent  = new Vector4(1, 0, 0, -1);
                for (int i = 0; i < vertexCount; i++)
                {
                    tangents[i] = tangent;
                }
                mesh1.tangents = tangents;
                mesh2.tangents = tangents;
            }
        }

        // Update previous state
        storedState.immutableTriangles = immutableTriangles;

        storedAttachments.Clear(true);
        storedAttachments.GrowIfNeeded(workingAttachments.Capacity);
        storedAttachments.Count = workingAttachments.Count;
        workingAttachments.CopyTo(storedAttachments.Items);

        storedFlips.GrowIfNeeded(workingFlips.Capacity);
        storedFlips.Count = workingFlips.Count;
        workingFlips.CopyTo(storedFlips.Items);

        storedState.addSubmeshArguments.GrowIfNeeded(workingSubmeshArguments.Capacity);
        storedState.addSubmeshArguments.Count = workingSubmeshArguments.Count;
        workingSubmeshArguments.CopyTo(storedState.addSubmeshArguments.Items);


        // Submesh Renderers
        if (submeshRenderers.Length > 0)
        {
            for (int i = 0; i < submeshRenderers.Length; i++)
            {
                SkeletonUtilitySubmeshRenderer submeshRenderer = submeshRenderers[i];
                if (submeshRenderer.submeshIndex < sharedMaterials.Length)
                {
                    submeshRenderer.SetMesh(meshRenderer, useMesh1 ? mesh1 : mesh2, sharedMaterials[submeshRenderer.submeshIndex]);
                }
                else
                {
                    submeshRenderer.GetComponent <Renderer>().enabled = false;
                }
            }
        }

        useMesh1 = !useMesh1;
    }
示例#16
0
        protected void UpdateSkeletonGeometry()
        {
            skeletonGeometry.ClearInstances();
            //defaultBlendState = PremultipliedAlpha ? BlendState.AlphaBlend : BlendState.NonPremultiplied;


            float[]     vertices = this.vertices;
            List <Slot> drawOrder = Skeleton.DrawOrder;
            float       x = Skeleton.X, y = Skeleton.Y;

            CCColor3B color3b   = Color;
            float     skeletonR = color3b.R / 255f;
            float     skeletonG = color3b.G / 255f;
            float     skeletonB = color3b.B / 255f;
            float     skeletonA = Opacity / 255f;

            for (int i = 0, n = drawOrder.Count; i < n; i++)
            {
                Slot       slot       = drawOrder[i];
                Attachment attachment = slot.Attachment;
                if (attachment is RegionAttachment)
                {
                    RegionAttachment regionAttachment = (RegionAttachment)attachment;
                    //BlendState blend = slot.Data.AdditiveBlending ? BlendState.Additive : defaultBlendState;

                    var item = skeletonGeometry.CreateGeometryInstance(4, 6);

                    //item.InstanceAttributes.BlendState = blend;
                    //item.InstanceAttributes.AdditionalTransform = AffineWorldTransform;
                    item.GeometryPacket.Indicies = quadTriangles;

                    var itemVertices = item.GeometryPacket.Vertices;

                    AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject;
                    item.GeometryPacket.Texture = (CCTexture2D)region.page.rendererObject;

                    CCColor4B color;
                    float     a = skeletonA * slot.A * regionAttachment.A;
                    if (PremultipliedAlpha)
                    {
                        color = new CCColor4B(
                            skeletonR * slot.R * regionAttachment.R * a,
                            skeletonG * slot.G * regionAttachment.G * a,
                            skeletonB * slot.B * regionAttachment.B * a, a);
                    }
                    else
                    {
                        color = new CCColor4B(
                            skeletonR * slot.R * regionAttachment.R,
                            skeletonG * slot.G * regionAttachment.G,
                            skeletonB * slot.B * regionAttachment.B, a);
                    }
                    itemVertices[TL].Colors = color;
                    itemVertices[BL].Colors = color;
                    itemVertices[BR].Colors = color;
                    itemVertices[TR].Colors = color;

                    regionAttachment.ComputeWorldVertices(x, y, slot.Bone, vertices);
                    itemVertices[TL].Vertices.X = vertices[RegionAttachment.X1];
                    itemVertices[TL].Vertices.Y = vertices[RegionAttachment.Y1];
                    itemVertices[TL].Vertices.Z = 0;
                    itemVertices[BL].Vertices.X = vertices[RegionAttachment.X2];
                    itemVertices[BL].Vertices.Y = vertices[RegionAttachment.Y2];
                    itemVertices[BL].Vertices.Z = 0;
                    itemVertices[BR].Vertices.X = vertices[RegionAttachment.X3];
                    itemVertices[BR].Vertices.Y = vertices[RegionAttachment.Y3];
                    itemVertices[BR].Vertices.Z = 0;
                    itemVertices[TR].Vertices.X = vertices[RegionAttachment.X4];
                    itemVertices[TR].Vertices.Y = vertices[RegionAttachment.Y4];
                    itemVertices[TR].Vertices.Z = 0;

                    float[] uvs = regionAttachment.UVs;
                    itemVertices[TL].TexCoords.U = uvs[RegionAttachment.X1];
                    itemVertices[TL].TexCoords.V = uvs[RegionAttachment.Y1];
                    itemVertices[BL].TexCoords.U = uvs[RegionAttachment.X2];
                    itemVertices[BL].TexCoords.V = uvs[RegionAttachment.Y2];
                    itemVertices[BR].TexCoords.U = uvs[RegionAttachment.X3];
                    itemVertices[BR].TexCoords.V = uvs[RegionAttachment.Y3];
                    itemVertices[TR].TexCoords.U = uvs[RegionAttachment.X4];
                    itemVertices[TR].TexCoords.V = uvs[RegionAttachment.Y4];
                }
                else if (attachment is MeshAttachment)
                {
                    MeshAttachment mesh        = (MeshAttachment)attachment;
                    int            vertexCount = mesh.Vertices.Length;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    mesh.ComputeWorldVertices(x, y, slot, vertices);

                    int[] triangles = mesh.Triangles;
                    var   item      = skeletonGeometry.CreateGeometryInstance(vertexCount, triangles.Length);
                    //item.InstanceAttributes.AdditionalTransform = AffineWorldTransform;
                    item.GeometryPacket.Indicies = triangles;

                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    item.GeometryPacket.Texture = (CCTexture2D)region.page.rendererObject;

                    CCColor4B color;
                    float     a = skeletonA * slot.A * mesh.A;
                    if (PremultipliedAlpha)
                    {
                        color = new CCColor4B(
                            skeletonR * slot.R * mesh.R * a,
                            skeletonG * slot.G * mesh.G * a,
                            skeletonB * slot.B * mesh.B * a, a);
                    }
                    else
                    {
                        color = new CCColor4B(
                            skeletonR * slot.R * mesh.R,
                            skeletonG * slot.G * mesh.G,
                            skeletonB * slot.B * mesh.B, a);
                    }

                    float[] uvs          = mesh.UVs;
                    var     itemVertices = item.GeometryPacket.Vertices;
                    for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2)
                    {
                        itemVertices[ii].Colors      = color;
                        itemVertices[ii].Vertices.X  = vertices[v];
                        itemVertices[ii].Vertices.Y  = vertices[v + 1];
                        itemVertices[ii].Vertices.Z  = 0;
                        itemVertices[ii].TexCoords.U = uvs[v];
                        itemVertices[ii].TexCoords.V = uvs[v + 1];
                    }
                }
                else if (attachment is SkinnedMeshAttachment)
                {
                    SkinnedMeshAttachment mesh = (SkinnedMeshAttachment)attachment;
                    int vertexCount            = mesh.UVs.Length;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    mesh.ComputeWorldVertices(x, y, slot, vertices);

                    int[] triangles = mesh.Triangles;
                    var   item      = skeletonGeometry.CreateGeometryInstance(vertexCount, triangles.Length);
                    item.GeometryPacket.Indicies = triangles;
                    //item.InstanceAttributes.AdditionalTransform = AffineWorldTransform;

                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    item.GeometryPacket.Texture = (CCTexture2D)region.page.rendererObject;

                    CCColor4B color;
                    float     a = skeletonA * slot.A * mesh.A;
                    if (PremultipliedAlpha)
                    {
                        color = new CCColor4B(
                            skeletonR * slot.R * mesh.R * a,
                            skeletonG * slot.G * mesh.G * a,
                            skeletonB * slot.B * mesh.B * a, a);
                    }
                    else
                    {
                        color = new CCColor4B(
                            skeletonR * slot.R * mesh.R,
                            skeletonG * slot.G * mesh.G,
                            skeletonB * slot.B * mesh.B, a);
                    }

                    float[] uvs          = mesh.UVs;
                    var     itemVertices = item.GeometryPacket.Vertices;
                    for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2)
                    {
                        itemVertices[ii].Colors      = color;
                        itemVertices[ii].Vertices.X  = vertices[v];
                        itemVertices[ii].Vertices.Y  = vertices[v + 1];
                        itemVertices[ii].Vertices.Z  = 0;
                        itemVertices[ii].TexCoords.U = uvs[v];
                        itemVertices[ii].TexCoords.V = uvs[v + 1];
                    }
                }
            }

            debugger.Clear();

            if (DebugBones || DebugSlots)
            {
                if (DebugSlots)
                {
                    for (int i = 0; i < Skeleton.Slots.Count; ++i)
                    {
                        var slot = Skeleton.Slots[i];

                        if (slot.Attachment == null)
                        {
                            continue;
                        }

                        var verticesCount = 0;
                        var worldVertices = new float[1000]; // Max number of vertices per mesh.
                        if (slot.Attachment is RegionAttachment)
                        {
                            var attachment = (RegionAttachment)slot.Attachment;
                            attachment.ComputeWorldVertices(Skeleton.X, Skeleton.Y, slot.bone, worldVertices);
                            verticesCount = 8;
                        }
                        else if (slot.Attachment is MeshAttachment)
                        {
                            var mesh = (MeshAttachment)slot.Attachment;
                            mesh.ComputeWorldVertices(Skeleton.X, Skeleton.Y, slot, worldVertices);
                            verticesCount = mesh.Vertices.Length;
                        }
                        else if (slot.Attachment is SkinnedMeshAttachment)
                        {
                            var mesh = (SkinnedMeshAttachment)slot.Attachment;
                            mesh.ComputeWorldVertices(Skeleton.X, Skeleton.Y, slot, worldVertices);
                            verticesCount = mesh.UVs.Length;
                        }
                        else
                        {
                            continue;
                        }

                        CCPoint[] slotVertices = new CCPoint[verticesCount / 2];

                        for (int ii = 0, si = 0; ii < verticesCount; ii += 2, si++)
                        {
                            slotVertices[si].X = worldVertices[ii] * ScaleX;
                            slotVertices[si].Y = worldVertices[ii + 1] * ScaleY;
                        }

                        debugger.DrawPolygon(slotVertices, verticesCount / 2, CCColor4B.Transparent, 1, DebugSlotColor);
                    }
                }

                if (DebugBones)
                {
                    // Bone lengths.
                    for (int i = 0; i < Skeleton.Bones.Count; i++)
                    {
                        Bone bone = Skeleton.Bones[i];
                        x = bone.Data.Length * bone.M00 + bone.WorldX;
                        y = bone.Data.Length * bone.M10 + bone.WorldY;

                        debugger.DrawLine(new CCPoint(bone.WorldX, bone.WorldY), new CCPoint(x, y), 1, DebugJointColor);
                    }

                    // Bone origins.
                    for (int i = 0; i < Skeleton.Bones.Count; i++)
                    {
                        Bone bone = Skeleton.Bones[i];
                        debugger.DrawDot(new CCPoint(bone.WorldX, bone.WorldY), 3, DebugBoneColor);
                    }
                }
            }
        }
示例#17
0
        public void BuildMeshWithArrays(SkeletonRendererInstruction instruction, bool updateTriangles)
        {
            Settings settings       = this.settings;
            int      rawVertexCount = instruction.rawVertexCount;

            if (rawVertexCount > vertexBuffer.Items.Length)
            {
                Array.Resize(ref vertexBuffer.Items, rawVertexCount);
                Array.Resize(ref uvBuffer.Items, rawVertexCount);
                Array.Resize(ref colorBuffer.Items, rawVertexCount);
            }
            vertexBuffer.Count = (uvBuffer.Count = (colorBuffer.Count = rawVertexCount));
            Color32 color = default(Color32);
            int     num   = 0;

            float[] array = tempVerts;
            Vector3 v     = meshBoundsMin;
            Vector3 v2    = meshBoundsMax;

            Vector3[] items   = vertexBuffer.Items;
            Vector2[] items2  = uvBuffer.Items;
            Color32[] items3  = colorBuffer.Items;
            int       num2    = 0;
            int       i       = 0;
            Vector2   vector  = default(Vector2);
            Vector2   vector2 = default(Vector2);

            for (int count = instruction.submeshInstructions.Count; i < count; i++)
            {
                SubmeshInstruction submeshInstruction = instruction.submeshInstructions.Items[i];
                Skeleton           skeleton           = submeshInstruction.skeleton;
                Slot[]             items4             = skeleton.drawOrder.Items;
                float num3      = skeleton.a * 255f;
                float r         = skeleton.r;
                float g         = skeleton.g;
                float b         = skeleton.b;
                int   endSlot   = submeshInstruction.endSlot;
                int   startSlot = submeshInstruction.startSlot;
                num2 = endSlot;
                if (settings.tintBlack)
                {
                    int num4 = num;
                    vector.y = 1f;
                    if (uv2 == null)
                    {
                        uv2 = new ExposedList <Vector2>();
                        uv3 = new ExposedList <Vector2>();
                    }
                    if (rawVertexCount > uv2.Items.Length)
                    {
                        Array.Resize(ref uv2.Items, rawVertexCount);
                        Array.Resize(ref uv3.Items, rawVertexCount);
                    }
                    uv2.Count = (uv3.Count = rawVertexCount);
                    Vector2[] items5 = uv2.Items;
                    Vector2[] items6 = uv3.Items;
                    for (int j = startSlot; j < endSlot; j++)
                    {
                        Slot       slot       = items4[j];
                        Attachment attachment = slot.attachment;
                        vector2.x = slot.r2;
                        vector2.y = slot.g2;
                        vector.x  = slot.b2;
                        RegionAttachment regionAttachment = attachment as RegionAttachment;
                        if (regionAttachment != null)
                        {
                            items5[num4]     = vector2;
                            items5[num4 + 1] = vector2;
                            items5[num4 + 2] = vector2;
                            items5[num4 + 3] = vector2;
                            items6[num4]     = vector;
                            items6[num4 + 1] = vector;
                            items6[num4 + 2] = vector;
                            items6[num4 + 3] = vector;
                            num4            += 4;
                            continue;
                        }
                        MeshAttachment meshAttachment = attachment as MeshAttachment;
                        if (meshAttachment != null)
                        {
                            int worldVerticesLength = meshAttachment.worldVerticesLength;
                            for (int k = 0; k < worldVerticesLength; k += 2)
                            {
                                items5[num4] = vector2;
                                items6[num4] = vector;
                                num4++;
                            }
                        }
                    }
                }
                for (int l = startSlot; l < endSlot; l++)
                {
                    Slot             slot2             = items4[l];
                    Attachment       attachment2       = slot2.attachment;
                    float            z                 = (float)l * settings.zSpacing;
                    RegionAttachment regionAttachment2 = attachment2 as RegionAttachment;
                    if (regionAttachment2 != null)
                    {
                        regionAttachment2.ComputeWorldVertices(slot2.bone, array, 0);
                        float num5  = array[0];
                        float num6  = array[1];
                        float num7  = array[2];
                        float num8  = array[3];
                        float num9  = array[4];
                        float num10 = array[5];
                        float num11 = array[6];
                        float num12 = array[7];
                        items[num].x     = num5;
                        items[num].y     = num6;
                        items[num].z     = z;
                        items[num + 1].x = num11;
                        items[num + 1].y = num12;
                        items[num + 1].z = z;
                        items[num + 2].x = num7;
                        items[num + 2].y = num8;
                        items[num + 2].z = z;
                        items[num + 3].x = num9;
                        items[num + 3].y = num10;
                        items[num + 3].z = z;
                        if (settings.pmaVertexColors)
                        {
                            color.a = (byte)(num3 * slot2.a * regionAttachment2.a);
                            color.r = (byte)(r * slot2.r * regionAttachment2.r * (float)(int)color.a);
                            color.g = (byte)(g * slot2.g * regionAttachment2.g * (float)(int)color.a);
                            color.b = (byte)(b * slot2.b * regionAttachment2.b * (float)(int)color.a);
                            if (slot2.data.blendMode == BlendMode.Additive)
                            {
                                color.a = 0;
                            }
                        }
                        else
                        {
                            color.a = (byte)(num3 * slot2.a * regionAttachment2.a);
                            color.r = (byte)(r * slot2.r * regionAttachment2.r * 255f);
                            color.g = (byte)(g * slot2.g * regionAttachment2.g * 255f);
                            color.b = (byte)(b * slot2.b * regionAttachment2.b * 255f);
                        }
                        items3[num]     = color;
                        items3[num + 1] = color;
                        items3[num + 2] = color;
                        items3[num + 3] = color;
                        float[] uvs = regionAttachment2.uvs;
                        items2[num].x     = uvs[0];
                        items2[num].y     = uvs[1];
                        items2[num + 1].x = uvs[6];
                        items2[num + 1].y = uvs[7];
                        items2[num + 2].x = uvs[2];
                        items2[num + 2].y = uvs[3];
                        items2[num + 3].x = uvs[4];
                        items2[num + 3].y = uvs[5];
                        if (num5 < v.x)
                        {
                            v.x = num5;
                        }
                        if (num5 > v2.x)
                        {
                            v2.x = num5;
                        }
                        if (num7 < v.x)
                        {
                            v.x = num7;
                        }
                        else if (num7 > v2.x)
                        {
                            v2.x = num7;
                        }
                        if (num9 < v.x)
                        {
                            v.x = num9;
                        }
                        else if (num9 > v2.x)
                        {
                            v2.x = num9;
                        }
                        if (num11 < v.x)
                        {
                            v.x = num11;
                        }
                        else if (num11 > v2.x)
                        {
                            v2.x = num11;
                        }
                        if (num6 < v.y)
                        {
                            v.y = num6;
                        }
                        if (num6 > v2.y)
                        {
                            v2.y = num6;
                        }
                        if (num8 < v.y)
                        {
                            v.y = num8;
                        }
                        else if (num8 > v2.y)
                        {
                            v2.y = num8;
                        }
                        if (num10 < v.y)
                        {
                            v.y = num10;
                        }
                        else if (num10 > v2.y)
                        {
                            v2.y = num10;
                        }
                        if (num12 < v.y)
                        {
                            v.y = num12;
                        }
                        else if (num12 > v2.y)
                        {
                            v2.y = num12;
                        }
                        num += 4;
                        continue;
                    }
                    MeshAttachment meshAttachment2 = attachment2 as MeshAttachment;
                    if (meshAttachment2 == null)
                    {
                        continue;
                    }
                    int worldVerticesLength2 = meshAttachment2.worldVerticesLength;
                    if (array.Length < worldVerticesLength2)
                    {
                        array = (tempVerts = new float[worldVerticesLength2]);
                    }
                    meshAttachment2.ComputeWorldVertices(slot2, array);
                    if (settings.pmaVertexColors)
                    {
                        color.a = (byte)(num3 * slot2.a * meshAttachment2.a);
                        color.r = (byte)(r * slot2.r * meshAttachment2.r * (float)(int)color.a);
                        color.g = (byte)(g * slot2.g * meshAttachment2.g * (float)(int)color.a);
                        color.b = (byte)(b * slot2.b * meshAttachment2.b * (float)(int)color.a);
                        if (slot2.data.blendMode == BlendMode.Additive)
                        {
                            color.a = 0;
                        }
                    }
                    else
                    {
                        color.a = (byte)(num3 * slot2.a * meshAttachment2.a);
                        color.r = (byte)(r * slot2.r * meshAttachment2.r * 255f);
                        color.g = (byte)(g * slot2.g * meshAttachment2.g * 255f);
                        color.b = (byte)(b * slot2.b * meshAttachment2.b * 255f);
                    }
                    float[] uvs2 = meshAttachment2.uvs;
                    if (num == 0)
                    {
                        float num13 = array[0];
                        float num14 = array[1];
                        if (num13 < v.x)
                        {
                            v.x = num13;
                        }
                        if (num13 > v2.x)
                        {
                            v2.x = num13;
                        }
                        if (num14 < v.y)
                        {
                            v.y = num14;
                        }
                        if (num14 > v2.y)
                        {
                            v2.y = num14;
                        }
                    }
                    for (int m = 0; m < worldVerticesLength2; m += 2)
                    {
                        float num15 = array[m];
                        float num16 = array[m + 1];
                        items[num].x  = num15;
                        items[num].y  = num16;
                        items[num].z  = z;
                        items3[num]   = color;
                        items2[num].x = uvs2[m];
                        items2[num].y = uvs2[m + 1];
                        if (num15 < v.x)
                        {
                            v.x = num15;
                        }
                        else if (num15 > v2.x)
                        {
                            v2.x = num15;
                        }
                        if (num16 < v.y)
                        {
                            v.y = num16;
                        }
                        else if (num16 > v2.y)
                        {
                            v2.y = num16;
                        }
                        num++;
                    }
                }
            }
            meshBoundsMin       = v;
            meshBoundsMax       = v2;
            meshBoundsThickness = (float)num2 * settings.zSpacing;
            if (!updateTriangles)
            {
                return;
            }
            int count2 = instruction.submeshInstructions.Count;

            if (submeshes.Count < count2)
            {
                submeshes.Resize(count2);
                int n = 0;
                for (int num17 = count2; n < num17; n++)
                {
                    ExposedList <int> exposedList = submeshes.Items[n];
                    if (exposedList == null)
                    {
                        submeshes.Items[n] = new ExposedList <int>();
                    }
                    else
                    {
                        exposedList.Clear(clearArray: false);
                    }
                }
            }
            SubmeshInstruction[] items7 = instruction.submeshInstructions.Items;
            int num18 = 0;

            for (int num19 = 0; num19 < count2; num19++)
            {
                SubmeshInstruction submeshInstruction2 = items7[num19];
                ExposedList <int>  exposedList2        = submeshes.Items[num19];
                int rawTriangleCount = submeshInstruction2.rawTriangleCount;
                if (rawTriangleCount > exposedList2.Items.Length)
                {
                    Array.Resize(ref exposedList2.Items, rawTriangleCount);
                }
                else if (rawTriangleCount < exposedList2.Items.Length)
                {
                    int[] items8 = exposedList2.Items;
                    int   num20  = rawTriangleCount;
                    for (int num21 = items8.Length; num20 < num21; num20++)
                    {
                        items8[num20] = 0;
                    }
                }
                exposedList2.Count = rawTriangleCount;
                int[]    items9    = exposedList2.Items;
                int      num22     = 0;
                Skeleton skeleton2 = submeshInstruction2.skeleton;
                Slot[]   items10   = skeleton2.drawOrder.Items;
                int      num23     = submeshInstruction2.startSlot;
                for (int endSlot2 = submeshInstruction2.endSlot; num23 < endSlot2; num23++)
                {
                    Attachment attachment3 = items10[num23].attachment;
                    if (attachment3 is RegionAttachment)
                    {
                        items9[num22]     = num18;
                        items9[num22 + 1] = num18 + 2;
                        items9[num22 + 2] = num18 + 1;
                        items9[num22 + 3] = num18 + 2;
                        items9[num22 + 4] = num18 + 3;
                        items9[num22 + 5] = num18 + 1;
                        num22            += 6;
                        num18            += 4;
                        continue;
                    }
                    MeshAttachment meshAttachment3 = attachment3 as MeshAttachment;
                    if (meshAttachment3 != null)
                    {
                        int[] triangles = meshAttachment3.triangles;
                        int   num24     = 0;
                        int   num25     = triangles.Length;
                        while (num24 < num25)
                        {
                            items9[num22] = num18 + triangles[num24];
                            num24++;
                            num22++;
                        }
                        num18 += meshAttachment3.worldVerticesLength >> 1;
                    }
                }
            }
        }
示例#18
0
    public virtual void LateUpdate()
    {
        if (!valid)
        {
            return;
        }

        // Exit early if there is nothing to render
        if (!meshRenderer.enabled && submeshRenderers.Length == 0)
        {
            return;
        }

        // Count vertices and submesh triangles.
        int                vertexCount = 0;
        int                submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
        Material           lastMaterial               = null;
        ExposedList <Slot> drawOrder                  = skeleton.drawOrder;
        int                drawOrderCount             = drawOrder.Count;
        int                submeshSeparatorSlotsCount = submeshSeparatorSlots.Count;
        bool               renderMeshes               = this.renderMeshes;

        // Clear last state of attachments and submeshes
        ExposedList <int> attachmentsTriangleCountTemp = lastState.attachmentsTriangleCountTemp;

        attachmentsTriangleCountTemp.GrowIfNeeded(drawOrderCount);
        attachmentsTriangleCountTemp.Count = drawOrderCount;
        ExposedList <bool> attachmentsFlipStateTemp = lastState.attachmentsFlipStateTemp;

        attachmentsFlipStateTemp.GrowIfNeeded(drawOrderCount);
        attachmentsFlipStateTemp.Count = drawOrderCount;

        ExposedList <LastState.AddSubmeshArguments> addSubmeshArgumentsTemp = lastState.addSubmeshArgumentsTemp;

        addSubmeshArgumentsTemp.Clear(false);
        bool noRender = false;

        for (int i = 0; i < drawOrderCount; i++)
        {
            Slot       slot       = drawOrder.Items[i];
            Bone       bone       = slot.bone;
            Attachment attachment = slot.attachment;

            object rendererObject;
            int    attachmentVertexCount, attachmentTriangleCount;
            bool   worldScaleXIsPositive = bone.worldScaleX >= 0f;
            bool   worldScaleYIsPositive = bone.worldScaleY >= 0f;
            bool   worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) ||
                                           (!worldScaleXIsPositive && !worldScaleYIsPositive);
            bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns);
            attachmentsFlipStateTemp.Items[i] = flip;

            attachmentsTriangleCountTemp.Items[i] = -1;
            RegionAttachment regionAttachment = attachment as RegionAttachment;
            if (regionAttachment != null)
            {
                rendererObject          = regionAttachment.RendererObject;
                attachmentVertexCount   = 4;
                attachmentTriangleCount = 6;
            }
            else
            {
                if (!renderMeshes)
                {
                    continue;
                }
                MeshAttachment meshAttachment = attachment as MeshAttachment;
                if (meshAttachment != null)
                {
                    rendererObject          = meshAttachment.RendererObject;
                    attachmentVertexCount   = meshAttachment.vertices.Length >> 1;
                    attachmentTriangleCount = meshAttachment.triangles.Length;
                }
                else
                {
                    SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
                    if (skinnedMeshAttachment != null)
                    {
                        rendererObject          = skinnedMeshAttachment.RendererObject;
                        attachmentVertexCount   = skinnedMeshAttachment.uvs.Length >> 1;
                        attachmentTriangleCount = skinnedMeshAttachment.triangles.Length;
                    }
                    else
                    {
                        continue;
                    }
                }
            }

            // Populate submesh when material changes.

            // tsteil - added support for mask material
            Material material = null;
            if (useMaskMaterial)
            {
                if (maskProvider != null)
                {
                    if (maskMaterial == null)
                    {
                        var prefabMat = (Material)((AtlasRegion)rendererObject).page.rendererObjectMask;
                        material           = new Material(prefabMat);
                        material.hideFlags = HideFlags.HideAndDontSave;
                        maskMaterial       = material;
                        SetMaskId();
                    }
                    else
                    {
                        material = maskMaterial;
                    }
                }
                else
                {
                    material = (Material)((AtlasRegion)rendererObject).page.rendererObjectMask;
                }
            }
            else
            {
#if !SPINE_TK2D
                material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
#else
                material = (rendererObject.GetType() == typeof(Material)) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject;
#endif
            }
            if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) ||
                (submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot)))
            {
                addSubmeshArgumentsTemp.Add(
                    new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false)
                    );
                submeshTriangleCount  = 0;
                submeshFirstVertex    = vertexCount;
                submeshStartSlotIndex = i;
            }
            lastMaterial = material;

            submeshTriangleCount += attachmentTriangleCount;
            vertexCount          += attachmentVertexCount;

            attachmentsTriangleCountTemp.Items[i] = attachmentTriangleCount;
        }

        // tsteil - we need to keep track if we're rendering or not
        if (lastMaterial == null)
        {
            noRender = true;
        }

        addSubmeshArgumentsTemp.Add(
            new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true)
            );

        bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(attachmentsTriangleCountTemp, attachmentsFlipStateTemp, addSubmeshArgumentsTemp);
        var  submeshMatCount         = 0;
        if (mustUpdateMeshStructure)
        {
            submeshMaterials.Clear();
            for (int i = 0, n = addSubmeshArgumentsTemp.Count; i < n; i++)
            {
                LastState.AddSubmeshArguments arguments = addSubmeshArgumentsTemp.Items[i];
                AddSubmesh(
                    arguments.material,
                    arguments.startSlot,
                    arguments.endSlot,
                    arguments.triangleCount,
                    arguments.firstVertex,
                    arguments.lastSubmesh,
                    attachmentsFlipStateTemp
                    );
            }

            // Set materials.
            submeshMatCount = submeshMaterials.Count;
            if (submeshMatCount == sharedMaterials.Length)
            {
                submeshMaterials.CopyTo(sharedMaterials);
            }
            else
            {
                sharedMaterials = submeshMaterials.ToArray();
            }
            meshRenderer.sharedMaterials = sharedMaterials;
        }

        // Ensure mesh data is the right size.
        Vector3[] vertices     = this.vertices;
        bool      newTriangles = vertexCount > vertices.Length;
        if (newTriangles)
        {
            // Not enough vertices, increase size.
            this.vertices = vertices = new Vector3[vertexCount];
            this.colors   = new Color32[vertexCount];
            this.uvs      = new Vector2[vertexCount];
            if (setupUv2)
            {
                this.uvs2 = new Vector2[vertexCount];
            }
            mesh1.Clear();
            mesh2.Clear();
        }
        else
        {
            // Too many vertices, zero the extra.
            Vector3 zero = Vector3.zero;
            for (int i = vertexCount, n = lastState.vertexCount; i < n; i++)
            {
                vertices[i] = zero;
            }
        }
        lastState.vertexCount = vertexCount;

        // Setup mesh.
        float     zSpacing     = this.zSpacing;
        float[]   tempVertices = this.tempVertices;
        Vector2[] uvs          = this.uvs;
        Vector2[] uvs2         = this.uvs2;
        Color32[] colors       = this.colors;
        int       vertexIndex  = 0;
        Color32   color;
        float     a = skeleton.a * 255, r = skeleton.r, g = skeleton.g, b = skeleton.b;

        Vector3 meshBoundsMin;
        meshBoundsMin.x = float.MaxValue;
        meshBoundsMin.y = float.MaxValue;
        meshBoundsMin.z = zSpacing > 0f ? 0f : zSpacing * (drawOrderCount - 1);
        Vector3 meshBoundsMax;
        meshBoundsMax.x = float.MinValue;
        meshBoundsMax.y = float.MinValue;
        meshBoundsMax.z = zSpacing < 0f ? 0f : zSpacing * (drawOrderCount - 1);
        for (int i = 0; i < drawOrderCount; i++)
        {
            Slot             slot             = drawOrder.Items[i];
            Attachment       attachment       = slot.attachment;
            RegionAttachment regionAttachment = attachment as RegionAttachment;
            if (regionAttachment != null)
            {
                regionAttachment.ComputeWorldVertices(slot.bone, tempVertices);

                float z = i * zSpacing;
                vertices[vertexIndex].x     = tempVertices[RegionAttachment.X1];
                vertices[vertexIndex].y     = tempVertices[RegionAttachment.Y1];
                vertices[vertexIndex].z     = z;
                vertices[vertexIndex + 1].x = tempVertices[RegionAttachment.X4];
                vertices[vertexIndex + 1].y = tempVertices[RegionAttachment.Y4];
                vertices[vertexIndex + 1].z = z;
                vertices[vertexIndex + 2].x = tempVertices[RegionAttachment.X2];
                vertices[vertexIndex + 2].y = tempVertices[RegionAttachment.Y2];
                vertices[vertexIndex + 2].z = z;
                vertices[vertexIndex + 3].x = tempVertices[RegionAttachment.X3];
                vertices[vertexIndex + 3].y = tempVertices[RegionAttachment.Y3];
                vertices[vertexIndex + 3].z = z;

                // Eugene - added
                if (overrideVertexColor)
                {
                    color = vertexColor;

                    colors[vertexIndex]     = color;
                    colors[vertexIndex + 1] = color;
                    colors[vertexIndex + 2] = color;
                    colors[vertexIndex + 3] = color;
                }
                else
                {
                    color.a = (byte)(a * slot.a * regionAttachment.a);
                    color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
                    color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
                    color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
                    if (slot.data.blendMode == BlendMode.additive)
                    {
                        color.a = 0;
                    }
                    colors[vertexIndex]     = color;
                    colors[vertexIndex + 1] = color;
                    colors[vertexIndex + 2] = color;
                    colors[vertexIndex + 3] = color;
                }

                float[] regionUVs = regionAttachment.uvs;
                uvs[vertexIndex].x     = regionUVs[RegionAttachment.X1];
                uvs[vertexIndex].y     = regionUVs[RegionAttachment.Y1];
                uvs[vertexIndex + 1].x = regionUVs[RegionAttachment.X4];
                uvs[vertexIndex + 1].y = regionUVs[RegionAttachment.Y4];
                uvs[vertexIndex + 2].x = regionUVs[RegionAttachment.X2];
                uvs[vertexIndex + 2].y = regionUVs[RegionAttachment.Y2];
                uvs[vertexIndex + 3].x = regionUVs[RegionAttachment.X3];
                uvs[vertexIndex + 3].y = regionUVs[RegionAttachment.Y3];

                // Calculate min/max X
                if (tempVertices[RegionAttachment.X1] < meshBoundsMin.x)
                {
                    meshBoundsMin.x = tempVertices[RegionAttachment.X1];
                }
                else if (tempVertices[RegionAttachment.X1] > meshBoundsMax.x)
                {
                    meshBoundsMax.x = tempVertices[RegionAttachment.X1];
                }
                if (tempVertices[RegionAttachment.X2] < meshBoundsMin.x)
                {
                    meshBoundsMin.x = tempVertices[RegionAttachment.X2];
                }
                else if (tempVertices[RegionAttachment.X2] > meshBoundsMax.x)
                {
                    meshBoundsMax.x = tempVertices[RegionAttachment.X2];
                }
                if (tempVertices[RegionAttachment.X3] < meshBoundsMin.x)
                {
                    meshBoundsMin.x = tempVertices[RegionAttachment.X3];
                }
                else if (tempVertices[RegionAttachment.X3] > meshBoundsMax.x)
                {
                    meshBoundsMax.x = tempVertices[RegionAttachment.X3];
                }
                if (tempVertices[RegionAttachment.X4] < meshBoundsMin.x)
                {
                    meshBoundsMin.x = tempVertices[RegionAttachment.X4];
                }
                else if (tempVertices[RegionAttachment.X4] > meshBoundsMax.x)
                {
                    meshBoundsMax.x = tempVertices[RegionAttachment.X4];
                }

                // Calculate min/max Y
                if (tempVertices[RegionAttachment.Y1] < meshBoundsMin.y)
                {
                    meshBoundsMin.y = tempVertices[RegionAttachment.Y1];
                }
                else if (tempVertices[RegionAttachment.Y1] > meshBoundsMax.y)
                {
                    meshBoundsMax.y = tempVertices[RegionAttachment.Y1];
                }
                if (tempVertices[RegionAttachment.Y2] < meshBoundsMin.y)
                {
                    meshBoundsMin.y = tempVertices[RegionAttachment.Y2];
                }
                else if (tempVertices[RegionAttachment.Y2] > meshBoundsMax.y)
                {
                    meshBoundsMax.y = tempVertices[RegionAttachment.Y2];
                }
                if (tempVertices[RegionAttachment.Y3] < meshBoundsMin.y)
                {
                    meshBoundsMin.y = tempVertices[RegionAttachment.Y3];
                }
                else if (tempVertices[RegionAttachment.Y3] > meshBoundsMax.y)
                {
                    meshBoundsMax.y = tempVertices[RegionAttachment.Y3];
                }
                if (tempVertices[RegionAttachment.Y4] < meshBoundsMin.y)
                {
                    meshBoundsMin.y = tempVertices[RegionAttachment.Y4];
                }
                else if (tempVertices[RegionAttachment.Y4] > meshBoundsMax.y)
                {
                    meshBoundsMax.y = tempVertices[RegionAttachment.Y4];
                }

                vertexIndex += 4;
            }
            else
            {
                if (!renderMeshes)
                {
                    continue;
                }
                MeshAttachment meshAttachment = attachment as MeshAttachment;
                if (meshAttachment != null)
                {
                    int meshVertexCount = meshAttachment.vertices.Length;
                    if (tempVertices.Length < meshVertexCount)
                    {
                        this.tempVertices = tempVertices = new float[meshVertexCount];
                    }
                    meshAttachment.ComputeWorldVertices(slot, tempVertices);

                    // Eugene - added
                    if (overrideVertexColor)
                    {
                        color = vertexColor;
                    }
                    else
                    {
                        color.a = (byte)(a * slot.a * meshAttachment.a);
                        color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
                        color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
                        color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
                        if (slot.data.blendMode == BlendMode.additive)
                        {
                            color.a = 0;
                        }
                    }

                    float[] meshUVs = meshAttachment.uvs;

                    float z = i * zSpacing;
                    for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                    {
                        vertices[vertexIndex].x = tempVertices[ii];
                        vertices[vertexIndex].y = tempVertices[ii + 1];
                        vertices[vertexIndex].z = z;
                        colors[vertexIndex]     = color;
                        uvs[vertexIndex].x      = meshUVs[ii];
                        uvs[vertexIndex].y      = meshUVs[ii + 1];

                        if (tempVertices[ii] < meshBoundsMin.x)
                        {
                            meshBoundsMin.x = tempVertices[ii];
                        }
                        else if (tempVertices[ii] > meshBoundsMax.x)
                        {
                            meshBoundsMax.x = tempVertices[ii];
                        }
                        if (tempVertices[ii + 1] < meshBoundsMin.y)
                        {
                            meshBoundsMin.y = tempVertices[ii + 1];
                        }
                        else if (tempVertices[ii + 1] > meshBoundsMax.y)
                        {
                            meshBoundsMax.y = tempVertices[ii + 1];
                        }
                    }
                }
                else
                {
                    SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
                    if (skinnedMeshAttachment != null)
                    {
                        int meshVertexCount = skinnedMeshAttachment.uvs.Length;
                        if (tempVertices.Length < meshVertexCount)
                        {
                            this.tempVertices = tempVertices = new float[meshVertexCount];
                        }
                        skinnedMeshAttachment.ComputeWorldVertices(slot, tempVertices);

                        // Eugene - added
                        if (overrideVertexColor)
                        {
                            color = vertexColor;
                        }
                        else
                        {
                            color.a = (byte)(a * slot.a * skinnedMeshAttachment.a);
                            color.r = (byte)(r * slot.r * skinnedMeshAttachment.r * color.a);
                            color.g = (byte)(g * slot.g * skinnedMeshAttachment.g * color.a);
                            color.b = (byte)(b * slot.b * skinnedMeshAttachment.b * color.a);
                            if (slot.data.blendMode == BlendMode.additive)
                            {
                                color.a = 0;
                            }
                        }

                        float[] meshUVs = skinnedMeshAttachment.uvs;
                        float   z       = i * zSpacing;
                        for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                        {
                            vertices[vertexIndex].x = tempVertices[ii];
                            vertices[vertexIndex].y = tempVertices[ii + 1];
                            vertices[vertexIndex].z = z;
                            colors[vertexIndex]     = color;
                            uvs[vertexIndex].x      = meshUVs[ii];
                            uvs[vertexIndex].y      = meshUVs[ii + 1];

                            if (tempVertices[ii] < meshBoundsMin.x)
                            {
                                meshBoundsMin.x = tempVertices[ii];
                            }
                            else if (tempVertices[ii] > meshBoundsMax.x)
                            {
                                meshBoundsMax.x = tempVertices[ii];
                            }
                            if (tempVertices[ii + 1] < meshBoundsMin.y)
                            {
                                meshBoundsMin.y = tempVertices[ii + 1];
                            }
                            else if (tempVertices[ii + 1] > meshBoundsMax.y)
                            {
                                meshBoundsMax.y = tempVertices[ii + 1];
                            }
                        }
                    }
                }
            }
        }

        // Double buffer mesh.
        Mesh mesh = useMesh1 ? mesh1 : mesh2;
        meshFilter.sharedMesh = mesh;

        mesh.vertices = vertices;
        mesh.colors32 = colors;
        mesh.uv       = uvs;

        // tsteil - added UV2 stuff
        if (setupUv2)
        {
            float minX  = 1f;
            float minY  = 1f;
            float maxX  = 0f;
            float maxY  = 0f;
            float sizeX = 0f;
            float sizeY = 0f;

            // go through our vertices and find the min and max so we can normalize the UVs against it
            for (int i = 0; i < vertexCount; ++i)
            {
                var x = vertices[i].x;
                var y = vertices[i].y;
                if (x < minX)
                {
                    minX = x;
                }
                else if (x > maxX)
                {
                    maxX = x;
                }
                if (y < minY)
                {
                    minY = y;
                }
                else if (y > maxY)
                {
                    maxY = y;
                }
            }
            sizeX = maxX - minX;
            sizeY = maxY - minY;

            // now set the uvs2
            for (int i = 0; i < vertexCount; ++i)
            {
                uvs2[i].x = (vertices[i].x - minX) / sizeX;
                uvs2[i].y = (vertices[i].y - minY) / sizeY;
            }
            mesh.uv2 = uvs2;
        }

        if (mustUpdateMeshStructure)
        {
            int submeshCount = submeshMatCount;
            mesh.subMeshCount = submeshCount;
            for (int i = 0; i < submeshCount; ++i)
            {
                mesh.SetTriangles(submeshes.Items[i].triangles, i);
            }
        }

        // tsteil: if we're not rendering, we dont need to calculate the bounds (this fixes the crazy AABB math errors)
        if (noRender == false)
        {
            Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;
            Vector3 meshBoundsCenter  = meshBoundsMin + meshBoundsExtents * 0.5f;
            mesh.bounds = new Bounds(meshBoundsCenter, meshBoundsExtents);
        }

        if (newTriangles && calculateNormals)
        {
            Vector3[] normals = new Vector3[vertexCount];
            Vector3   normal  = new Vector3(0, 0, -1);
            for (int i = 0; i < vertexCount; i++)
            {
                normals[i] = normal;
            }
            (useMesh1 ? mesh2 : mesh1).vertices = vertices;             // Set other mesh vertices.
            mesh1.normals = normals;
            mesh2.normals = normals;

            if (calculateTangents)
            {
                Vector4[] tangents = new Vector4[vertexCount];
                Vector3   tangent  = new Vector3(0, 0, 1);
                for (int i = 0; i < vertexCount; i++)
                {
                    tangents[i] = tangent;
                }
                mesh1.tangents = tangents;
                mesh2.tangents = tangents;
            }
        }

        // Update previous state
        ExposedList <int>  attachmentsTriangleCountCurrentMesh;
        ExposedList <bool> attachmentsFlipStateCurrentMesh;
        ExposedList <LastState.AddSubmeshArguments> addSubmeshArgumentsCurrentMesh;
        if (useMesh1)
        {
            attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh1;
            addSubmeshArgumentsCurrentMesh      = lastState.addSubmeshArgumentsMesh1;
            attachmentsFlipStateCurrentMesh     = lastState.attachmentsFlipStateMesh1;
            lastState.immutableTrianglesMesh1   = immutableTriangles;
        }
        else
        {
            attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh2;
            addSubmeshArgumentsCurrentMesh      = lastState.addSubmeshArgumentsMesh2;
            attachmentsFlipStateCurrentMesh     = lastState.attachmentsFlipStateMesh2;
            lastState.immutableTrianglesMesh2   = immutableTriangles;
        }

        attachmentsTriangleCountCurrentMesh.GrowIfNeeded(attachmentsTriangleCountTemp.Capacity);
        attachmentsTriangleCountCurrentMesh.Count = attachmentsTriangleCountTemp.Count;
        attachmentsTriangleCountTemp.CopyTo(attachmentsTriangleCountCurrentMesh.Items, 0);

        attachmentsFlipStateCurrentMesh.GrowIfNeeded(attachmentsFlipStateTemp.Capacity);
        attachmentsFlipStateCurrentMesh.Count = attachmentsFlipStateTemp.Count;
        attachmentsFlipStateTemp.CopyTo(attachmentsFlipStateCurrentMesh.Items, 0);

        addSubmeshArgumentsCurrentMesh.GrowIfNeeded(addSubmeshArgumentsTemp.Count);
        addSubmeshArgumentsCurrentMesh.Count = addSubmeshArgumentsTemp.Count;
        addSubmeshArgumentsTemp.CopyTo(addSubmeshArgumentsCurrentMesh.Items);

        if (submeshRenderers.Length > 0)
        {
            for (int i = 0; i < submeshRenderers.Length; i++)
            {
                SkeletonUtilitySubmeshRenderer submeshRenderer = submeshRenderers[i];
                if (submeshRenderer.submeshIndex < sharedMaterials.Length)
                {
                    submeshRenderer.SetMesh(meshRenderer, useMesh1 ? mesh1 : mesh2, sharedMaterials[submeshRenderer.submeshIndex]);
                }
                else
                {
                    submeshRenderer.GetComponent <Renderer>().enabled = false;
                }
            }
        }

        useMesh1 = !useMesh1;
    }
示例#19
0
        protected override void Draw()
        {
            defaultBlendState = PremultipliedAlpha ? BlendState.AlphaBlend : BlendState.NonPremultiplied;


            float[]     vertices = this.vertices;
            List <Slot> drawOrder = Skeleton.DrawOrder;
            float       x = Skeleton.X, y = Skeleton.Y;

            CCColor3B color3b   = Color;
            float     skeletonR = color3b.R / 255f;
            float     skeletonG = color3b.G / 255f;
            float     skeletonB = color3b.B / 255f;
            float     skeletonA = Opacity / 255f;

            batcher.BlendState = defaultBlendState;

            batcher.Begin();

            for (int i = 0, n = drawOrder.Count; i < n; i++)
            {
                Slot       slot       = drawOrder[i];
                Attachment attachment = slot.Attachment;
                if (attachment is RegionAttachment)
                {
                    RegionAttachment regionAttachment = (RegionAttachment)attachment;
                    BlendState       blend            = slot.Data.AdditiveBlending ? BlendState.Additive : defaultBlendState;
                    //batcher.BlendState = blend;

                    if (CCDrawManager.GraphicsDevice.BlendState != blend)
                    {
                        batcher.End();
                        batcher.BlendState = blend;
                        batcher.Begin();
                    }

                    MeshItem item = batcher.NextItem(4, 6);
                    item.triangles = quadTriangles;
                    VertexPositionColorTexture[] itemVertices = item.vertices;

                    AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject;
                    item.texture = (Texture2D)region.page.rendererObject;

                    Color color;
                    float a = skeletonA * slot.A * regionAttachment.A;
                    if (PremultipliedAlpha)
                    {
                        color = new Color(
                            skeletonR * slot.R * regionAttachment.R * a,
                            skeletonG * slot.G * regionAttachment.G * a,
                            skeletonB * slot.B * regionAttachment.B * a, a);
                    }
                    else
                    {
                        color = new Color(
                            skeletonR * slot.R * regionAttachment.R,
                            skeletonG * slot.G * regionAttachment.G,
                            skeletonB * slot.B * regionAttachment.B, a);
                    }
                    itemVertices[TL].Color = color;
                    itemVertices[BL].Color = color;
                    itemVertices[BR].Color = color;
                    itemVertices[TR].Color = color;

                    regionAttachment.ComputeWorldVertices(x, y, slot.Bone, vertices);
                    itemVertices[TL].Position.X = vertices[RegionAttachment.X1];
                    itemVertices[TL].Position.Y = vertices[RegionAttachment.Y1];
                    itemVertices[TL].Position.Z = 0;
                    itemVertices[BL].Position.X = vertices[RegionAttachment.X2];
                    itemVertices[BL].Position.Y = vertices[RegionAttachment.Y2];
                    itemVertices[BL].Position.Z = 0;
                    itemVertices[BR].Position.X = vertices[RegionAttachment.X3];
                    itemVertices[BR].Position.Y = vertices[RegionAttachment.Y3];
                    itemVertices[BR].Position.Z = 0;
                    itemVertices[TR].Position.X = vertices[RegionAttachment.X4];
                    itemVertices[TR].Position.Y = vertices[RegionAttachment.Y4];
                    itemVertices[TR].Position.Z = 0;

                    float[] uvs = regionAttachment.UVs;
                    itemVertices[TL].TextureCoordinate.X = uvs[RegionAttachment.X1];
                    itemVertices[TL].TextureCoordinate.Y = uvs[RegionAttachment.Y1];
                    itemVertices[BL].TextureCoordinate.X = uvs[RegionAttachment.X2];
                    itemVertices[BL].TextureCoordinate.Y = uvs[RegionAttachment.Y2];
                    itemVertices[BR].TextureCoordinate.X = uvs[RegionAttachment.X3];
                    itemVertices[BR].TextureCoordinate.Y = uvs[RegionAttachment.Y3];
                    itemVertices[TR].TextureCoordinate.X = uvs[RegionAttachment.X4];
                    itemVertices[TR].TextureCoordinate.Y = uvs[RegionAttachment.Y4];
                }
                else if (attachment is MeshAttachment)
                {
                    MeshAttachment mesh        = (MeshAttachment)attachment;
                    int            vertexCount = mesh.Vertices.Length;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    mesh.ComputeWorldVertices(x, y, slot, vertices);

                    int[]    triangles = mesh.Triangles;
                    MeshItem item      = batcher.NextItem(vertexCount, triangles.Length);
                    item.triangles = triangles;

                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    item.texture = (Texture2D)region.page.rendererObject;

                    Color color;
                    float a = skeletonA * slot.A * mesh.A;
                    if (PremultipliedAlpha)
                    {
                        color = new Color(
                            skeletonR * slot.R * mesh.R * a,
                            skeletonG * slot.G * mesh.G * a,
                            skeletonB * slot.B * mesh.B * a, a);
                    }
                    else
                    {
                        color = new Color(
                            skeletonR * slot.R * mesh.R,
                            skeletonG * slot.G * mesh.G,
                            skeletonB * slot.B * mesh.B, a);
                    }

                    float[] uvs = mesh.UVs;
                    VertexPositionColorTexture[] itemVertices = item.vertices;
                    for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2)
                    {
                        itemVertices[ii].Color               = color;
                        itemVertices[ii].Position.X          = vertices[v];
                        itemVertices[ii].Position.Y          = vertices[v + 1];
                        itemVertices[ii].Position.Z          = 0;
                        itemVertices[ii].TextureCoordinate.X = uvs[v];
                        itemVertices[ii].TextureCoordinate.Y = uvs[v + 1];
                    }
                }
                else if (attachment is SkinnedMeshAttachment)
                {
                    SkinnedMeshAttachment mesh = (SkinnedMeshAttachment)attachment;
                    int vertexCount            = mesh.UVs.Length;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    mesh.ComputeWorldVertices(x, y, slot, vertices);

                    int[]    triangles = mesh.Triangles;
                    MeshItem item      = batcher.NextItem(vertexCount, triangles.Length);
                    item.triangles = triangles;

                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    item.texture = (Texture2D)region.page.rendererObject;

                    Color color;
                    float a = skeletonA * slot.A * mesh.A;
                    if (PremultipliedAlpha)
                    {
                        color = new Color(
                            skeletonR * slot.R * mesh.R * a,
                            skeletonG * slot.G * mesh.G * a,
                            skeletonB * slot.B * mesh.B * a, a);
                    }
                    else
                    {
                        color = new Color(
                            skeletonR * slot.R * mesh.R,
                            skeletonG * slot.G * mesh.G,
                            skeletonB * slot.B * mesh.B, a);
                    }

                    float[] uvs = mesh.UVs;
                    VertexPositionColorTexture[] itemVertices = item.vertices;
                    for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2)
                    {
                        itemVertices[ii].Color               = color;
                        itemVertices[ii].Position.X          = vertices[v];
                        itemVertices[ii].Position.Y          = vertices[v + 1];
                        itemVertices[ii].Position.Z          = 0;
                        itemVertices[ii].TextureCoordinate.X = uvs[v];
                        itemVertices[ii].TextureCoordinate.Y = uvs[v + 1];
                    }
                }
            }

            batcher.End();

            if (DebugBones || DebugSlots)
            {
                if (DebugSlots)
                {
                    for (int i = 0; i < Skeleton.Slots.Count; ++i)
                    {
                        var slot = Skeleton.Slots[i];

                        if (slot.Attachment == null)
                        {
                            continue;
                        }

                        var verticesCount = 0;
                        var worldVertices = new float[1000]; // Max number of vertices per mesh.
                        if (slot.Attachment is RegionAttachment)
                        {
                            var attachment = (RegionAttachment)slot.Attachment;
                            attachment.ComputeWorldVertices(Skeleton.X, Skeleton.Y, slot.bone, worldVertices);
                            verticesCount = 8;
                        }
                        else if (slot.Attachment is MeshAttachment)
                        {
                            var mesh = (MeshAttachment)slot.Attachment;
                            mesh.ComputeWorldVertices(Skeleton.X, Skeleton.Y, slot, worldVertices);
                            verticesCount = mesh.Vertices.Length;
                        }
                        else if (slot.Attachment is SkinnedMeshAttachment)
                        {
                            var mesh = (SkinnedMeshAttachment)slot.Attachment;
                            mesh.ComputeWorldVertices(Skeleton.X, Skeleton.Y, slot, worldVertices);
                            verticesCount = mesh.UVs.Length;
                        }
                        else
                        {
                            continue;
                        }

                        CCPoint[] slotVertices = new CCPoint[verticesCount / 2];

                        for (int ii = 0, si = 0; ii < verticesCount; ii += 2, si++)
                        {
                            slotVertices[si].X = worldVertices[ii] * ScaleX;
                            slotVertices[si].Y = worldVertices[ii + 1] * ScaleY;
                        }

                        CCDrawingPrimitives.Begin();
                        CCDrawingPrimitives.DrawPoly(slotVertices, verticesCount / 2, true, DebugSlotColor);
                        CCDrawingPrimitives.End();
                    }
                }

                if (DebugBones)
                {
                    // Bone lengths.
                    for (int i = 0; i < Skeleton.Bones.Count; i++)
                    {
                        Bone bone = Skeleton.Bones[i];
                        x = bone.Data.Length * bone.M00 + bone.WorldX;
                        y = bone.Data.Length * bone.M10 + bone.WorldY;

                        CCDrawingPrimitives.Begin();
                        CCDrawingPrimitives.DrawLine(new CCPoint(bone.WorldX, bone.WorldY), new CCPoint(x, y), DebugJointColor);
                        CCDrawingPrimitives.End();
                    }

                    // Bone origins.
                    for (int i = 0; i < Skeleton.Bones.Count; i++)
                    {
                        Bone bone = Skeleton.Bones[i];
                        CCDrawingPrimitives.Begin();
                        CCDrawingPrimitives.DrawPoint(new CCPoint(bone.WorldX, bone.WorldY), 4, DebugBoneColor);
                        CCDrawingPrimitives.End();
                    }
                }
            }
        }
示例#20
0
        public void Draw(OpenGL gl, Skeleton skeleton)
        {
            if (skeleton == null)
            {
                return;
            }

            var   drawOrder = skeleton.DrawOrder;
            var   drawOrderItems = skeleton.DrawOrder.Items;
            float skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B, skeletonA = skeleton.A;

            for (int i = 0, n = drawOrder.Count; i < n; i++)
            {
                float[]    vertices   = this.vertices;
                Slot       slot       = drawOrderItems[i];
                Attachment attachment = slot.Attachment;
                if (attachment is RegionAttachment)
                {
                    RegionAttachment regionAttachment = (RegionAttachment)attachment;

                    MeshItem item = batcher.NextItem(4, 6);
                    item.triangles = quadTriangles;
                    VertexPositionColorTexture[] itemVertices = item.vertices;

                    AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject;
                    item.texture = (uint)region.page.rendererObject;

                    Color color;
                    float a = skeletonA * slot.A * regionAttachment.A;
                    if (premultipliedAlpha)
                    {
                        color = new Color(
                            skeletonR * slot.R * regionAttachment.R * a,
                            skeletonG * slot.G * regionAttachment.G * a,
                            skeletonB * slot.B * regionAttachment.B * a, a);
                    }
                    else
                    {
                        color = new Color(
                            skeletonR * slot.R * regionAttachment.R,
                            skeletonG * slot.G * regionAttachment.G,
                            skeletonB * slot.B * regionAttachment.B, a);
                    }
                    itemVertices[TL].color = color;
                    itemVertices[BL].color = color;
                    itemVertices[BR].color = color;
                    itemVertices[TR].color = color;

                    regionAttachment.ComputeWorldVertices(slot.Bone, vertices);
                    itemVertices[TL].position = new Vector2(vertices[RegionAttachment.X1], vertices[RegionAttachment.Y1]);
                    itemVertices[BL].position = new Vector2(vertices[RegionAttachment.X2], vertices[RegionAttachment.Y2]);
                    itemVertices[BR].position = new Vector2(vertices[RegionAttachment.X3], vertices[RegionAttachment.Y3]);
                    itemVertices[TR].position = new Vector2(vertices[RegionAttachment.X4], vertices[RegionAttachment.Y4]);

                    float[] uvs = regionAttachment.UVs;
                    itemVertices[TL].textureCoordinate = new Vector2(uvs[RegionAttachment.X1], uvs[RegionAttachment.Y1]);
                    itemVertices[BL].textureCoordinate = new Vector2(uvs[RegionAttachment.X2], uvs[RegionAttachment.Y2]);
                    itemVertices[BR].textureCoordinate = new Vector2(uvs[RegionAttachment.X3], uvs[RegionAttachment.Y3]);
                    itemVertices[TR].textureCoordinate = new Vector2(uvs[RegionAttachment.X4], uvs[RegionAttachment.Y4]);
                }
                else if (attachment is MeshAttachment)
                {
                    MeshAttachment mesh        = (MeshAttachment)attachment;
                    int            vertexCount = mesh.WorldVerticesLength;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    mesh.ComputeWorldVertices(slot, vertices);

                    int[]    triangles = mesh.Triangles;
                    MeshItem item      = batcher.NextItem(vertexCount, triangles.Length);
                    item.triangles = triangles;

                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;
                    item.texture = (uint)region.page.rendererObject;

                    Color color;
                    float a = skeletonA * slot.A * mesh.A;
                    if (premultipliedAlpha)
                    {
                        color = new Color(
                            skeletonR * slot.R * mesh.R * a,
                            skeletonG * slot.G * mesh.G * a,
                            skeletonB * slot.B * mesh.B * a, a);
                    }
                    else
                    {
                        color = new Color(
                            skeletonR * slot.R * mesh.R,
                            skeletonG * slot.G * mesh.G,
                            skeletonB * slot.B * mesh.B, a);
                    }

                    float[] uvs = mesh.UVs;
                    VertexPositionColorTexture[] itemVertices = item.vertices;
                    for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2)
                    {
                        itemVertices[ii].color             = color;
                        itemVertices[ii].position          = new Vector2(vertices[v], vertices[v + 1]);
                        itemVertices[ii].textureCoordinate = new Vector2(uvs[v], uvs[v + 1]);
                    }
                }
            }

            batcher.Draw(gl);
        }
示例#21
0
        /// <summary>
        /// Helper method that draws debug lines.
        /// </summary>
        /// <remarks>
        /// This method will only work on debug mode and if RenderManager.DebugLines /&gt;
        /// is set to <c>true</c>.
        /// </remarks>
        protected override void DrawDebugLines()
        {
            base.DrawDebugLines();

            var platform = WaveServices.Platform;

            Vector2 start = new Vector2();
            Vector2 end   = new Vector2();
            Color   color = Color.Red;

            // Draw bones
            if ((this.ActualDebugMode & DebugMode.Bones) == DebugMode.Bones)
            {
                foreach (var bone in this.SkeletalAnimation.Skeleton.Bones)
                {
                    if (bone.Parent != null)
                    {
                        start.X = bone.WorldX;
                        start.Y = -bone.WorldY;
                        end.X   = (bone.Data.Length * bone.M00) + bone.WorldX;
                        end.Y   = -((bone.Data.Length * bone.M10) + bone.WorldY);

                        Vector2.Transform(ref start, ref this.localWorld, out start);
                        Vector2.Transform(ref end, ref this.localWorld, out end);

                        RenderManager.LineBatch2D.DrawLine(ref start, ref end, ref color);
                    }
                }
            }

            // Draw quads
            if ((this.ActualDebugMode & DebugMode.Quads) == DebugMode.Quads)
            {
                color = Color.Yellow;
                for (int i = 0; i < this.drawOrder.Count; i++)
                {
                    Slot       slot       = this.drawOrder[i];
                    Attachment attachment = slot.Attachment;

                    if (attachment is RegionAttachment)
                    {
                        float[] spineVertices = new float[8];

                        RegionAttachment mesh = (RegionAttachment)attachment;
                        mesh.ComputeWorldVertices(0, 0, slot.Bone, spineVertices);

                        // Edge1
                        start.X = spineVertices[RegionAttachment.X1];
                        start.Y = -spineVertices[RegionAttachment.Y1];
                        end.X   = spineVertices[RegionAttachment.X2];
                        end.Y   = -spineVertices[RegionAttachment.Y2];

                        Vector2.Transform(ref start, ref this.localWorld, out start);
                        Vector2.Transform(ref end, ref this.localWorld, out end);

                        RenderManager.LineBatch2D.DrawLine(ref start, ref end, ref color);

                        // Edge2
                        start.X = spineVertices[RegionAttachment.X2];
                        start.Y = -spineVertices[RegionAttachment.Y2];
                        end.X   = spineVertices[RegionAttachment.X3];
                        end.Y   = -spineVertices[RegionAttachment.Y3];

                        Vector2.Transform(ref start, ref this.localWorld, out start);
                        Vector2.Transform(ref end, ref this.localWorld, out end);

                        RenderManager.LineBatch2D.DrawLine(ref start, ref end, ref color);

                        // Edge3
                        start.X = spineVertices[RegionAttachment.X3];
                        start.Y = -spineVertices[RegionAttachment.Y3];
                        end.X   = spineVertices[RegionAttachment.X4];
                        end.Y   = -spineVertices[RegionAttachment.Y4];

                        Vector2.Transform(ref start, ref this.localWorld, out start);
                        Vector2.Transform(ref end, ref this.localWorld, out end);

                        RenderManager.LineBatch2D.DrawLine(ref start, ref end, ref color);

                        // Edge4
                        start.X = spineVertices[RegionAttachment.X4];
                        start.Y = -spineVertices[RegionAttachment.Y4];
                        end.X   = spineVertices[RegionAttachment.X1];
                        end.Y   = -spineVertices[RegionAttachment.Y1];

                        Vector2.Transform(ref start, ref this.localWorld, out start);
                        Vector2.Transform(ref end, ref this.localWorld, out end);

                        RenderManager.LineBatch2D.DrawLine(ref start, ref end, ref color);
                    }
                    else if (attachment is MeshAttachment)
                    {
                        MeshAttachment mesh          = (MeshAttachment)attachment;
                        int            vertexCount   = mesh.Vertices.Length;
                        float[]        spineVertices = new float[vertexCount];
                        mesh.ComputeWorldVertices(0, 0, slot, spineVertices);

                        for (int j = 0; j < vertexCount; j += 2)
                        {
                            start.X = spineVertices[j];
                            start.Y = -spineVertices[j + 1];

                            if (j < vertexCount - 2)
                            {
                                end.X = spineVertices[j + 2];
                                end.Y = -spineVertices[j + 3];
                            }
                            else
                            {
                                end.X = spineVertices[0];
                                end.Y = -spineVertices[1];
                            }

                            Vector2.Transform(ref start, ref this.localWorld, out start);
                            Vector2.Transform(ref end, ref this.localWorld, out end);

                            RenderManager.LineBatch2D.DrawLine(ref start, ref end, ref color);
                        }
                    }
                    else if (attachment is SkinnedMeshAttachment)
                    {
                        SkinnedMeshAttachment mesh = (SkinnedMeshAttachment)attachment;
                        int     vertexCount        = mesh.UVs.Length;
                        float[] spineVertices      = new float[vertexCount];
                        mesh.ComputeWorldVertices(0, 0, slot, spineVertices);

                        for (int j = 0; j < vertexCount; j += 2)
                        {
                            start.X = spineVertices[j];
                            start.Y = -spineVertices[j + 1];

                            if (j < vertexCount - 2)
                            {
                                end.X = spineVertices[j + 2];
                                end.Y = -spineVertices[j + 3];
                            }
                            else
                            {
                                end.X = spineVertices[0];
                                end.Y = -spineVertices[1];
                            }

                            Vector2.Transform(ref start, ref this.localWorld, out start);
                            Vector2.Transform(ref end, ref this.localWorld, out end);

                            RenderManager.LineBatch2D.DrawLine(ref start, ref end, ref color);
                        }
                    }
                }
            }
        }
    public virtual void LateUpdate()
    {
        if (!valid)
        {
            return;
        }

        // Exit early if there is nothing to render
        if (!meshRenderer.enabled && submeshRenderers.Length == 0)
        {
            return;
        }

        // Count vertices and submesh triangles.
        int                vertexCount = 0;
        int                submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
        Material           lastMaterial               = null;
        ExposedList <Slot> drawOrder                  = skeleton.drawOrder;
        int                drawOrderCount             = drawOrder.Count;
        int                submeshSeparatorSlotsCount = submeshSeparatorSlots.Count;
        bool               renderMeshes               = this.renderMeshes;

        // Clear last state of attachments and submeshes
        ExposedList <int> attachmentsTriangleCountTemp = lastState.attachmentsTriangleCountTemp;

        attachmentsTriangleCountTemp.GrowIfNeeded(drawOrderCount);
        attachmentsTriangleCountTemp.Count = drawOrderCount;
        ExposedList <bool> attachmentsFlipStateTemp = lastState.attachmentsFlipStateTemp;

        attachmentsFlipStateTemp.GrowIfNeeded(drawOrderCount);
        attachmentsFlipStateTemp.Count = drawOrderCount;

        ExposedList <LastState.AddSubmeshArguments> addSubmeshArgumentsTemp = lastState.addSubmeshArgumentsTemp;

        addSubmeshArgumentsTemp.Clear(false);
        for (int i = 0; i < drawOrderCount; i++)
        {
            Slot       slot       = drawOrder.Items[i];
            Bone       bone       = slot.bone;
            Attachment attachment = slot.attachment;

            object rendererObject;
            int    attachmentVertexCount, attachmentTriangleCount;
            bool   worldScaleXIsPositive = bone.worldScaleX >= 0f;
            bool   worldScaleYIsPositive = bone.worldScaleY >= 0f;
            bool   worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) ||
                                           (!worldScaleXIsPositive && !worldScaleYIsPositive);
            bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns);
            attachmentsFlipStateTemp.Items[i] = flip;

            attachmentsTriangleCountTemp.Items[i] = -1;
            RegionAttachment regionAttachment = attachment as RegionAttachment;
            if (regionAttachment != null)
            {
                rendererObject          = regionAttachment.RendererObject;
                attachmentVertexCount   = 4;
                attachmentTriangleCount = 6;
            }
            else
            {
                if (!renderMeshes)
                {
                    continue;
                }
                MeshAttachment meshAttachment = attachment as MeshAttachment;
                if (meshAttachment != null)
                {
                    rendererObject          = meshAttachment.RendererObject;
                    attachmentVertexCount   = meshAttachment.vertices.Length >> 1;
                    attachmentTriangleCount = meshAttachment.triangles.Length;
                }
                else
                {
                    SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
                    if (skinnedMeshAttachment != null)
                    {
                        rendererObject          = skinnedMeshAttachment.RendererObject;
                        attachmentVertexCount   = skinnedMeshAttachment.uvs.Length >> 1;
                        attachmentTriangleCount = skinnedMeshAttachment.triangles.Length;
                    }
                    else
                    {
                        continue;
                    }
                }
            }

            // Populate submesh when material changes.
#if !SPINE_TK2D
            Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
#else
            Material material = (rendererObject.GetType() == typeof(Material)) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject;
#endif
            if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) ||
                (submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot)))
            {
                addSubmeshArgumentsTemp.Add(
                    new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false)
                    );
                submeshTriangleCount  = 0;
                submeshFirstVertex    = vertexCount;
                submeshStartSlotIndex = i;
            }
            lastMaterial = material;

            submeshTriangleCount += attachmentTriangleCount;
            vertexCount          += attachmentVertexCount;

            attachmentsTriangleCountTemp.Items[i] = attachmentTriangleCount;
        }
        addSubmeshArgumentsTemp.Add(
            new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true)
            );

        bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(attachmentsTriangleCountTemp, attachmentsFlipStateTemp, addSubmeshArgumentsTemp);
        if (mustUpdateMeshStructure)
        {
            submeshMaterials.Clear();
            for (int i = 0, n = addSubmeshArgumentsTemp.Count; i < n; i++)
            {
                LastState.AddSubmeshArguments arguments = addSubmeshArgumentsTemp.Items[i];
                AddSubmesh(
                    arguments.material,
                    arguments.startSlot,
                    arguments.endSlot,
                    arguments.triangleCount,
                    arguments.firstVertex,
                    arguments.lastSubmesh,
                    attachmentsFlipStateTemp
                    );
            }

            // Set materials.
            if (submeshMaterials.Count == sharedMaterials.Length)
            {
                submeshMaterials.CopyTo(sharedMaterials);
            }
            else
            {
                sharedMaterials = submeshMaterials.ToArray();
            }

            meshRenderer.sharedMaterials = sharedMaterials;
        }

        // Ensure mesh data is the right size.
        Vector3[] vertices     = this.vertices;
        bool      newTriangles = vertexCount > vertices.Length;
        if (newTriangles)
        {
            // Not enough vertices, increase size.
            this.vertices = vertices = new Vector3[vertexCount];
            this.colors   = new Color32[vertexCount];
            this.uvs      = new Vector2[vertexCount];
            mesh1.Clear();
            mesh2.Clear();
        }
        else
        {
            // Too many vertices, zero the extra.
            Vector3 zero = Vector3.zero;
            for (int i = vertexCount, n = lastState.vertexCount; i < n; i++)
            {
                vertices[i] = zero;
            }
        }
        lastState.vertexCount = vertexCount;

        // Setup mesh.
        float     zSpacing     = this.zSpacing;
        float[]   tempVertices = this.tempVertices;
        Vector2[] uvs          = this.uvs;
        Color32[] colors       = this.colors;
        int       vertexIndex  = 0;
        Color32   color;
        float     a = skeleton.a * 255, r = skeleton.r, g = skeleton.g, b = skeleton.b;

        Vector3 meshBoundsMin;
        Vector3 meshBoundsMax;
        if (vertexCount == 0)
        {
            meshBoundsMin = new Vector3(0, 0, 0);
            meshBoundsMax = new Vector3(0, 0, 0);
        }
        else
        {
            meshBoundsMin.x = int.MaxValue;
            meshBoundsMin.y = int.MaxValue;
            meshBoundsMax.x = int.MinValue;
            meshBoundsMax.y = int.MinValue;
            if (zSpacing > 0f)
            {
                meshBoundsMin.z = 0f;
                meshBoundsMax.z = zSpacing * (drawOrderCount - 1);
            }
            else
            {
                meshBoundsMin.z = zSpacing * (drawOrderCount - 1);
                meshBoundsMax.z = 0f;
            }
            int i = 0;
            do
            {
                Slot             slot             = drawOrder.Items[i];
                Attachment       attachment       = slot.attachment;
                RegionAttachment regionAttachment = attachment as RegionAttachment;
                if (regionAttachment != null)
                {
                    regionAttachment.ComputeWorldVertices(slot.bone, tempVertices);

                    float z = i * zSpacing;
                    float x1 = tempVertices[RegionAttachment.X1], y1 = tempVertices[RegionAttachment.Y1];
                    float x2 = tempVertices[RegionAttachment.X2], y2 = tempVertices[RegionAttachment.Y2];
                    float x3 = tempVertices[RegionAttachment.X3], y3 = tempVertices[RegionAttachment.Y3];
                    float x4 = tempVertices[RegionAttachment.X4], y4 = tempVertices[RegionAttachment.Y4];
                    vertices[vertexIndex].x     = x1;
                    vertices[vertexIndex].y     = y1;
                    vertices[vertexIndex].z     = z;
                    vertices[vertexIndex + 1].x = x4;
                    vertices[vertexIndex + 1].y = y4;
                    vertices[vertexIndex + 1].z = z;
                    vertices[vertexIndex + 2].x = x2;
                    vertices[vertexIndex + 2].y = y2;
                    vertices[vertexIndex + 2].z = z;
                    vertices[vertexIndex + 3].x = x3;
                    vertices[vertexIndex + 3].y = y3;
                    vertices[vertexIndex + 3].z = z;

                    color.a = (byte)(a * slot.a * regionAttachment.a);
                    color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
                    color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
                    color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
                    if (slot.data.blendMode == BlendMode.additive)
                    {
                        color.a = 0;
                    }
                    colors[vertexIndex]     = color;
                    colors[vertexIndex + 1] = color;
                    colors[vertexIndex + 2] = color;
                    colors[vertexIndex + 3] = color;

                    float[] regionUVs = regionAttachment.uvs;
                    uvs[vertexIndex].x     = regionUVs[RegionAttachment.X1];
                    uvs[vertexIndex].y     = regionUVs[RegionAttachment.Y1];
                    uvs[vertexIndex + 1].x = regionUVs[RegionAttachment.X4];
                    uvs[vertexIndex + 1].y = regionUVs[RegionAttachment.Y4];
                    uvs[vertexIndex + 2].x = regionUVs[RegionAttachment.X2];
                    uvs[vertexIndex + 2].y = regionUVs[RegionAttachment.Y2];
                    uvs[vertexIndex + 3].x = regionUVs[RegionAttachment.X3];
                    uvs[vertexIndex + 3].y = regionUVs[RegionAttachment.Y3];

                    // Calculate min/max X
                    if (x1 < meshBoundsMin.x)
                    {
                        meshBoundsMin.x = x1;
                    }
                    else if (x1 > meshBoundsMax.x)
                    {
                        meshBoundsMax.x = x1;
                    }
                    if (x2 < meshBoundsMin.x)
                    {
                        meshBoundsMin.x = x2;
                    }
                    else if (x2 > meshBoundsMax.x)
                    {
                        meshBoundsMax.x = x2;
                    }
                    if (x3 < meshBoundsMin.x)
                    {
                        meshBoundsMin.x = x3;
                    }
                    else if (x3 > meshBoundsMax.x)
                    {
                        meshBoundsMax.x = x3;
                    }
                    if (x4 < meshBoundsMin.x)
                    {
                        meshBoundsMin.x = x4;
                    }
                    else if (x4 > meshBoundsMax.x)
                    {
                        meshBoundsMax.x = x4;
                    }

                    // Calculate min/max Y
                    if (y1 < meshBoundsMin.y)
                    {
                        meshBoundsMin.y = y1;
                    }
                    else if (y1 > meshBoundsMax.y)
                    {
                        meshBoundsMax.y = y1;
                    }
                    if (y2 < meshBoundsMin.y)
                    {
                        meshBoundsMin.y = y2;
                    }
                    else if (y2 > meshBoundsMax.y)
                    {
                        meshBoundsMax.y = y2;
                    }
                    if (y3 < meshBoundsMin.y)
                    {
                        meshBoundsMin.y = y3;
                    }
                    else if (y3 > meshBoundsMax.y)
                    {
                        meshBoundsMax.y = y3;
                    }
                    if (y4 < meshBoundsMin.y)
                    {
                        meshBoundsMin.y = y4;
                    }
                    else if (y4 > meshBoundsMax.y)
                    {
                        meshBoundsMax.y = y4;
                    }

                    vertexIndex += 4;
                }
                else
                {
                    if (!renderMeshes)
                    {
                        continue;
                    }
                    MeshAttachment meshAttachment = attachment as MeshAttachment;
                    if (meshAttachment != null)
                    {
                        int meshVertexCount = meshAttachment.vertices.Length;
                        if (tempVertices.Length < meshVertexCount)
                        {
                            this.tempVertices = tempVertices = new float[meshVertexCount];
                        }
                        meshAttachment.ComputeWorldVertices(slot, tempVertices);

                        color.a = (byte)(a * slot.a * meshAttachment.a);
                        color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
                        color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
                        color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
                        if (slot.data.blendMode == BlendMode.additive)
                        {
                            color.a = 0;
                        }

                        float[] meshUVs = meshAttachment.uvs;
                        float   z       = i * zSpacing;
                        for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                        {
                            float x = tempVertices[ii], y = tempVertices[ii + 1];
                            vertices[vertexIndex].x = x;
                            vertices[vertexIndex].y = y;
                            vertices[vertexIndex].z = z;
                            colors[vertexIndex]     = color;
                            uvs[vertexIndex].x      = meshUVs[ii];
                            uvs[vertexIndex].y      = meshUVs[ii + 1];

                            if (x < meshBoundsMin.x)
                            {
                                meshBoundsMin.x = x;
                            }
                            else if (x > meshBoundsMax.x)
                            {
                                meshBoundsMax.x = x;
                            }
                            if (y < meshBoundsMin.y)
                            {
                                meshBoundsMin.y = y;
                            }
                            else if (y > meshBoundsMax.y)
                            {
                                meshBoundsMax.y = y;
                            }
                        }
                    }
                    else
                    {
                        SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
                        if (skinnedMeshAttachment != null)
                        {
                            int meshVertexCount = skinnedMeshAttachment.uvs.Length;
                            if (tempVertices.Length < meshVertexCount)
                            {
                                this.tempVertices = tempVertices = new float[meshVertexCount];
                            }
                            skinnedMeshAttachment.ComputeWorldVertices(slot, tempVertices);

                            color.a = (byte)(a * slot.a * skinnedMeshAttachment.a);
                            color.r = (byte)(r * slot.r * skinnedMeshAttachment.r * color.a);
                            color.g = (byte)(g * slot.g * skinnedMeshAttachment.g * color.a);
                            color.b = (byte)(b * slot.b * skinnedMeshAttachment.b * color.a);
                            if (slot.data.blendMode == BlendMode.additive)
                            {
                                color.a = 0;
                            }

                            float[] meshUVs = skinnedMeshAttachment.uvs;
                            float   z       = i * zSpacing;
                            for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                            {
                                float x = tempVertices[ii], y = tempVertices[ii + 1];
                                vertices[vertexIndex].x = x;
                                vertices[vertexIndex].y = y;
                                vertices[vertexIndex].z = z;
                                colors[vertexIndex]     = color;
                                uvs[vertexIndex].x      = meshUVs[ii];
                                uvs[vertexIndex].y      = meshUVs[ii + 1];

                                if (x < meshBoundsMin.x)
                                {
                                    meshBoundsMin.x = x;
                                }
                                else if (x > meshBoundsMax.x)
                                {
                                    meshBoundsMax.x = x;
                                }
                                if (y < meshBoundsMin.y)
                                {
                                    meshBoundsMin.y = y;
                                }
                                else if (y > meshBoundsMax.y)
                                {
                                    meshBoundsMax.y = y;
                                }
                            }
                        }
                    }
                }
            } while (++i < drawOrderCount);
        }

        // Double buffer mesh.
        Mesh mesh = useMesh1 ? mesh1 : mesh2;
        meshFilter.sharedMesh = mesh;

        mesh.vertices = vertices;
        mesh.colors32 = colors;
        mesh.uv       = uvs;

        if (mustUpdateMeshStructure)
        {
            int submeshCount = submeshMaterials.Count;
            mesh.subMeshCount = submeshCount;
            for (int i = 0; i < submeshCount; ++i)
            {
                mesh.SetTriangles(submeshes.Items[i].triangles, i);
            }
        }

        Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;
        Vector3 meshBoundsCenter  = meshBoundsMin + meshBoundsExtents * 0.5f;
        mesh.bounds = new Bounds(meshBoundsCenter, meshBoundsExtents);

        if (newTriangles && calculateNormals)
        {
            Vector3[] normals = new Vector3[vertexCount];
            Vector3   normal  = new Vector3(0, 0, -1);
            for (int i = 0; i < vertexCount; i++)
            {
                normals[i] = normal;
            }
            (useMesh1 ? mesh2 : mesh1).vertices = vertices;             // Set other mesh vertices.
            mesh1.normals = normals;
            mesh2.normals = normals;

            if (calculateTangents)
            {
                Vector4[] tangents = new Vector4[vertexCount];
                Vector3   tangent  = new Vector3(0, 0, 1);
                for (int i = 0; i < vertexCount; i++)
                {
                    tangents[i] = tangent;
                }
                mesh1.tangents = tangents;
                mesh2.tangents = tangents;
            }
        }

        // Update previous state
        ExposedList <int>  attachmentsTriangleCountCurrentMesh;
        ExposedList <bool> attachmentsFlipStateCurrentMesh;
        ExposedList <LastState.AddSubmeshArguments> addSubmeshArgumentsCurrentMesh;
        if (useMesh1)
        {
            attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh1;
            addSubmeshArgumentsCurrentMesh      = lastState.addSubmeshArgumentsMesh1;
            attachmentsFlipStateCurrentMesh     = lastState.attachmentsFlipStateMesh1;
            lastState.immutableTrianglesMesh1   = immutableTriangles;
        }
        else
        {
            attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh2;
            addSubmeshArgumentsCurrentMesh      = lastState.addSubmeshArgumentsMesh2;
            attachmentsFlipStateCurrentMesh     = lastState.attachmentsFlipStateMesh2;
            lastState.immutableTrianglesMesh2   = immutableTriangles;
        }

        attachmentsTriangleCountCurrentMesh.GrowIfNeeded(attachmentsTriangleCountTemp.Capacity);
        attachmentsTriangleCountCurrentMesh.Count = attachmentsTriangleCountTemp.Count;
        attachmentsTriangleCountTemp.CopyTo(attachmentsTriangleCountCurrentMesh.Items, 0);

        attachmentsFlipStateCurrentMesh.GrowIfNeeded(attachmentsFlipStateTemp.Capacity);
        attachmentsFlipStateCurrentMesh.Count = attachmentsFlipStateTemp.Count;
        attachmentsFlipStateTemp.CopyTo(attachmentsFlipStateCurrentMesh.Items, 0);

        addSubmeshArgumentsCurrentMesh.GrowIfNeeded(addSubmeshArgumentsTemp.Count);
        addSubmeshArgumentsCurrentMesh.Count = addSubmeshArgumentsTemp.Count;
        addSubmeshArgumentsTemp.CopyTo(addSubmeshArgumentsCurrentMesh.Items);

        if (submeshRenderers.Length > 0)
        {
            for (int i = 0; i < submeshRenderers.Length; i++)
            {
                SkeletonUtilitySubmeshRenderer submeshRenderer = submeshRenderers[i];
                if (submeshRenderer.submeshIndex < sharedMaterials.Length)
                {
                    submeshRenderer.SetMesh(meshRenderer, useMesh1 ? mesh1 : mesh2, sharedMaterials[submeshRenderer.submeshIndex]);
                }
                else
                {
                    submeshRenderer.GetComponent <Renderer>().enabled = false;
                }
            }
        }

        useMesh1 = !useMesh1;
    }
    public virtual void LateUpdate()
    {
        if (!valid)
        {
            return;
        }
        // Count vertices and submesh triangles.
        int      vertexCount = 0;
        int      submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
        Material lastMaterial = null;

        submeshMaterials.Clear();
        List <Slot> drawOrder      = skeleton.DrawOrder;
        int         drawOrderCount = drawOrder.Count;
        bool        renderMeshes   = this.renderMeshes;

        for (int i = 0; i < drawOrderCount; i++)
        {
            Slot       slot       = drawOrder[i];
            Attachment attachment = slot.attachment;

            object rendererObject;
            int    attachmentVertexCount, attachmentTriangleCount;

            if (attachment is RegionAttachment)
            {
                rendererObject          = ((RegionAttachment)attachment).RendererObject;
                attachmentVertexCount   = 4;
                attachmentTriangleCount = 6;
            }
            else
            {
                if (!renderMeshes)
                {
                    continue;
                }
                if (attachment is MeshAttachment)
                {
                    MeshAttachment meshAttachment = (MeshAttachment)attachment;
                    rendererObject          = meshAttachment.RendererObject;
                    attachmentVertexCount   = meshAttachment.vertices.Length >> 1;
                    attachmentTriangleCount = meshAttachment.triangles.Length;
                }
                else if (attachment is SkinnedMeshAttachment)
                {
                    SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
                    rendererObject          = meshAttachment.RendererObject;
                    attachmentVertexCount   = meshAttachment.uvs.Length >> 1;
                    attachmentTriangleCount = meshAttachment.triangles.Length;
                }
                else
                {
                    continue;
                }
            }

            // Populate submesh when material changes.
            Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
            if ((lastMaterial != material && lastMaterial != null) || slot.Data.name[0] == '*')
            {
                AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
                submeshTriangleCount  = 0;
                submeshFirstVertex    = vertexCount;
                submeshStartSlotIndex = i;
            }
            lastMaterial = material;

            submeshTriangleCount += attachmentTriangleCount;
            vertexCount          += attachmentVertexCount;
        }
        AddSubmesh(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true);

        // Set materials.
        if (submeshMaterials.Count == sharedMaterials.Length)
        {
            submeshMaterials.CopyTo(sharedMaterials);
        }
        else
        {
            sharedMaterials = submeshMaterials.ToArray();
        }
        renderer.sharedMaterials = sharedMaterials;

        // Ensure mesh data is the right size.
        Vector3[] vertices     = this.vertices;
        bool      newTriangles = vertexCount > vertices.Length;

        if (newTriangles)
        {
            // Not enough vertices, increase size.
            this.vertices = vertices = new Vector3[vertexCount];
            this.colors   = new Color32[vertexCount];
            this.uvs      = new Vector2[vertexCount];
            mesh1.Clear();
            mesh2.Clear();
        }
        else
        {
            // Too many vertices, zero the extra.
            Vector3 zero = Vector3.zero;
            for (int i = vertexCount, n = lastVertexCount; i < n; i++)
            {
                vertices[i] = zero;
            }
        }
        lastVertexCount = vertexCount;

        // Setup mesh.
        float[]   tempVertices = this.tempVertices;
        Vector2[] uvs = this.uvs;
        Color32[] colors = this.colors;
        int       vertexIndex = 0;
        Color32   color = new Color32();
        float     zSpacing = this.zSpacing;
        float     a = skeleton.a * 255, r = skeleton.r, g = skeleton.g, b = skeleton.b;

        for (int i = 0; i < drawOrderCount; i++)
        {
            Slot       slot       = drawOrder[i];
            Attachment attachment = slot.attachment;
            if (attachment is RegionAttachment)
            {
                RegionAttachment regionAttachment = (RegionAttachment)attachment;
                regionAttachment.ComputeWorldVertices(slot.bone, tempVertices);

                float z = i * zSpacing;
                vertices[vertexIndex]     = new Vector3(tempVertices[RegionAttachment.X1], tempVertices[RegionAttachment.Y1], z);
                vertices[vertexIndex + 1] = new Vector3(tempVertices[RegionAttachment.X4], tempVertices[RegionAttachment.Y4], z);
                vertices[vertexIndex + 2] = new Vector3(tempVertices[RegionAttachment.X2], tempVertices[RegionAttachment.Y2], z);
                vertices[vertexIndex + 3] = new Vector3(tempVertices[RegionAttachment.X3], tempVertices[RegionAttachment.Y3], z);

                color.a = (byte)(a * slot.a * regionAttachment.a);
                color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
                color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
                color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
                if (slot.data.additiveBlending)
                {
                    color.a = 0;
                }
                colors[vertexIndex]     = color;
                colors[vertexIndex + 1] = color;
                colors[vertexIndex + 2] = color;
                colors[vertexIndex + 3] = color;

                float[] regionUVs = regionAttachment.uvs;
                uvs[vertexIndex]     = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]);
                uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]);
                uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]);
                uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]);

                vertexIndex += 4;
            }
            else
            {
                if (!renderMeshes)
                {
                    continue;
                }
                if (attachment is MeshAttachment)
                {
                    MeshAttachment meshAttachment  = (MeshAttachment)attachment;
                    int            meshVertexCount = meshAttachment.vertices.Length;
                    if (tempVertices.Length < meshVertexCount)
                    {
                        tempVertices = new float[meshVertexCount];
                    }
                    meshAttachment.ComputeWorldVertices(slot, tempVertices);

                    color.a = (byte)(a * slot.a * meshAttachment.a);
                    color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
                    color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
                    color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
                    if (slot.data.additiveBlending)
                    {
                        color.a = 0;
                    }

                    float[] meshUVs = meshAttachment.uvs;
                    float   z       = i * zSpacing;
                    for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                    {
                        vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
                        colors[vertexIndex]   = color;
                        uvs[vertexIndex]      = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
                    }
                }
                else if (attachment is SkinnedMeshAttachment)
                {
                    SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
                    int meshVertexCount = meshAttachment.uvs.Length;
                    if (tempVertices.Length < meshVertexCount)
                    {
                        tempVertices = new float[meshVertexCount];
                    }
                    meshAttachment.ComputeWorldVertices(slot, tempVertices);

                    color.a = (byte)(a * slot.a * meshAttachment.a);
                    color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
                    color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
                    color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
                    if (slot.data.additiveBlending)
                    {
                        color.a = 0;
                    }

                    float[] meshUVs = meshAttachment.uvs;
                    float   z       = i * zSpacing;
                    for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++)
                    {
                        vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
                        colors[vertexIndex]   = color;
                        uvs[vertexIndex]      = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
                    }
                }
            }
        }

        // Double buffer mesh.
        Mesh mesh = useMesh1 ? mesh1 : mesh2;

        meshFilter.sharedMesh = mesh;

        mesh.vertices = vertices;
        mesh.colors32 = colors;
        mesh.uv       = uvs;

        int submeshCount = submeshMaterials.Count;

        mesh.subMeshCount = submeshCount;
        for (int i = 0; i < submeshCount; ++i)
        {
            mesh.SetTriangles(submeshes[i].triangles, i);
        }
        mesh.RecalculateBounds();

        if (newTriangles && calculateNormals)
        {
            Vector3[] normals = new Vector3[vertexCount];
            Vector3   normal  = new Vector3(0, 0, -1);
            for (int i = 0; i < vertexCount; i++)
            {
                normals[i] = normal;
            }
            (useMesh1 ? mesh2 : mesh1).vertices = vertices;             // Set other mesh vertices.
            mesh1.normals = normals;
            mesh2.normals = normals;

            if (calculateTangents)
            {
                Vector4[] tangents = new Vector4[vertexCount];
                Vector3   tangent  = new Vector3(0, 0, 1);
                for (int i = 0; i < vertexCount; i++)
                {
                    tangents[i] = tangent;
                }
                mesh1.tangents = tangents;
                mesh2.tangents = tangents;
            }
        }

        useMesh1 = !useMesh1;
    }
        private void InternalDraw(Skeleton pSkeleton, Texture2D[] pTextureArray, float pDepth, float scale, Color pColor)
        {
            if (!isBegin)
            {
                throw new Exception("Beginn muss vor Draw aufgerufen werden!");
            }

            float[]     vertices = this.mSkeletonVertecies;
            List <Slot> drawOrder = pSkeleton.DrawOrder;
            float       x = pSkeleton.X, y = pSkeleton.Y;
            int         textId = this.mBatch.AddTextures(pTextureArray);

            for (int i = 0, n = drawOrder.Count; i < n; i++)
            {
                Slot       slot       = drawOrder[i];
                Attachment attachment = slot.Attachment;

                if (attachment is RegionAttachment)
                {
                    RegionAttachment regionAttachment = (RegionAttachment)attachment;

                    MeshData item = this.mBatch.NextItem(4, 6);

                    item.triangles = quadIndecies;

                    AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject;
                    regionAttachment.ComputeWorldVertices(x, y, slot.Bone, vertices);



                    item.vertices[TL].Position.X = vertices[RegionAttachment.X1];
                    item.vertices[TL].Position.Y = vertices[RegionAttachment.Y1];
                    item.vertices[TL].Position.Z = pDepth;                    // -orderDepth * (n - (i + 1));
                    item.vertices[BL].Position.X = vertices[RegionAttachment.X2];
                    item.vertices[BL].Position.Y = vertices[RegionAttachment.Y2];
                    item.vertices[BL].Position.Z = pDepth;// -orderDepth * (n - (i + 1));
                    item.vertices[BR].Position.X = vertices[RegionAttachment.X3];
                    item.vertices[BR].Position.Y = vertices[RegionAttachment.Y3];
                    item.vertices[BR].Position.Z = pDepth;// -orderDepth * (n - (i + 1));
                    item.vertices[TR].Position.X = vertices[RegionAttachment.X4];
                    item.vertices[TR].Position.Y = vertices[RegionAttachment.Y4];
                    item.vertices[TR].Position.Z = pDepth;// -orderDepth * (n - (i + 1));

                    float[] uvs = regionAttachment.UVs;
                    item.vertices[TL].TextureCoordinate.X = uvs[RegionAttachment.X1];
                    item.vertices[TL].TextureCoordinate.Y = uvs[RegionAttachment.Y1];
                    item.vertices[BL].TextureCoordinate.X = uvs[RegionAttachment.X2];
                    item.vertices[BL].TextureCoordinate.Y = uvs[RegionAttachment.Y2];
                    item.vertices[BR].TextureCoordinate.X = uvs[RegionAttachment.X3];
                    item.vertices[BR].TextureCoordinate.Y = uvs[RegionAttachment.Y3];
                    item.vertices[TR].TextureCoordinate.X = uvs[RegionAttachment.X4];
                    item.vertices[TR].TextureCoordinate.Y = uvs[RegionAttachment.Y4];

                    item.vertices[TL].Color = pColor;
                    item.vertices[BL].Color = pColor;
                    item.vertices[BR].Color = pColor;
                    item.vertices[TR].Color = pColor;

                    item.TextureID = textId;
                }
                else if (attachment is MeshAttachment)
                {
                    MeshAttachment mesh = (MeshAttachment)attachment;

                    int vertexCount = mesh.Vertices.Length;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }

                    mesh.ComputeWorldVertices(x, y, slot, vertices);

                    int[]    triangles = mesh.triangles;
                    MeshData item      = mBatch.NextItem(vertexCount, triangles.Length);

                    item.triangles = triangles;
                    item.TextureID = textId;

                    AtlasRegion region = (AtlasRegion)mesh.RendererObject;

                    float[] uvs = mesh.UVs;
                    VertexPositionColorTexture[] itemVertices = item.vertices;

                    for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2)
                    {
                        itemVertices[ii].Position.X          = vertices[v];
                        itemVertices[ii].Position.Y          = vertices[v + 1];
                        itemVertices[ii].Position.Z          = pDepth;
                        itemVertices[ii].TextureCoordinate.X = uvs[v];
                        itemVertices[ii].TextureCoordinate.Y = uvs[v + 1];
                        itemVertices[ii].Color = pColor;
                    }
                }
                else if (attachment is SkinnedMeshAttachment)
                {
                    SkinnedMeshAttachment mesh = (SkinnedMeshAttachment)attachment;
                    int vertexCount            = mesh.UVs.Length;
                    if (vertices.Length < vertexCount)
                    {
                        vertices = new float[vertexCount];
                    }
                    mesh.ComputeWorldVertices(x, y, slot, vertices);

                    int[]    triangles = mesh.Triangles;
                    MeshData item      = mBatch.NextItem(vertexCount, triangles.Length);
                    item.triangles = triangles;
                    item.TextureID = textId;


                    float[] uvs = mesh.UVs;
                    VertexPositionColorTexture[] itemVertices = item.vertices;
                    for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2)
                    {
                        itemVertices[ii].Position.X          = vertices[v];
                        itemVertices[ii].Position.Y          = vertices[v + 1];
                        itemVertices[ii].Position.Z          = 0;
                        itemVertices[ii].TextureCoordinate.X = uvs[v];
                        itemVertices[ii].TextureCoordinate.Y = uvs[v + 1];
                        itemVertices[ii].Color = pColor;
                    }
                }
            }
        }