public static void SetColor(this SkinnedMeshAttachment attachment, Color32 color)
 {
     attachment.A = color.a * ByteToFloat;
     attachment.R = color.r * ByteToFloat;
     attachment.G = color.g * ByteToFloat;
     attachment.B = color.b * ByteToFloat;
 }
 public static void SetColor(this SkinnedMeshAttachment attachment, Color32 color)
 {
     attachment.A = color.a / 255f;
     attachment.R = color.r / 255f;
     attachment.G = color.g / 255f;
     attachment.B = color.b / 255f;
 }
 public static void SetColor(this SkinnedMeshAttachment attachment, Color color)
 {
     attachment.A = color.a;
     attachment.R = color.r;
     attachment.G = color.g;
     attachment.B = color.b;
 }
	public SkinnedMeshAttachment NewSkinnedMeshAttachment (Skin skin, String name, String path) {
		ProcessSpriteDefinition(path);
		
		SkinnedMeshAttachment mesh = new SkinnedMeshAttachment(name);
		mesh.Path = path;
		mesh.RendererObject = material;
		mesh.RegionU = u;
		mesh.RegionV = v;
		mesh.RegionU2 = u2;
		mesh.RegionV2 = v2;
		mesh.RegionRotate = regionRotated;
		mesh.RegionOriginalWidth = regionOriginalWidth;
		mesh.RegionOriginalHeight = regionOriginalHeight;
		mesh.RegionWidth = regionWidth;
		mesh.RegionHeight = regionHeight;
		mesh.RegionOffsetX = regionOffsetX;
		mesh.RegionOffsetY = regionOffsetY;
		return mesh;
	}
예제 #5
0
        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);
                }
            }
        }
예제 #6
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
        MeshState.SingleMeshState workingState = meshState.buffer;
        var workingAttachments      = workingState.attachments;
        var workingFlips            = workingState.attachmentsFlipState;
        var workingSubmeshArguments = workingState.addSubmeshArguments;

        workingAttachments.Clear(true);
        workingState.UpdateAttachmentCount(drawOrderCount);
        workingSubmeshArguments.Clear(false);

        MeshState.SingleMeshState storedState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2;
        var storedAttachments = storedState.attachments;
        var storedFlips       = storedState.attachmentsFlipState;

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

        for (int i = 0; i < drawOrderCount; i++)
        {
            Slot       slot       = drawOrder.Items[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 normals (for lighting).
            bool worldScaleIsSameSigns = ((bone.worldScaleY >= 0f) == (bone.worldScaleX >= 0f));
            bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns);             // TODO: bone flipX and flipY will be removed in Spine 3.0

            workingFlips.Items[i]       = flip;
            workingAttachments.Items[i] = attachment;

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

            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;
                    }
                }
            }

                        #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

            // Populate submesh when material changes. (or when forced to separate by a submeshSeparator)
            if ((lastMaterial != null && 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();
            for (int i = 0, n = workingSubmeshArguments.Count; i < n; i++)
            {
                AddSubmesh(workingSubmeshArguments.Items[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             = 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);
            }

            // 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];
                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
        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;
    }
예제 #7
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);
                    }
                }
            }
        }
예제 #8
0
파일: SkeletonBin.cs 프로젝트: PenpenLi/Nav
    Attachment readAttachment(Skin skin, string attachmentName, bool nonessential)
    {
        string name = ReadString();

        if (name == "")
        {
            name = attachmentName;
        }

        int type = Read();

        switch ((AttachmentType)type)
        {
        case AttachmentType.region:
        {
            string path = ReadString();
            if (path == "")
            {
                path = name;
            }

            RegionAttachment region = m_attachmentLoader.NewRegionAttachment(skin, name, path);
            if (region == null)
            {
                return(null);
            }
            region.Path     = path;
            region.X        = ReadFloat();
            region.Y        = ReadFloat();
            region.ScaleX   = ReadFloat();
            region.ScaleY   = ReadFloat();
            region.Rotation = ReadFloat();
            region.Width    = ReadFloat();
            region.Height   = ReadFloat();
            //Color
            Color color = ReadColor();
            region.R = color.r;
            region.G = color.g;
            region.B = color.b;
            region.A = color.a;

            region.UpdateOffset();
            return(region);
        }

        case AttachmentType.boundingbox:
        {
            BoundingBoxAttachment box = m_attachmentLoader.NewBoundingBoxAttachment(skin, name);
            if (box == null)
            {
                return(null);
            }
            box.Vertices = readFloatArray();
            return(box);
        }

        case AttachmentType.mesh:
        {
            string path = ReadString();
            if (path == "")
            {
                path = name;
            }
            MeshAttachment mesh = m_attachmentLoader.NewMeshAttachment(skin, name, path);
            if (mesh == null)
            {
                return(null);
            }
            mesh.Path = path;
            float[] uvs       = readFloatArray();
            int[]   triangles = readShortArray();
            float[] vertices  = readFloatArray();
            mesh.vertices  = vertices;
            mesh.Triangles = triangles;
            mesh.regionUVs = uvs;
            mesh.UpdateUVs();
            //Color
            Color color = ReadColor();
            mesh.R = color.r;
            mesh.G = color.g;
            mesh.B = color.b;
            mesh.A = color.a;

            mesh.HullLength = ReadInt() * 2;
            if (nonessential)
            {
                mesh.Edges  = readIntArray();
                mesh.Width  = ReadFloat();
                mesh.Height = ReadFloat();
            }

            return(mesh);
        }

        case AttachmentType.skinnedmesh:
        {
            string path = ReadString();
            if (path == "")
            {
                path = name;
            }
            SkinnedMeshAttachment mesh = m_attachmentLoader.NewSkinnedMeshAttachment(skin, name, path);
            if (mesh == null)
            {
                return(null);
            }
            mesh.Path = path;
            float[] uvs       = readFloatArray();
            int[]   triangles = readShortArray();

            int          vertexCount = ReadInt();
            List <float> weights     = new List <float>(uvs.Length * 3 * 3);
            List <int>   bones       = new List <int>(uvs.Length * 3);

            for (int i = 0; i < vertexCount; i++)
            {
                int boneCount = (int)ReadFloat();
                bones.Add(boneCount);
                for (int j = i + boneCount * 4; i < j; i += 4)
                {
                    bones.Add((int)ReadFloat());
                    weights.Add(ReadFloat());
                    weights.Add(ReadFloat());
                    weights.Add(ReadFloat());
                }
            }
            mesh.bones     = bones.ToArray();
            mesh.Weights   = weights.ToArray();
            mesh.Triangles = triangles;
            mesh.regionUVs = uvs;
            mesh.UpdateUVs();
            //Color
            Color color = ReadColor();
            mesh.R = color.r;
            mesh.G = color.g;
            mesh.B = color.b;
            mesh.A = color.a;

            mesh.HullLength = ReadInt() * 2;
            if (nonessential)
            {
                mesh.Edges  = readIntArray();
                mesh.Width  = ReadFloat();
                mesh.Height = ReadFloat();
            }
            return(mesh);
        }
        }
        return(null);
    }
예제 #9
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);
        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;
    }
예제 #10
0
    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;
    }
예제 #11
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();
                    }
                }
            }
        }
예제 #12
0
    /** Stores vertices and triangles for a single material. */
    private void addSubmesh(Material material, int startSlot, int endSlot, int triangleCount, int firstVertex, bool lastSubmesh)
    {
        int submeshIndex = submeshMaterials.Count;

        submeshMaterials.Add(material);

        if (submeshes.Count <= submeshIndex)
        {
            submeshes.Add(new Submesh());
        }
        Submesh submesh = submeshes[submeshIndex];

        int[] triangles         = submesh.triangles;
        int   trianglesCapacity = triangles.Length;

        if (lastSubmesh && trianglesCapacity > triangleCount)
        {
            // Last submesh may have more triangles than required, so zero triangles to the end.
            for (int i = triangleCount; i < trianglesCapacity; i++)
            {
                triangles[i] = 0;
            }
            submesh.triangleCount = triangleCount;
        }
        else if (trianglesCapacity != triangleCount)
        {
            // Reallocate triangles when not the exact size needed.
            submesh.triangles     = triangles = new int[triangleCount];
            submesh.triangleCount = 0;
        }

        List <Slot> drawOrder = skeleton.DrawOrder;

        for (int i = startSlot, triangleIndex = 0; i < endSlot; i++)
        {
            Attachment attachment = drawOrder[i].attachment;
            int[]      attachmentTriangles;
            int        attachmentVertexCount;
            if (attachment is RegionAttachment)
            {
                attachmentVertexCount = 4;
                attachmentTriangles   = quadTriangles;
            }
            else if (attachment is MeshAttachment)
            {
                MeshAttachment meshAttachment = (MeshAttachment)attachment;
                attachmentVertexCount = meshAttachment.vertices.Length / 2;
                attachmentTriangles   = meshAttachment.triangles;
            }
            else if (attachment is SkinnedMeshAttachment)
            {
                SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
                attachmentVertexCount = meshAttachment.uvs.Length / 2;
                attachmentTriangles   = meshAttachment.triangles;
            }
            else
            {
                continue;
            }
            for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++)
            {
                triangles[triangleIndex] = firstVertex + attachmentTriangles[ii];
            }
            firstVertex += attachmentVertexCount;
        }
    }
예제 #13
0
 public static Color GetColor(this SkinnedMeshAttachment a)
 {
     return(new Color(a.r, a.g, a.b, a.a));
 }
예제 #14
0
	/** Stores vertices and triangles for a single material. */
	private void AddSubmesh (Material material, int startSlot, int endSlot, int triangleCount, int firstVertex, bool lastSubmesh) {
		
		int submeshIndex = submeshMaterials.Count;
		submeshMaterials.Add(material);

		if (submeshes.Count <= submeshIndex)
			submeshes.Add(new Submesh());
		else if (immutableTriangles)
			return;

		Submesh submesh = submeshes[submeshIndex];

		int[] triangles = submesh.triangles;
		int trianglesCapacity = triangles.Length;
		if (lastSubmesh && trianglesCapacity > triangleCount) {
			// Last submesh may have more triangles than required, so zero triangles to the end.
			for (int i = triangleCount; i < trianglesCapacity; i++)
				triangles[i] = 0;
			submesh.triangleCount = triangleCount;
		} else if (trianglesCapacity != triangleCount) {
			// Reallocate triangles when not the exact size needed.
			submesh.triangles = triangles = new int[triangleCount];
			submesh.triangleCount = 0;
		}

		if (!renderMeshes && !frontFacing) {
			// Use stored triangles if possible.
			if (submesh.firstVertex != firstVertex || submesh.triangleCount < triangleCount) {
				submesh.triangleCount = triangleCount;
				submesh.firstVertex = firstVertex;
				int drawOrderIndex = 0;
				for (int i = 0; i < triangleCount; i += 6, firstVertex += 4, drawOrderIndex++) {
					triangles[i] = firstVertex;
					triangles[i + 1] = firstVertex + 2;
					triangles[i + 2] = firstVertex + 1;
					triangles[i + 3] = firstVertex + 2;
					triangles[i + 4] = firstVertex + 3;
					triangles[i + 5] = firstVertex + 1;
				}
			}
			return;
		}

		// Store triangles.
		List<Slot> drawOrder = skeleton.DrawOrder;
		for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) {
			Slot slot = drawOrder[i];
			Attachment attachment = slot.attachment;
			Bone bone = slot.bone;
			bool flip = frontFacing && ((bone.WorldFlipX != bone.WorldFlipY) != (Mathf.Sign(bone.WorldScaleX) != Mathf.Sign(bone.WorldScaleY)));

			if (attachment is RegionAttachment) {
				if (!flip) {
					triangles[triangleIndex] = firstVertex;
					triangles[triangleIndex + 1] = firstVertex + 2;
					triangles[triangleIndex + 2] = firstVertex + 1;
					triangles[triangleIndex + 3] = firstVertex + 2;
					triangles[triangleIndex + 4] = firstVertex + 3;
					triangles[triangleIndex + 5] = firstVertex + 1;
				} else {
					triangles[triangleIndex] = firstVertex + 1;
					triangles[triangleIndex + 1] = firstVertex + 2;
					triangles[triangleIndex + 2] = firstVertex;
					triangles[triangleIndex + 3] = firstVertex + 1;
					triangles[triangleIndex + 4] = firstVertex + 3;
					triangles[triangleIndex + 5] = firstVertex + 2;
				}

				triangleIndex += 6;
				firstVertex += 4;
				continue;
			}
			int[] attachmentTriangles;
			int attachmentVertexCount;
			if (attachment is MeshAttachment) {
				MeshAttachment meshAttachment = (MeshAttachment)attachment;
				attachmentVertexCount = meshAttachment.vertices.Length >> 1;
				attachmentTriangles = meshAttachment.triangles;
			} else if (attachment is SkinnedMeshAttachment) {
				SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
				attachmentVertexCount = meshAttachment.uvs.Length >> 1;
				attachmentTriangles = meshAttachment.triangles;
			} else
				continue;

			if (flip) {
				for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii += 3, triangleIndex += 3) {
					triangles[triangleIndex + 2] = firstVertex + attachmentTriangles[ii];
					triangles[triangleIndex + 1] = firstVertex + attachmentTriangles[ii + 1];
					triangles[triangleIndex] = firstVertex + attachmentTriangles[ii + 2];
				}
			} else {
				for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++) {
					triangles[triangleIndex] = firstVertex + attachmentTriangles[ii];
				}
			}

			firstVertex += attachmentVertexCount;
		}
	}
예제 #15
0
    private void AddSubmesh(MeshState.AddSubmeshArguments submeshArguments, ExposedList <bool> flipStates)
    {
        int submeshIndex = submeshMaterials.Count;

        submeshMaterials.Add(submeshArguments.material);

        if (submeshes.Count <= submeshIndex)
        {
            submeshes.Add(new Submesh());
        }
        else if (immutableTriangles)
        {
            return;
        }

        Submesh submesh = submeshes.Items[submeshIndex];

        int[] triangles = submesh.triangles;

        int triangleCount = submeshArguments.triangleCount;
        int firstVertex   = submeshArguments.firstVertex;

        int trianglesCapacity = triangles.Length;

        if (submeshArguments.isLastSubmesh && trianglesCapacity > triangleCount)
        {
            // Last submesh may have more triangles than required, so zero triangles to the end.
            for (int i = triangleCount; i < trianglesCapacity; i++)
            {
                triangles[i] = 0;
            }
            submesh.triangleCount = triangleCount;
        }
        else if (trianglesCapacity != triangleCount)
        {
            // Reallocate triangles when not the exact size needed.
            submesh.triangles     = triangles = new int[triangleCount];
            submesh.triangleCount = 0;
        }

        if (!renderMeshes && !frontFacing)
        {
            // Use stored triangles if possible.
            if (submesh.firstVertex != firstVertex || submesh.triangleCount < triangleCount)
            {
                submesh.triangleCount = triangleCount;
                submesh.firstVertex   = firstVertex;
                //int drawOrderIndex = 0;
                for (int i = 0; i < triangleCount; i += 6, firstVertex += 4 /*, drawOrderIndex++*/)
                {
                    triangles[i]     = firstVertex;
                    triangles[i + 1] = firstVertex + 2;
                    triangles[i + 2] = firstVertex + 1;
                    triangles[i + 3] = firstVertex + 2;
                    triangles[i + 4] = firstVertex + 3;
                    triangles[i + 5] = firstVertex + 1;
                }
            }
            return;
        }

        // Iterate through all slots and store their triangles.
        ExposedList <Slot> drawOrder = skeleton.DrawOrder;
        int triangleIndex            = 0; // Modified by loop

        for (int i = submeshArguments.startSlot, n = submeshArguments.endSlot; i < n; i++)
        {
            Slot       slot       = drawOrder.Items[i];
            Attachment attachment = slot.attachment;

            bool flip = flipStates.Items[i];

            // Add RegionAttachment triangles
            if (attachment is RegionAttachment)
            {
                if (!flip)
                {
                    triangles[triangleIndex]     = firstVertex;
                    triangles[triangleIndex + 1] = firstVertex + 2;
                    triangles[triangleIndex + 2] = firstVertex + 1;
                    triangles[triangleIndex + 3] = firstVertex + 2;
                    triangles[triangleIndex + 4] = firstVertex + 3;
                    triangles[triangleIndex + 5] = firstVertex + 1;
                }
                else
                {
                    triangles[triangleIndex]     = firstVertex + 1;
                    triangles[triangleIndex + 1] = firstVertex + 2;
                    triangles[triangleIndex + 2] = firstVertex;
                    triangles[triangleIndex + 3] = firstVertex + 1;
                    triangles[triangleIndex + 4] = firstVertex + 3;
                    triangles[triangleIndex + 5] = firstVertex + 2;
                }

                triangleIndex += 6;
                firstVertex   += 4;
                continue;
            }

            // Add (Skinned)MeshAttachment triangles
            int[]          attachmentTriangles;
            int            attachmentVertexCount;
            MeshAttachment meshAttachment = attachment as MeshAttachment;
            if (meshAttachment != null)
            {
                attachmentVertexCount = meshAttachment.vertices.Length >> 1;                 //  length/2
                attachmentTriangles   = meshAttachment.triangles;
            }
            else
            {
                SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment;
                if (skinnedMeshAttachment != null)
                {
                    attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1;                     // length/2
                    attachmentTriangles   = skinnedMeshAttachment.triangles;
                }
                else
                {
                    continue;
                }
            }

            if (flip)
            {
                for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii += 3, triangleIndex += 3)
                {
                    triangles[triangleIndex + 2] = firstVertex + attachmentTriangles[ii];
                    triangles[triangleIndex + 1] = firstVertex + attachmentTriangles[ii + 1];
                    triangles[triangleIndex]     = firstVertex + attachmentTriangles[ii + 2];
                }
            }
            else
            {
                for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++)
                {
                    triangles[triangleIndex] = firstVertex + attachmentTriangles[ii];
                }
            }

            firstVertex += attachmentVertexCount;
        }
    }
예제 #16
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;
    }
예제 #17
0
        /// <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);
                }
            }
        }
예제 #18
0
    public virtual void Reset()
    {
        if (meshFilter != null)
        {
            meshFilter.sharedMesh = null;
        }
        if (mesh != null)
        {
            DestroyImmediate(mesh);
        }
        if (renderer != null)
        {
            renderer.sharedMaterial = null;
        }
        mesh            = null;
        mesh1           = null;
        mesh2           = null;
        lastVertexCount = 0;
        vertices        = null;
        colors          = null;
        uvs             = null;
        sharedMaterials = new Material[0];
        submeshMaterials.Clear();
        submeshes.Clear();
        skeleton = null;

        valid = false;
        if (!skeletonDataAsset)
        {
            if (logErrors)
            {
                Debug.LogError("Missing SkeletonData asset.", this);
            }

            return;
        }
        SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);

        if (skeletonData == null)
        {
            return;
        }
        valid = true;

        meshFilter = GetComponent <MeshFilter>();
        mesh1      = newMesh();
        mesh2      = newMesh();
        vertices   = new Vector3[0];

        skeleton = new Skeleton(skeletonData);
        if (initialSkinName != null && initialSkinName.Length > 0 && initialSkinName != "default")
        {
            skeleton.SetSkin(initialSkinName);
        }
        if (OnReset != null)
        {
            OnReset(this);
        }

        /*实例化新的材质,避免应用颜色被影响*/
        List <Slot> drawOrder      = skeleton.DrawOrder;
        int         drawOrderCount = drawOrder.Count;
        bool        renderMeshes   = this.renderMeshes;

        materialMap.Clear();
        for (int i = 0; i < drawOrderCount; i++)
        {
            Slot       slot       = drawOrder[i];
            Attachment attachment = slot.attachment;
            if (attachment == null)
            {
                continue;
            }
            object rendererObject;
            if (attachment is RegionAttachment)
            {
                rendererObject = ((RegionAttachment)attachment).RendererObject;
            }
            else
            {
                if (!renderMeshes)
                {
                    continue;
                }
                if (attachment is MeshAttachment)
                {
                    MeshAttachment meshAttachment = (MeshAttachment)attachment;
                    rendererObject = meshAttachment.RendererObject;
                }
                else if (attachment is SkinnedMeshAttachment)
                {
                    SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
                    rendererObject = meshAttachment.RendererObject;
                }
                else
                {
                    continue;
                }
            }
            AtlasRegion region = (AtlasRegion)rendererObject;
            newMaterial((Material)region.page.rendererObject);
        }
    }
예제 #19
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);
                        }
                    }
                }
            }
        }
예제 #20
0
    /** Stores vertices and triangles for a single material. */
    private void AddSubmesh(Material material, int startSlot, int endSlot, int triangleCount, int firstVertex, bool lastSubmesh)
    {
        int submeshIndex = submeshMaterials.Count;

        submeshMaterials.Add(material);

        if (submeshes.Count <= submeshIndex)
        {
            submeshes.Add(new Submesh());
        }
        else if (immutableTriangles)
        {
            return;
        }

        Submesh submesh = submeshes[submeshIndex];

        int[] triangles         = submesh.triangles;
        int   trianglesCapacity = triangles.Length;

        if (lastSubmesh && trianglesCapacity > triangleCount)
        {
            // Last submesh may have more triangles than required, so zero triangles to the end.
            for (int i = triangleCount; i < trianglesCapacity; i++)
            {
                triangles[i] = 0;
            }
            submesh.triangleCount = triangleCount;
        }
        else if (trianglesCapacity != triangleCount)
        {
            // Reallocate triangles when not the exact size needed.
            submesh.triangles     = triangles = new int[triangleCount];
            submesh.triangleCount = 0;
        }

        if (!renderMeshes)
        {
            // Use stored triangles if possible.
            if (submesh.firstVertex != firstVertex || submesh.triangleCount < triangleCount)
            {
                submesh.triangleCount = triangleCount;
                submesh.firstVertex   = firstVertex;
                for (int i = 0; i < triangleCount; i += 6, firstVertex += 4)
                {
                    triangles[i]     = firstVertex;
                    triangles[i + 1] = firstVertex + 2;
                    triangles[i + 2] = firstVertex + 1;
                    triangles[i + 3] = firstVertex + 2;
                    triangles[i + 4] = firstVertex + 3;
                    triangles[i + 5] = firstVertex + 1;
                }
            }
            return;
        }

        // Store triangles.
        List <Slot> drawOrder = skeleton.DrawOrder;

        for (int i = startSlot, triangleIndex = 0; i < endSlot; i++)
        {
            Attachment attachment = drawOrder[i].attachment;
            if (attachment is RegionAttachment)
            {
                triangles[triangleIndex]     = firstVertex;
                triangles[triangleIndex + 1] = firstVertex + 2;
                triangles[triangleIndex + 2] = firstVertex + 1;
                triangles[triangleIndex + 3] = firstVertex + 2;
                triangles[triangleIndex + 4] = firstVertex + 3;
                triangles[triangleIndex + 5] = firstVertex + 1;
                triangleIndex += 6;
                firstVertex   += 4;
                continue;
            }
            int[] attachmentTriangles;
            int   attachmentVertexCount;
            if (attachment is MeshAttachment)
            {
                MeshAttachment meshAttachment = (MeshAttachment)attachment;
                attachmentVertexCount = meshAttachment.vertices.Length >> 1;
                attachmentTriangles   = meshAttachment.triangles;
            }
            else if (attachment is SkinnedMeshAttachment)
            {
                SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
                attachmentVertexCount = meshAttachment.uvs.Length >> 1;
                attachmentTriangles   = meshAttachment.triangles;
            }
            else
            {
                continue;
            }
            for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++)
            {
                triangles[triangleIndex] = firstVertex + attachmentTriangles[ii];
            }
            firstVertex += attachmentVertexCount;
        }
    }
예제 #21
0
        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;
                    }
                }
            }
        }