Esempio n. 1
0
 /// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary>
 public static void SetScale(this RegionAttachment regionAttachment, Vector2 scale)
 {
     regionAttachment.scaleX = scale.x;
     regionAttachment.scaleY = scale.y;
 }
Esempio n. 2
0
 /// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary>
 public static void SetPositionOffset(this RegionAttachment regionAttachment, Vector2 offset)
 {
     regionAttachment.x = offset.x;
     regionAttachment.y = offset.y;
 }
Esempio n. 3
0
        public RegionAttachment NewRegionAttachment(Skin skin, string name, string path)
        {
            RegionAttachment attachment = new RegionAttachment(name);

            Texture2D   tex        = sprite.texture;
            int         instanceId = tex.GetInstanceID();
            AtlasRegion atlasRegion;

            //check cache first
            if (atlasTable.ContainsKey(instanceId))
            {
                atlasRegion = atlasTable[instanceId];
            }
            else
            {
                //Setup new material
                Material mat = new Material(shader);
                if (sprite.packed)
                {
                    mat.name = "Unity Packed Sprite Material";
                }
                else
                {
                    mat.name = sprite.name + " Sprite Material";
                }
                mat.mainTexture = tex;

                //create faux-region to play nice with SkeletonRenderer
                atlasRegion = new AtlasRegion();
                AtlasPage page = new AtlasPage();
                page.rendererObject = mat;
                atlasRegion.page    = page;

                //cache it
                atlasTable[instanceId] = atlasRegion;
            }

            Rect texRect = sprite.textureRect;

            //normalize rect to UV space of packed atlas
            texRect.x      = Mathf.InverseLerp(0, tex.width, texRect.x);
            texRect.y      = Mathf.InverseLerp(0, tex.height, texRect.y);
            texRect.width  = Mathf.InverseLerp(0, tex.width, texRect.width);
            texRect.height = Mathf.InverseLerp(0, tex.height, texRect.height);

            Bounds  bounds = sprite.bounds;
            Vector3 size   = bounds.size;

            //TODO: make sure this rotation thing actually works
            bool rotated = false;

            if (sprite.packed)
            {
                rotated = sprite.packingRotation == SpritePackingRotation.Any;
            }

            //do some math and assign UVs and sizes
            attachment.SetUVs(texRect.xMin, texRect.yMax, texRect.xMax, texRect.yMin, rotated);
            attachment.RendererObject = atlasRegion;
            attachment.SetColor(Color.white);
            attachment.ScaleX               = 1;
            attachment.ScaleY               = 1;
            attachment.RegionOffsetX        = sprite.rect.width * (0.5f - Mathf.InverseLerp(bounds.min.x, bounds.max.x, 0)) / sprite.pixelsPerUnit;
            attachment.RegionOffsetY        = sprite.rect.height * (0.5f - Mathf.InverseLerp(bounds.min.y, bounds.max.y, 0)) / sprite.pixelsPerUnit;
            attachment.Width                = size.x;
            attachment.Height               = size.y;
            attachment.RegionWidth          = size.x;
            attachment.RegionHeight         = size.y;
            attachment.RegionOriginalWidth  = size.x;
            attachment.RegionOriginalHeight = size.y;
            attachment.UpdateOffset();

            return(attachment);
        }
    public virtual void Update()
    {
        // Clear fields if missing information to render.
        if (skeletonDataAsset == null || skeletonDataAsset.GetSkeletonData(false) == null)
        {
            Clear();
            return;
        }

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

        UpdateSkeleton();

        // Count quads.
        int         quadCount = 0;
        List <Slot> drawOrder = skeleton.DrawOrder;

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

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

        if (newTriangles)
        {
            // Not enough vertices, increase size.
            this.vertices = vertices = new Vector3[vertexCount];
            colors        = new Color32[vertexCount];
            uvs           = new Vector2[vertexCount];
            triangles     = new int[quadCount * 6];
            mesh.Clear();

            for (int i = 0, n = quadCount; i < n; i++)
            {
                int index  = i * 6;
                int vertex = i * 4;
                triangles[index]     = vertex;
                triangles[index + 1] = vertex + 2;
                triangles[index + 2] = vertex + 1;
                triangles[index + 3] = vertex + 2;
                triangles[index + 4] = vertex + 3;
                triangles[index + 5] = vertex + 1;
            }
        }
        else
        {
            // Too many vertices, zero the extra.
            Vector3 zero = new Vector3(0, 0, 0);
            for (int i = vertexCount, n = lastVertexCount; i < n; i++)
            {
                vertices[i] = zero;
            }
        }
        lastVertexCount = vertexCount;

        // Setup mesh.
        float[] vertexPositions = this.vertexPositions;
        int     vertexIndex     = 0;
        Color32 color           = new Color32();

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

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

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

            color.a                 = (byte)(skeleton.A * slot.A * 255);
            color.r                 = (byte)(skeleton.R * slot.R * color.a);
            color.g                 = (byte)(skeleton.G * slot.G * color.a);
            color.b                 = (byte)(skeleton.B * slot.B * color.a);
            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], 1 - regionUVs[RegionAttachment.Y1]);
            uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], 1 - regionUVs[RegionAttachment.Y4]);
            uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], 1 - regionUVs[RegionAttachment.Y2]);
            uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], 1 - regionUVs[RegionAttachment.Y3]);

            vertexIndex += 4;
        }
        mesh.vertices = vertices;
        mesh.colors32 = colors;
        mesh.uv       = uvs;
        if (newTriangles)
        {
            mesh.triangles = triangles;
        }
    }
Esempio n. 5
0
        public virtual void LateUpdate()
        {
            if (!valid || (!meshRenderer.enabled && this.generateMeshOverride == null))
            {
                return;
            }
            ExposedList <Slot> drawOrder = skeleton.drawOrder;

            Slot[] items = drawOrder.Items;
            int    count = drawOrder.Count;
            bool   flag  = renderMeshes;

            SmartMesh.Instruction    instruction = currentInstructions;
            ExposedList <Attachment> attachments = instruction.attachments;

            attachments.Clear(clearArray: false);
            attachments.GrowIfNeeded(count);
            attachments.Count = count;
            Attachment[] items2 = instruction.attachments.Items;
            ExposedList <SubmeshInstruction> submeshInstructions = instruction.submeshInstructions;

            submeshInstructions.Clear(clearArray: false);
            bool     flag2            = customSlotMaterials.Count > 0;
            int      num              = 0;
            int      num2             = 0;
            int      num3             = 0;
            int      firstVertexIndex = 0;
            int      startSlot        = 0;
            Material material         = null;

            for (int i = 0; i < count; i++)
            {
                Slot             slot             = items[i];
                Attachment       attachment       = items2[i] = slot.attachment;
                RegionAttachment regionAttachment = attachment as RegionAttachment;
                object           rendererObject;
                int num4;
                int num5;
                if (regionAttachment != null)
                {
                    rendererObject = regionAttachment.RendererObject;
                    num4           = 4;
                    num5           = 6;
                }
                else
                {
                    if (!flag)
                    {
                        continue;
                    }
                    MeshAttachment meshAttachment = attachment as MeshAttachment;
                    if (meshAttachment == null)
                    {
                        continue;
                    }
                    rendererObject = meshAttachment.RendererObject;
                    num4           = meshAttachment.worldVerticesLength >> 1;
                    num5           = meshAttachment.triangles.Length;
                }
                Material value;
                if (flag2)
                {
                    if (!customSlotMaterials.TryGetValue(slot, out value))
                    {
                        value = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                    }
                }
                else
                {
                    value = (Material)((AtlasRegion)rendererObject).page.rendererObject;
                }
                bool flag3 = separatorSlots.Count > 0 && separatorSlots.Contains(slot);
                if (num > 0 && (material.GetInstanceID() != value.GetInstanceID() || flag3))
                {
                    submeshInstructions.Add(new SubmeshInstruction
                    {
                        skeleton         = skeleton,
                        material         = material,
                        startSlot        = startSlot,
                        endSlot          = i,
                        triangleCount    = num3,
                        firstVertexIndex = firstVertexIndex,
                        vertexCount      = num2,
                        forceSeparate    = flag3
                    });
                    num3             = 0;
                    num2             = 0;
                    firstVertexIndex = num;
                    startSlot        = i;
                }
                material = value;
                num3    += num5;
                num     += num4;
                num2    += num4;
            }
            if (num2 != 0)
            {
                submeshInstructions.Add(new SubmeshInstruction
                {
                    skeleton         = skeleton,
                    material         = material,
                    startSlot        = startSlot,
                    endSlot          = count,
                    triangleCount    = num3,
                    firstVertexIndex = firstVertexIndex,
                    vertexCount      = num2,
                    forceSeparate    = false
                });
            }
            instruction.vertexCount        = num;
            instruction.immutableTriangles = immutableTriangles;
            if (customMaterialOverride.Count > 0)
            {
                SubmeshInstruction[] items3 = submeshInstructions.Items;
                for (int j = 0; j < submeshInstructions.Count; j++)
                {
                    Material material2 = items3[j].material;
                    Material value2;
                    if (customMaterialOverride.TryGetValue(material2, out value2))
                    {
                        items3[j].material = value2;
                    }
                }
            }
            if (this.generateMeshOverride != null)
            {
                this.generateMeshOverride(instruction);
                if (disableRenderingOnOverride)
                {
                    return;
                }
            }
            if (ArraysMeshGenerator.EnsureSize(num, ref vertices, ref uvs, ref colors) && calculateNormals)
            {
                Vector3[] array  = normals = new Vector3[num];
                Vector3   vector = new Vector3(0f, 0f, -1f);
                for (int k = 0; k < num; k++)
                {
                    array[k] = vector;
                }
            }
            Vector3 boundsMin = default(Vector3);
            Vector3 boundsMax = default(Vector3);

            if (num <= 0)
            {
                boundsMin = new Vector3(0f, 0f, 0f);
                boundsMax = new Vector3(0f, 0f, 0f);
            }
            else
            {
                boundsMin.x = 2.14748365E+09f;
                boundsMin.y = 2.14748365E+09f;
                boundsMax.x = -2.14748365E+09f;
                boundsMax.y = -2.14748365E+09f;
                if (zSpacing > 0f)
                {
                    boundsMin.z = 0f;
                    boundsMax.z = zSpacing * (float)(count - 1);
                }
                else
                {
                    boundsMin.z = zSpacing * (float)(count - 1);
                    boundsMax.z = 0f;
                }
            }
            int vertexIndex = 0;

            ArraysMeshGenerator.FillVerts(skeleton, 0, count, zSpacing, pmaVertexColors, vertices, uvs, colors, ref vertexIndex, ref tempVertices, ref boundsMin, ref boundsMax, flag);
            SmartMesh next = doubleBufferedMesh.GetNext();
            Mesh      mesh = next.mesh;

            mesh.vertices = vertices;
            mesh.colors32 = colors;
            mesh.uv       = uvs;
            mesh.bounds   = ArraysMeshGenerator.ToBounds(boundsMin, boundsMax);
            SmartMesh.Instruction instructionUsed = next.instructionUsed;
            if (calculateNormals && instructionUsed.vertexCount < num)
            {
                mesh.normals = normals;
            }
            bool flag4  = CheckIfMustUpdateMeshStructure(instruction, instructionUsed);
            int  count2 = submeshInstructions.Count;

            if (flag4)
            {
                ExposedList <Material> exposedList = submeshMaterials;
                exposedList.Clear(clearArray: false);
                int count3 = submeshes.Count;
                if (submeshes.Capacity < count2)
                {
                    submeshes.Capacity = count2;
                }
                for (int l = count3; l < count2; l++)
                {
                    submeshes.Items[l] = new ArraysMeshGenerator.SubmeshTriangleBuffer(submeshInstructions.Items[l].triangleCount);
                }
                submeshes.Count = count2;
                bool flag5 = !instruction.immutableTriangles;
                int  m     = 0;
                int  num6  = count2 - 1;
                for (; m < count2; m++)
                {
                    SubmeshInstruction submeshInstruction = submeshInstructions.Items[m];
                    if (flag5 || m >= count3)
                    {
                        ArraysMeshGenerator.SubmeshTriangleBuffer submeshTriangleBuffer = submeshes.Items[m];
                        int triangleCount = submeshInstruction.triangleCount;
                        if (flag)
                        {
                            ArraysMeshGenerator.FillTriangles(ref submeshTriangleBuffer.triangles, skeleton, triangleCount, submeshInstruction.firstVertexIndex, submeshInstruction.startSlot, submeshInstruction.endSlot, m == num6);
                            submeshTriangleBuffer.triangleCount = triangleCount;
                        }
                        else
                        {
                            ArraysMeshGenerator.FillTrianglesQuads(ref submeshTriangleBuffer.triangles, ref submeshTriangleBuffer.triangleCount, ref submeshTriangleBuffer.firstVertex, submeshInstruction.firstVertexIndex, triangleCount, m == num6);
                        }
                    }
                    exposedList.Add(submeshInstruction.material);
                }
                mesh.subMeshCount = count2;
                for (int n = 0; n < count2; n++)
                {
                    mesh.SetTriangles(submeshes.Items[n].triangles, n);
                }
            }
            if (calculateTangents)
            {
                ArraysMeshGenerator.SolveTangents2DEnsureSize(ref tangents, ref tempTanBuffer, vertices.Length);
                for (int num7 = 0; num7 < count2; num7++)
                {
                    ArraysMeshGenerator.SubmeshTriangleBuffer submeshTriangleBuffer2 = submeshes.Items[num7];
                    ArraysMeshGenerator.SolveTangents2DTriangles(tempTanBuffer, submeshTriangleBuffer2.triangles, submeshTriangleBuffer2.triangleCount, vertices, uvs, num);
                }
                ArraysMeshGenerator.SolveTangents2DBuffer(tangents, tempTanBuffer, num);
                mesh.tangents = tangents;
            }
            Material[] array2 = sharedMaterials;
            bool       flag6  = flag4 || array2.Length != count2;

            if (!flag6)
            {
                SubmeshInstruction[] items4 = submeshInstructions.Items;
                int num8 = 0;
                for (int num9 = array2.Length; num8 < num9; num8++)
                {
                    if (array2[num8].GetInstanceID() != items4[num8].material.GetInstanceID())
                    {
                        flag6 = true;
                        break;
                    }
                }
            }
            if (flag6)
            {
                if (submeshMaterials.Count == sharedMaterials.Length)
                {
                    submeshMaterials.CopyTo(sharedMaterials);
                }
                else
                {
                    sharedMaterials = submeshMaterials.ToArray();
                }
                meshRenderer.sharedMaterials = sharedMaterials;
            }
            meshFilter.sharedMesh = mesh;
            next.instructionUsed.Set(instruction);
        }
    public virtual void Draw()
    {
        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.
#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 != material && lastMaterial != null) || submeshSeparatorSlots.Contains(slot))
            {
                AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
                submeshTriangleCount  = 0;
                submeshFirstVertex    = vertexCount;
                submeshStartSlotIndex = i;
            }
            lastMaterial = material;            //new Material(material);

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

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

        // 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.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]     = 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)
                    {
                        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++)
                    {
                        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)
                    {
                        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++)
                    {
                        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.mesh = 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;
            }
        }

        if (submeshRenderers.Length > 0)
        {
            foreach (var submeshRenderer in submeshRenderers)
            {
                if (submeshRenderer.submeshIndex < mMats.Length)
                {
                    submeshRenderer.SetMesh(mRenderer, useMesh1 ? mesh1 : mesh2, mMats[submeshRenderer.submeshIndex]);
                }
                else
                {
                    submeshRenderer.GetComponent <Renderer>().enabled = false;
                }
            }
        }

        useMesh1 = !useMesh1;
    }
    public Attachment NewAttachment(Skin skin, AttachmentType type, String name)
    {
        if (type != AttachmentType.region)
        {
            throw new Exception("Unknown attachment type: " + type);
        }

        // Strip folder names.
        int index = name.LastIndexOfAny(new char[] { '/', '\\' });

        if (index != -1)
        {
            name = name.Substring(index + 1);
        }

        tk2dSpriteDefinition attachmentParameters = null;

        for (int i = 0; i < sprites.inst.spriteDefinitions.Length; ++i)
        {
            tk2dSpriteDefinition def = sprites.inst.spriteDefinitions[i];
            if (def.name == name)
            {
                attachmentParameters = def;
                break;
            }
        }

        if (attachmentParameters == null)
        {
            throw new Exception("Sprite not found in atlas: " + name + " (" + type + ")");
        }
        if (attachmentParameters.complexGeometry)
        {
            throw new NotImplementedException("Complex geometry is not supported: " + name + " (" + type + ")");
        }
        if (attachmentParameters.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW)
        {
            throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name + " (" + type + ")");
        }

        Vector2 minTexCoords = Vector2.one;
        Vector2 maxTexCoords = Vector2.zero;

        for (int i = 0; i < attachmentParameters.uvs.Length; ++i)
        {
            Vector2 uv = attachmentParameters.uvs[i];
            minTexCoords = Vector2.Min(minTexCoords, uv);
            maxTexCoords = Vector2.Max(maxTexCoords, uv);
        }

        Texture texture = attachmentParameters.material.mainTexture;
        int     width   = (int)(Mathf.Abs(maxTexCoords.x - minTexCoords.x) * texture.width);
        int     height  = (int)(Mathf.Abs(maxTexCoords.y - minTexCoords.y) * texture.height);

        bool rotated = (attachmentParameters.flipped == tk2dSpriteDefinition.FlipMode.Tk2d);

        if (rotated)
        {
            float temp = minTexCoords.x;
            minTexCoords.x = maxTexCoords.x;
            maxTexCoords.x = temp;
        }

        RegionAttachment attachment = new RegionAttachment(name);

        attachment.SetUVs(
            minTexCoords.x,
            maxTexCoords.y,
            maxTexCoords.x,
            minTexCoords.y,
            rotated
            );

        // TODO - Set attachment.RegionOffsetX/Y. What units does attachmentParameters.untrimmedBoundsData use?!
        attachment.RegionWidth          = width;
        attachment.RegionHeight         = height;
        attachment.RegionOriginalWidth  = width;
        attachment.RegionOriginalHeight = height;

        return(attachment);
    }
        /// <summary>
        /// Allows to perform custom drawing.
        /// </summary>
        /// <param name="gameTime">The elapsed game time.</param>
        public override void Draw(TimeSpan gameTime)
        {
            if (this.SkeletalData.Atlas == null || this.SkeletalAnimation.Skeleton == null)
            {
                return;
            }

            float opacity = this.Transform2D.GlobalOpacity;

            if (this.RenderManager.ShouldDrawFlag(Framework.Managers.DebugLinesFlags.DebugAlphaOpacity))
            {
                opacity *= DebugAlpha;
            }

            int numVertices   = 0;
            int numPrimitives = 0;

            VertexPositionColorTexture tempVertex;
            StandardMaterial           material = null;

            // Process Mesh
            for (int i = 0; i < this.drawOrder.Count; i++)
            {
                var slot       = this.drawOrder.Items[i];
                var attachment = slot.Attachment;
                var skeleton   = this.SkeletalAnimation.Skeleton;

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

                    byte a = (byte)(skeleton.A * 255 * slot.A * regionAttachment.A * opacity);
                    byte r = (byte)(skeleton.R * slot.R * regionAttachment.R * a);
                    byte g = (byte)(skeleton.G * slot.G * regionAttachment.G * a);
                    byte b = (byte)(skeleton.B * slot.B * regionAttachment.B * a);

                    if (slot.Data.BlendMode == SpineBlendMode.additive)
                    {
                        a = 0;
                    }

                    Color color = new Color(r, g, b, a);

                    float[] uvs = regionAttachment.UVs;

                    var region = (AtlasRegion)regionAttachment.RendererObject;
                    material = (StandardMaterial)region.page.rendererObject;

                    var computedVertices = this.ComputeAttachmentVertices(regionAttachment, slot);
                    this.vertices = new VertexPositionColorTexture[4];

                    // Vertex TL
                    tempVertex.Position   = computedVertices[0];
                    tempVertex.Color      = color;
                    tempVertex.TexCoord.X = uvs[RegionAttachment.X1];
                    tempVertex.TexCoord.Y = uvs[RegionAttachment.Y1];
                    this.vertices[0]      = tempVertex;

                    // Vertex TR
                    tempVertex.Position   = computedVertices[1];
                    tempVertex.Color      = color;
                    tempVertex.TexCoord.X = uvs[RegionAttachment.X4];
                    tempVertex.TexCoord.Y = uvs[RegionAttachment.Y4];
                    this.vertices[1]      = tempVertex;

                    // Vertex BR
                    tempVertex.Position   = computedVertices[2];
                    tempVertex.Color      = color;
                    tempVertex.TexCoord.X = uvs[RegionAttachment.X3];
                    tempVertex.TexCoord.Y = uvs[RegionAttachment.Y3];
                    this.vertices[2]      = tempVertex;

                    // Vertex BL
                    tempVertex.Position   = computedVertices[3];
                    tempVertex.Color      = color;
                    tempVertex.TexCoord.X = uvs[RegionAttachment.X2];
                    tempVertex.TexCoord.Y = uvs[RegionAttachment.Y2];
                    this.vertices[3]      = tempVertex;

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

                    byte a = (byte)(skeleton.A * 255 * slot.A * mesh.A * opacity);
                    byte r = (byte)(skeleton.R * slot.R * mesh.R * a);
                    byte g = (byte)(skeleton.G * slot.G * mesh.G * a);
                    byte b = (byte)(skeleton.B * slot.B * mesh.B * a);

                    if (slot.Data.BlendMode == SpineBlendMode.additive)
                    {
                        a = 0;
                    }

                    Color color = new Color(r, g, b, a);

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

                    var region = (AtlasRegion)mesh.RendererObject;
                    material = (StandardMaterial)region.page.rendererObject;

                    var computedVertices = this.ComputeAttachmentVertices(mesh, slot);
                    this.vertices = new VertexPositionColorTexture[numVertices / 2];

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

                    byte a = (byte)(skeleton.A * 255 * slot.A * mesh.A * opacity);
                    byte r = (byte)(skeleton.R * slot.R * mesh.R * a);
                    byte g = (byte)(skeleton.G * slot.G * mesh.G * a);
                    byte b = (byte)(skeleton.B * slot.B * mesh.B * a);

                    if (slot.Data.BlendMode == SpineBlendMode.additive)
                    {
                        a = 0;
                    }

                    Color color = new Color(r, g, b, a);

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

                    var computedVertices = this.ComputeAttachmentVertices(mesh, slot);

                    var region = (AtlasRegion)mesh.RendererObject;
                    material = (StandardMaterial)region.page.rendererObject;

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

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

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

                    if (this.spineMeshes[i] != null)
                    {
                        if (this.spineMeshes[i].VertexBuffer.VertexCount != this.vertices.Length ||
                            this.spineMeshes[i].IndexBuffer.Data.Length != this.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(this.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 - (i * this.ZOrderBias);
                    mesh.DisableBatch = true;

                    material.LayerId = this.LayerId;

                    Matrix worldTransform = this.Transform2D.WorldTransform;
                    this.RenderManager.DrawMesh(mesh, material, ref worldTransform, false);
                }
            }
        }
    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;
    }
Esempio n. 10
0
    public override 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();
        }
//			GetComponent<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 [X1], tempVertices [Y1], z);
                vertices [vertexIndex + 1] = new Vector3(tempVertices [X2], tempVertices [Y2], z);
                vertices [vertexIndex + 2] = new Vector3(tempVertices [X3], tempVertices [Y3], z);
                vertices [vertexIndex + 3] = new Vector3(tempVertices [X4], tempVertices [Y4], 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 [X1], regionUVs [Y1]);
                uvs [vertexIndex + 1] = new Vector2(regionUVs [X2], regionUVs [Y2]);
                uvs [vertexIndex + 2] = new Vector2(regionUVs [X3], regionUVs [Y3]);
                uvs [vertexIndex + 3] = new Vector2(regionUVs [X4], regionUVs [Y4]);

                vertexIndex += 4;
            }
            else
            {
                if (!renderMeshes)
                {
                    continue;
                }
                if (attachment is MeshAttachment)
                {
                    MeshAttachment meshAttachment  = (MeshAttachment)attachment;
                    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.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)
                    {
                        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.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]);
                    }
                }
            }
        }

        if (fillDrawCall != null)
        {
            fillDrawCall(vertices, colors, uvs);
        }
    }
Esempio n. 11
0
    public Attachment NewAttachment(Skin skin, AttachmentType type, String name)
    {
        switch (type)
        {
        case AttachmentType.region:
            break;

        case AttachmentType.boundingbox:
            return(new BoundingBoxAttachment(name));

        default:
            throw new Exception("Unknown attachment type: " + type);
        }

        // Strip folder names.
        int index = name.LastIndexOfAny(new char[] { '/', '\\' });

        if (index != -1)
        {
            name = name.Substring(index + 1);
        }

        tk2dSpriteDefinition def = sprites.inst.GetSpriteDefinition(name);

        if (def == null)
        {
            throw new Exception("Sprite not found in atlas: " + name + " (" + type + ")");
        }
        if (def.complexGeometry)
        {
            throw new NotImplementedException("Complex geometry is not supported: " + name + " (" + type + ")");
        }
        if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW)
        {
            throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name + " (" + type + ")");
        }

        RegionAttachment attachment = new RegionAttachment(name);

        Vector2 minTexCoords = Vector2.one;
        Vector2 maxTexCoords = Vector2.zero;

        for (int i = 0; i < def.uvs.Length; ++i)
        {
            Vector2 uv = def.uvs[i];
            minTexCoords = Vector2.Min(minTexCoords, uv);
            maxTexCoords = Vector2.Max(maxTexCoords, uv);
        }
        bool rotated = def.flipped == tk2dSpriteDefinition.FlipMode.Tk2d;

        if (rotated)
        {
            float temp = minTexCoords.x;
            minTexCoords.x = maxTexCoords.x;
            maxTexCoords.x = temp;
        }
        attachment.SetUVs(
            minTexCoords.x,
            maxTexCoords.y,
            maxTexCoords.x,
            minTexCoords.y,
            rotated
            );

        attachment.RegionOriginalWidth  = (int)(def.untrimmedBoundsData[1].x / def.texelSize.x);
        attachment.RegionOriginalHeight = (int)(def.untrimmedBoundsData[1].y / def.texelSize.y);

        attachment.RegionWidth  = (int)(def.boundsData[1].x / def.texelSize.x);
        attachment.RegionHeight = (int)(def.boundsData[1].y / def.texelSize.y);

        float x0 = def.untrimmedBoundsData[0].x - def.untrimmedBoundsData[1].x / 2;
        float x1 = def.boundsData[0].x - def.boundsData[1].x / 2;

        attachment.RegionOffsetX = (int)((x1 - x0) / def.texelSize.x);

        float y0 = def.untrimmedBoundsData[0].y - def.untrimmedBoundsData[1].y / 2;
        float y1 = def.boundsData[0].y - def.boundsData[1].y / 2;

        attachment.RegionOffsetY = (int)((y1 - y0) / def.texelSize.y);

        attachment.RendererObject = def.material;

        return(attachment);
    }
Esempio n. 12
0
    /*
     */
    private void UpdateMesh()
    {
        int   quadIndex    = 0;
        int   drawCount    = skeleton.DrawOrder.Count;
        Color currentColor = new Color();

        for (int i = 0; i < drawCount; i++)
        {
            Slot       slot       = skeleton.DrawOrder[i];
            Attachment attachment = slot.Attachment;

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

                regionAttachment.ComputeVertices(slot.Bone, vertexPositions);
                int vertexIndex = quadIndex * 4;

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

                float[] regionUVs = regionAttachment.UVs;
                uvs[vertexIndex + 0] = 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]);

                currentColor.a = skeleton.A * slot.A;
                currentColor.r = skeleton.R * slot.R * slot.A;
                currentColor.g = skeleton.G * slot.G * slot.A;
                currentColor.b = skeleton.B * slot.B * slot.A;

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

                int index = quadIndex * 6;
                triangles[index + 0] = vertexIndex;
                triangles[index + 1] = vertexIndex + 2;
                triangles[index + 2] = vertexIndex + 1;
                triangles[index + 3] = vertexIndex + 2;
                triangles[index + 4] = vertexIndex + 3;
                triangles[index + 5] = vertexIndex + 1;

                quadIndex++;
            }
        }

        mesh.Clear();

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

        if (skeletonDataAsset.normalGenerationMode != tk2dSpriteCollection.NormalGenerationMode.None)
        {
            mesh.RecalculateNormals();

            if (skeletonDataAsset.normalGenerationMode == tk2dSpriteCollection.NormalGenerationMode.NormalsAndTangents)
            {
                Vector4[] tangents = new Vector4[mesh.normals.Length];
                for (int t = 0; t < tangents.Length; ++t)
                {
                    tangents[t] = new Vector4(1, 0, 0, 1);
                }
                mesh.tangents = tangents;
            }
        }

        renderer.sharedMaterial = skeletonDataAsset.spritesData.inst.materials[0];
    }
Esempio n. 13
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);
                        }
                    }
                }
            }
        }
Esempio n. 14
0
 /// <summary> Sets the rotation. Call regionAttachment.UpdateOffset to apply the change.</summary>
 public static void SetRotation(this RegionAttachment regionAttachment, float rotation)
 {
     regionAttachment.rotation = rotation;
 }
        // RegionAttachment
        protected void AddAttachment(Slot slot, RegionAttachment attachment)
        {
            var tempVertices = this.tempVertices;
            attachment.ComputeWorldVertices(slot.bone, tempVertices);

            float[] regionUVs = attachment.uvs;

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

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

            AddTriangle(fv, fv+2, fv+1);
            AddTriangle(fv+2, fv+3, fv+1);
        }
		/// <summary>
		/// Creates a new RegionAttachment from a given AtlasRegion.</summary>
		public static RegionAttachment ToRegionAttachment (this AtlasRegion region, string attachmentName, float scale = 0.01f) {
			if (string.IsNullOrEmpty(attachmentName)) throw new System.ArgumentException("attachmentName can't be null or empty.", "attachmentName");
			if (region == null) throw new System.ArgumentNullException("region");

			// (AtlasAttachmentLoader.cs)
			var attachment = new RegionAttachment(attachmentName);

			attachment.RendererObject = region;
			attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate);
			attachment.regionOffsetX = region.offsetX;
			attachment.regionOffsetY = region.offsetY;
			attachment.regionWidth = region.width;
			attachment.regionHeight = region.height;
			attachment.regionOriginalWidth = region.originalWidth;
			attachment.regionOriginalHeight = region.originalHeight;

			attachment.Path = region.name;
			attachment.scaleX = 1;
			attachment.scaleY = 1;
			attachment.rotation = 0;

			// pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation.
			attachment.width = attachment.regionOriginalWidth * scale;
			attachment.height = attachment.regionOriginalHeight * scale;

			attachment.SetColor(Color.white);
			attachment.UpdateOffset();
			return attachment;
		}
Esempio n. 17
0
        public virtual void LateUpdate()
        {
            if (!valid)
            {
                return;
            }

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

            if (
                (
                    !meshRenderer.enabled

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

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

                )
            {
                return;
            }



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

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

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

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

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

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

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

                workingAttachmentsItems[i] = attachment;

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

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

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

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

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

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

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

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

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

            workingInstruction.vertexCount        = vertexCount;
            workingInstruction.immutableTriangles = this.immutableTriangles;
                        #if SPINE_OPTIONAL_FRONTFACING
            workingInstruction.frontFacing = this.frontFacing;
                        #endif

            // STEP 1.9. Post-process workingInstructions.

                        #if SPINE_OPTIONAL_MATERIALOVERRIDE
            // Material overrides are done here so they can be applied per submesh instead of per slot
            // but they will still be passed through the GenerateMeshOverride delegate,
            // and will still go through the normal material match check step in STEP 3.
            if (customMaterialOverride.Count > 0)               // isCustomMaterialOverridePopulated
            {
                var workingSubmeshInstructionsItems = workingSubmeshInstructions.Items;
                for (int i = 0; i < workingSubmeshInstructions.Count; i++)
                {
                    var      m = workingSubmeshInstructionsItems[i].material;
                    Material mo;
                    if (customMaterialOverride.TryGetValue(m, out mo))
                    {
                        workingSubmeshInstructionsItems[i].material = mo;
                    }
                }
            }
                        #endif

                        #if SPINE_OPTIONAL_RENDEROVERRIDE
            if (this.generateMeshOverride != null)
            {
                this.generateMeshOverride(workingInstruction);

                if (disableRenderingOnOverride)
                {
                    return;
                }
            }
                        #endif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                currentMesh.subMeshCount = submeshCount;

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

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

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

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

                    meshRenderer.sharedMaterials = sharedMaterials;
                }
            }

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


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

                        #if SPINE_OPTIONAL_SUBMESHRENDERER
            if (submeshRenderers.Length > 0)
            {
                for (int i = 0; i < submeshRenderers.Length; i++)
                {
                    var submeshRenderer = submeshRenderers[i];
                    if (submeshRenderer.submeshIndex < sharedMaterials.Length)
                    {
                        submeshRenderer.SetMesh(meshRenderer, currentMesh, sharedMaterials[submeshRenderer.submeshIndex]);
                    }
                    else
                    {
                        submeshRenderer.GetComponent <Renderer>().enabled = false;
                    }
                }
            }
                        #endif
        }
Esempio n. 18
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);
                    }
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        /// 主要逻辑copy SkeletonJson.ReadAttachment
        /// </summary>
        /// <param name="sdEX"></param>
        /// <param name="atlasArray"></param>
        /// <returns></returns>
        public Skin GenSkinBySkniDataAsset(SkinDataEx sdEX, Atlas[] atlasArray)
        {
#if SPINE_TK2D
            throw new NotImplementedException("GenSkinBySkniDataAsset Not Implemented");
#endif
            float      scale            = this.skeletonDataAsset.scale;
            var        attachmentLoader = new AtlasAttachmentLoader(atlasArray);
            var        skin             = new Skin(sdEX.SkinName);
            var        linkedMeshes     = new List <SkeletonJson.LinkedMesh>();
            Attachment attachment       = null;
            foreach (var slot in sdEX.AllSlots)
            {
                var slotIndex = skeleton.Data.FindSlotIndex(slot.SlotName);
                foreach (var entry in slot.AllAttachments)
                {
                    switch (entry.type)
                    {
                    case AttachmentType.Region:
                    {
                        RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, entry.AttachmentName, entry.PathName);
                        if (region == null)
                        {
                            Debug.LogError("RegionAttachment New Fail:" + entry.AttachmentName + "," + entry.PathName);
                            continue;
                        }
                        region.Path = entry.PathName;
                        #region Region数据的填充
                        CheckRegionData(entry.FloatValues);
                        Single w = 32, h = 32;
                        foreach (var f in entry.FloatValues)
                        {
                            switch (f.Key)
                            {
                            case "x":
                                region.x = f.FloatValue * scale;
                                break;

                            case "y":
                                region.y = f.FloatValue * scale;
                                break;

                            case "scaleX":
                                region.scaleX = f.FloatValue;
                                break;

                            case "scaleY":
                                region.scaleY = f.FloatValue;
                                break;

                            case "rotation":
                                region.rotation = f.FloatValue;
                                break;

                            case "width":
                                w = f.FloatValue;
                                break;

                            case "height":
                                h = f.FloatValue;
                                break;
                            }
                        }
                        region.width  = w * scale;
                        region.height = h * scale;
                        if (entry.ColorValues != null && entry.ColorValues.Count > 0)
                        {
                            foreach (var c in entry.ColorValues)
                            {
                                switch (c.Key)
                                {
                                case "color":
                                    region.r = c.ColorValue.r;
                                    region.g = c.ColorValue.g;
                                    region.b = c.ColorValue.b;
                                    region.a = c.ColorValue.a;
                                    break;
                                }
                            }
                        }
                        #endregion
                        region.UpdateOffset();
                        attachment = region;
                    }
                    break;

                    case AttachmentType.Boundingbox:
                    {
                        BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, entry.AttachmentName);
                        if (box == null)
                        {
                            Debug.LogError("BoundingBoxAttachment New Fail:" + entry.AttachmentName);
                            continue;
                        }
                        #region Box数据填充
                        Int32 vertexCount = 0;
                        if (entry.IntValues != null && entry.IntValues.Count > 0)
                        {
                            foreach (var i in entry.IntValues)
                            {
                                if (i.Key.Equals("vertexCount"))
                                {
                                    vertexCount = i.IntValue;
                                    break;
                                }
                            }
                        }
                        foreach (var fs in entry.FloatArrayValues)
                        {
                            if (fs.Key.Equals("vertices"))
                            {
                                ReadVertices(fs, box, vertexCount << 1, scale);
                                break;
                            }
                        }
                        #endregion
                        attachment = box;
                    }
                    break;

                    case AttachmentType.Mesh:
                    case AttachmentType.Linkedmesh:
                    {
                        MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, entry.AttachmentName, entry.PathName);
                        if (mesh == null)
                        {
                            Debug.LogError("MeshAttachment New Fail:" + entry.AttachmentName + "," + entry.PathName);
                            continue;
                        }
                        #region Mesh数据填充
                        mesh.Path = entry.PathName;
                        if (entry.ColorValues != null && entry.ColorValues.Count > 0)
                        {
                            foreach (var c in entry.ColorValues)
                            {
                                if (c.Key.Equals("color"))
                                {
                                    mesh.r = c.ColorValue.r;
                                    mesh.g = c.ColorValue.g;
                                    mesh.b = c.ColorValue.b;
                                    mesh.a = c.ColorValue.a;
                                    break;
                                }
                            }
                        }
                        Single w = 0, h = 0;
                        foreach (var f in entry.FloatValues)
                        {
                            switch (f.Key)
                            {
                            case "width":
                                w = f.FloatValue * scale;
                                break;

                            case "height":
                                h = f.FloatValue * scale;
                                break;
                            }
                        }
                        mesh.Width  = w;
                        mesh.Height = h;

                        String  parentStr = null, skinStr = null;
                        Boolean deform = true;
                        if (entry.StringValues != null && entry.StringValues.Count > 0)
                        {
                            foreach (var ss in entry.StringValues)
                            {
                                switch (ss.Key)
                                {
                                case "parent":
                                    parentStr = ss.StringValue;
                                    break;

                                case "skin":
                                    skinStr = ss.StringValue;
                                    break;
                                }
                            }
                        }
                        if (entry.BoolValues != null && entry.BoolValues.Count > 0)
                        {
                            foreach (var b in entry.BoolValues)
                            {
                                if (b.Key.Equals("deform"))
                                {
                                    deform = b.BooleanValue;
                                    break;
                                }
                            }
                        }
                        if (parentStr != null)
                        {
                            mesh.InheritDeform = deform;
                            linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinStr, slotIndex, parentStr));
                        }
                        KeyFloatArrayPair kfap_Vs = new KeyFloatArrayPair();
                        Single[]          uvs     = null;
                        foreach (var fs in entry.FloatArrayValues)
                        {
                            switch (fs.Key)
                            {
                            case "vertices":
                                kfap_Vs = fs;
                                break;

                            case "uvs":
                                uvs = fs.FloatArrayValue.ToArray();
                                break;
                            }
                        }
                        ReadVertices(kfap_Vs, mesh, uvs.Length, scale);
                        Int32[] triangles = null, edges = null;
                        if (entry.IntArrayValues != null && entry.IntArrayValues.Count > 0)
                        {
                            foreach (var i32s in entry.IntArrayValues)
                            {
                                switch (i32s.Key)
                                {
                                case "triangles":
                                    triangles = i32s.IntArrayValue.ToArray();
                                    break;

                                case "edges":
                                    edges = i32s.IntArrayValue.ToArray();
                                    break;
                                }
                            }
                        }

                        mesh.triangles = triangles;
                        mesh.regionUVs = uvs;
                        mesh.UpdateUVs();

                        Int32 hull = 0;
                        if (entry.IntValues != null && entry.IntValues.Count > 0)
                        {
                            foreach (var i in entry.IntValues)
                            {
                                if (i.Key.Equals("hull"))
                                {
                                    hull = i.IntValue * 2;
                                    break;
                                }
                            }
                        }
                        if (hull != 0)
                        {
                            mesh.HullLength = hull;
                        }
                        if (edges != null)
                        {
                            mesh.Edges = edges;
                        }
                        #endregion
                        attachment = mesh;
                    }
                    break;

                    case AttachmentType.Path:
                    {
                        PathAttachment pathAttachment = attachmentLoader.NewPathAttachment(skin, entry.AttachmentName);
                        if (pathAttachment == null)
                        {
                            Debug.LogError("PathAttachment New Fail:" + entry.AttachmentName);
                            continue;
                        }
                        #region Path填充数据
                        Boolean closed = false, constantSpeed = false;
                        if (entry.BoolValues != null && entry.BoolValues.Count > 0)
                        {
                            foreach (var b in entry.BoolValues)
                            {
                                switch (b.Key)
                                {
                                case "closed":
                                    closed = b.BooleanValue;
                                    break;

                                case "constantSpeed":
                                    constantSpeed = b.BooleanValue;
                                    break;
                                }
                            }
                        }
                        pathAttachment.closed        = closed;
                        pathAttachment.constantSpeed = constantSpeed;

                        Int32 vertexCount = 0;
                        if (entry.IntValues != null && entry.IntValues.Count > 0)
                        {
                            foreach (var i in entry.IntValues)
                            {
                                if (i.Key.Equals("vertexCount"))
                                {
                                    vertexCount = i.IntValue;
                                    break;
                                }
                            }
                        }
                        foreach (var fs in entry.FloatArrayValues)
                        {
                            switch (fs.Key)
                            {
                            case "vertices":
                                ReadVertices(fs, pathAttachment, vertexCount << 1, scale);
                                break;

                            case "lengths":
                                var count = fs.FloatArrayValue.Count;
                                pathAttachment.lengths = new Single[count];
                                for (var idx = 0; idx < count; idx++)
                                {
                                    pathAttachment.lengths[idx] = fs.FloatArrayValue[idx] * scale;
                                }
                                break;
                            }
                        }
                        #endregion
                        attachment = pathAttachment;
                    }
                    break;

                    case AttachmentType.Point:
                    {
                        PointAttachment point = attachmentLoader.NewPointAttachment(skin, entry.AttachmentName);
                        if (point == null)
                        {
                            Debug.LogError("PointAttachment New Fail:" + entry.AttachmentName);
                            continue;
                        }
                        #region Point填充数据
                        Single x = 0, y = 0, r = 0;
                        if (entry.FloatValues != null && entry.FloatValues.Count > 0)
                        {
                            foreach (var f in entry.FloatValues)
                            {
                                switch (f.Key)
                                {
                                case "x":
                                    x = f.FloatValue * scale;
                                    break;

                                case "y":
                                    y = f.FloatValue * scale;
                                    break;

                                case "rotation":
                                    r = f.FloatValue;
                                    break;
                                }
                            }
                        }
                        point.x        = x;
                        point.y        = y;
                        point.rotation = r;
                        #endregion
                        attachment = point;
                    }
                    break;

                    case AttachmentType.Clipping:
                    {
                        ClippingAttachment clip = attachmentLoader.NewClippingAttachment(skin, entry.AttachmentName);
                        if (clip == null)
                        {
                            Debug.LogError("ClippingAttachment New Fail:" + entry.AttachmentName);
                            continue;
                        }
                        #region Clipping填充数据
                        String end = null;
                        if (entry.StringValues != null && entry.StringValues.Count > 0)
                        {
                            foreach (var s in entry.StringValues)
                            {
                                if (s.Key.Equals("end"))
                                {
                                    end = s.StringValue;
                                    break;
                                }
                            }
                        }
                        if (end != null)
                        {
                            SlotData sd = skeleton.Data.FindSlot(end);
                            if (sd == null)
                            {
                                throw new Exception("Clipping end slot not found: " + end);
                            }
                            clip.EndSlot = sd;
                        }

                        Int32 vertexCount = 0;
                        if (entry.IntValues != null && entry.IntValues.Count > 0)
                        {
                            foreach (var i in entry.IntValues)
                            {
                                if (i.Key.Equals("vertexCount"))
                                {
                                    vertexCount = i.IntValue;
                                    break;
                                }
                            }
                        }
                        foreach (var fs in entry.FloatArrayValues)
                        {
                            if (fs.Key.Equals("vertices"))
                            {
                                ReadVertices(fs, clip, vertexCount << 1, scale);
                                break;
                            }
                        }
                        #endregion
                        attachment = clip;
                    }
                    break;

                    default:
                        break;
                    }
                    skin.SetAttachment(slot.SlotName, entry.AttachmentName, attachment, skeleton);
                }
            }
            // Linked meshes.
            for (int i = 0, n = linkedMeshes.Count; i < n; i++)
            {
                var  linkedMesh = linkedMeshes[i];
                Skin sk         = linkedMesh.skin == null ? skeleton.Data.defaultSkin : skeleton.Data.FindSkin(linkedMesh.skin);
                if (sk == null)
                {
                    throw new Exception("Slot not found: " + linkedMesh.skin);
                }
                Attachment parent = sk.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent);
                if (parent == null)
                {
                    throw new Exception("Parent mesh not found: " + linkedMesh.parent);
                }
                linkedMesh.mesh.ParentMesh = (MeshAttachment)parent;
                linkedMesh.mesh.UpdateUVs();
            }
            skeleton.Data.Skins.Add(skin);
            return(skin);
        }
 public static Color GetColor(this RegionAttachment a)
 {
     return(new Color(a.R, a.G, a.B, a.A));
 }
Esempio n. 21
0
        public static void FillVerts(Skeleton skeleton, int startSlot, int endSlot, float zSpacing, bool pmaColors, Vector3[] verts, Vector2[] uvs, Color32[] colors, ref int vertexIndex, ref float[] tempVertBuffer, ref Vector3 boundsMin, ref Vector3 boundsMax, bool renderMeshes = true)
        {
            Color32 color = new Color32(0, 0, 0, 0);

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

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

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

#if UNITY_EDITOR
        for (int i = 0; i < meshRender.sharedMaterials.Length; ++i)
        {
            meshRender.sharedMaterials[i].shader = Shader.Find(meshRender.sharedMaterial.shader.name);
        }
#endif

        // 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)
                    {
                        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.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)
                    {
                        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.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;

        ///如果要替换材质
        if (this.controllerMaterialByOut)
        {
            for (int i = 0; i < meshRender.sharedMaterials.Length; i++)
            {
                var texture       = meshRender.sharedMaterials[i].GetTexture("_MainTex");
                var alpha_texture = meshRender.sharedMaterials[i].GetTexture("_AlphaTex");
                this.repMaterials[i].SetTexture("_MainTex", texture);
                this.repMaterials[i].SetTexture("_AlphaTex", alpha_texture);
            }

            meshRender.sharedMaterials = this.repMaterials;
        }

        ///如果在 NGUI 中要动态改层级
        if (this.needControllerRenderQueue)
        {
            for (int i = 0; i < this.meshRender.sharedMaterials.Length; i++)
            {
                this.meshRender.sharedMaterials[i].renderQueue = renderQueue;
            }
        }
    }
    public virtual void Update()
    {
        if (skeletonDataAsset == null)
        {
            Clear();
            return;
        }

        SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);

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

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

        UpdateSkeleton(Time.deltaTime);

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

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

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

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

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

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

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

        meshFilter.sharedMesh = mesh;

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

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

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

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

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

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

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

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

            vertexIndex += 4;
        }

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

        int submeshCount = submeshMaterials.Count;

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

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

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

        useMesh1 = !useMesh1;
    }
Esempio n. 24
0
 public static Color GetColor(this RegionAttachment a)
 {
     return(new Color(a.r, a.g, a.b, a.a));
 }
Esempio n. 25
0
    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);
    }
Esempio n. 26
0
    public virtual void LateUpdate()
    {
        if (!valid)
        {
            return;
        }

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

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

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

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

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

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

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

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

        workingSubmeshArguments.Clear(false);

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

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

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

        bool isCustomMaterialsPopulated = customSlotMaterials.Count > 0;

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

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

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

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

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

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

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

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

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

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

            submeshTriangleCount += attachmentTriangleCount;
            vertexCount          += attachmentVertexCount;
        }


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

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

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

        // NOT ELSE

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

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

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

            meshRenderer.sharedMaterials = sharedMaterials;
        }


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        // Update previous state
        storedState.immutableTriangles = immutableTriangles;

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

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

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


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

        useMesh1 = !useMesh1;
    }
Esempio n. 27
0
    public void Update()
    {
        // Clear fields if missing information to render.
        if (skeletonDataAsset == null || skeletonDataAsset.GetSkeletonData(false) == null)
        {
            Clear();
            return;
        }

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

        // Keep AnimationState in sync with animationName and loop fields.
        if (animationName == null && state.Animation != null)
        {
            state.ClearAnimation();
        }
        else if (state.Animation == null || animationName != state.Animation.Name)
        {
            Spine.Animation animation = skeleton.Data.FindAnimation(animationName);
            if (animation != null)
            {
                state.SetAnimation(animation, loop);
            }
        }
        state.Loop = loop;

        UpdateAnimation();

        // Count quads.
        int         quadCount = 0;
        List <Slot> drawOrder = skeleton.DrawOrder;

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

        // Ensure mesh data is the right size.
        if (quadCount != this.quadCount)
        {
            this.quadCount = quadCount;
            vertices       = new Vector3[quadCount * 4];
            uvs            = new Vector2[quadCount * 4];
            triangles      = new int[quadCount * 6];
        }

        // Setup mesh.
        int quadIndex = 0;

        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;

                regionAttachment.UpdateVertices(slot.Bone);
                float[] regionVertices = regionAttachment.Vertices;
                int     vertexIndex    = quadIndex * 4;
                vertices[vertexIndex]     = new Vector3(regionVertices[RegionAttachment.X1], regionVertices[RegionAttachment.Y1], 0);
                vertices[vertexIndex + 1] = new Vector3(regionVertices[RegionAttachment.X4], regionVertices[RegionAttachment.Y4], 0);
                vertices[vertexIndex + 2] = new Vector3(regionVertices[RegionAttachment.X2], regionVertices[RegionAttachment.Y2], 0);
                vertices[vertexIndex + 3] = new Vector3(regionVertices[RegionAttachment.X3], regionVertices[RegionAttachment.Y3], 0);

                AtlasRegion region = regionAttachment.Region;
                if (region.rotate)
                {
                    uvs[vertexIndex + 1] = new Vector2(region.u, 1 - region.v2);
                    uvs[vertexIndex + 2] = new Vector2(region.u2, 1 - region.v2);
                    uvs[vertexIndex + 3] = new Vector2(region.u, 1 - region.v);
                    uvs[vertexIndex]     = new Vector2(region.u2, 1 - region.v);
                }
                else
                {
                    uvs[vertexIndex]     = new Vector2(region.u, 1 - region.v2);
                    uvs[vertexIndex + 1] = new Vector2(region.u2, 1 - region.v2);
                    uvs[vertexIndex + 2] = new Vector2(region.u, 1 - region.v);
                    uvs[vertexIndex + 3] = new Vector2(region.u2, 1 - region.v);
                }

                int index = quadIndex * 6;
                triangles[index]     = vertexIndex;
                triangles[index + 1] = vertexIndex + 2;
                triangles[index + 2] = vertexIndex + 1;
                triangles[index + 3] = vertexIndex + 2;
                triangles[index + 4] = vertexIndex + 3;
                triangles[index + 5] = vertexIndex + 1;

                quadIndex++;
            }
        }
        mesh.vertices  = vertices;
        mesh.uv        = uvs;
        mesh.triangles = triangles;

        renderer.sharedMaterial = skeletonDataAsset.atlasAsset.material;
    }
Esempio n. 28
0
 /// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary>
 public static void SetScale(this RegionAttachment regionAttachment, float x, float y)
 {
     regionAttachment.scaleX = x;
     regionAttachment.scaleY = y;
 }
Esempio n. 29
0
        public void UpdateSkeletonGeometry()
        {
            skeletonGeometry.ClearInstances();
            BlendState blend;
            var        drawOrder = Skeleton.DrawOrder;
            var        drawOrderItems = Skeleton.DrawOrder.Items;
            float      skeletonR = Skeleton.R, skeletonG = Skeleton.G, skeletonB = Skeleton.B, skeletonA = Skeleton.A;
            Color      color;

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

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

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

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

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

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

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

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

                clipper.ClipEnd(slot);
            }
            clipper.ClipEnd();
        }
Esempio n. 30
0
 /// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary>
 public static void SetPositionOffset(this RegionAttachment regionAttachment, float x, float y)
 {
     regionAttachment.x = x;
     regionAttachment.y = y;
 }
Esempio n. 31
0
    public virtual void Update()
    {
        // Clear fields if missing information to render.
        if (skeletonDataAsset == null || skeletonDataAsset.GetSkeletonData(false) == null)
        {
            Clear();
            return;
        }

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

        UpdateSkeleton();

        // Count quads.
        int         quadCount = 0;
        List <Slot> drawOrder = skeleton.DrawOrder;

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

        // Ensure mesh data is the right size.
        if (quadCount > vertices.Length / 4)
        {
            vertices  = new Vector3[quadCount * 4];
            colors    = new Color[quadCount * 4];
            uvs       = new Vector2[quadCount * 4];
            triangles = new int[quadCount * 6];
            mesh.Clear();

            for (int i = 0, n = quadCount; i < n; i++)
            {
                int index       = i * 6;
                int vertexIndex = i * 4;
                triangles[index]     = vertexIndex;
                triangles[index + 1] = vertexIndex + 2;
                triangles[index + 2] = vertexIndex + 1;
                triangles[index + 3] = vertexIndex + 2;
                triangles[index + 4] = vertexIndex + 3;
                triangles[index + 5] = vertexIndex + 1;
            }
        }
        else
        {
            Vector3 zero = new Vector3(0, 0, 0);
            for (int i = quadCount * 4, n = vertices.Length; i < n; i++)
            {
                vertices[i] = zero;
            }
        }

        // Setup mesh.
        float[] vertexPositions = this.vertexPositions;
        int     quadIndex       = 0;
        Color   color           = new Color();

        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;

                regionAttachment.ComputeVertices(skeleton.X, skeleton.Y, slot.Bone, vertexPositions);
                int vertexIndex = quadIndex * 4;
                vertices[vertexIndex]     = new Vector3(vertexPositions[RegionAttachment.X1], vertexPositions[RegionAttachment.Y1], 0);
                vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4], vertexPositions[RegionAttachment.Y4], 0);
                vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], 0);
                vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], 0);

                color.a                 = skeleton.A * slot.A;
                color.r                 = skeleton.R * slot.R * color.a;
                color.g                 = skeleton.G * slot.G * color.a;
                color.b                 = skeleton.B * slot.B * color.a;
                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], 1 - regionUVs[RegionAttachment.Y1]);
                uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], 1 - regionUVs[RegionAttachment.Y4]);
                uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], 1 - regionUVs[RegionAttachment.Y2]);
                uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], 1 - regionUVs[RegionAttachment.Y3]);

                quadIndex++;
            }
        }
        mesh.vertices  = vertices;
        mesh.colors    = colors;
        mesh.uv        = uvs;
        mesh.triangles = triangles;

        renderer.sharedMaterial = skeletonDataAsset.atlasAsset.material;
    }
Esempio n. 32
0
 /// <summary>Gets the region (image) of a RegionAttachment</summary>
 public static AtlasRegion GetRegion(this RegionAttachment regionAttachment)
 {
     return(regionAttachment.RendererObject as AtlasRegion);
 }
		public void Attach () {
			var skeletonComponent = GetComponent<ISkeletonComponent>();
			var skeletonRenderer = skeletonComponent as SkeletonRenderer;
			if (skeletonRenderer != null)
				this.applyPMA = skeletonRenderer.pmaVertexColors;
			else {
				var skeletonGraphic = skeletonComponent as SkeletonGraphic;
				if (skeletonGraphic != null)
					this.applyPMA = skeletonGraphic.SpineMeshGenerator.PremultiplyVertexColors;
			}

			Shader attachmentShader = applyPMA ? Shader.Find(DefaultPMAShader) : Shader.Find(DefaultStraightAlphaShader);
			attachment = applyPMA ? sprite.ToRegionAttachmentPMAClone(attachmentShader) : sprite.ToRegionAttachment(SpriteAttacher.GetPageFor(sprite.texture, attachmentShader));
			skeletonComponent.Skeleton.FindSlot(slot).Attachment = attachment;
		}