Beispiel #1
0
        /// <summary>
        /// Clears any previous polygons, finds all visible bounding box attachments,
        /// and computes the world vertices for each bounding box's polygon.</summary>
        /// <param name="skeleton">The skeleton.</param>
        /// <param name="updateAabb">
        /// If true, the axis aligned bounding box containing all the polygons is computed.
        /// If false, the SkeletonBounds AABB methods will always return true.
        /// </param>
        public void Update(Skeleton skeleton, bool updateAabb)
        {
            ExposedList <BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
            ExposedList <Polygon> polygons = Polygons;
            ExposedList <Slot>    slots    = skeleton.slots;
            int slotCount = slots.Count;

            boundingBoxes.Clear();
            for (int i = 0, n = polygons.Count; i < n; i++)
            {
                polygonPool.Add(polygons.Items[i]);
            }
            polygons.Clear();

            for (int i = 0; i < slotCount; i++)
            {
                Slot slot = slots.Items[i];
                BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment;
                if (boundingBox == null)
                {
                    continue;
                }
                boundingBoxes.Add(boundingBox);

                Polygon polygon   = null;
                int     poolCount = polygonPool.Count;
                if (poolCount > 0)
                {
                    polygon = polygonPool.Items[poolCount - 1];
                    polygonPool.RemoveAt(poolCount - 1);
                }
                else
                {
                    polygon = new Polygon();
                }
                polygons.Add(polygon);

                int count = boundingBox.worldVerticesLength;
                polygon.Count = count;
                if (polygon.Vertices.Length < count)
                {
                    polygon.Vertices = new float[count];
                }
                boundingBox.ComputeWorldVertices(slot, polygon.Vertices);
            }

            if (updateAabb)
            {
                AabbCompute();
            }
            else
            {
                minX = int.MinValue;
                minY = int.MinValue;
                maxX = int.MaxValue;
                maxY = int.MaxValue;
            }
        }
Beispiel #2
0
        /// <summary>Caches information about bones and constraints. Must be called if bones, constraints or weighted path attachments are added
        /// or removed.</summary>
        public void UpdateCache()
        {
            ExposedList <IUpdatable> updateCache = this.updateCache;

            updateCache.Clear();
            this.updateCacheReset.Clear();

            ExposedList <Bone> bones = this.bones;

            for (int i = 0, n = bones.Count; i < n; i++)
            {
                bones.Items[i].sorted = false;
            }

            ExposedList <IkConstraint> ikConstraints = this.ikConstraints;
            var transformConstraints = this.transformConstraints;
            var pathConstraints = this.pathConstraints;
            int ikCount = IkConstraints.Count, transformCount = transformConstraints.Count, pathCount = pathConstraints.Count;
            int constraintCount = ikCount + transformCount + pathCount;

            //outer:
            for (int i = 0; i < constraintCount; i++)
            {
                for (int ii = 0; ii < ikCount; ii++)
                {
                    IkConstraint constraint = ikConstraints.Items[ii];
                    if (constraint.data.order == i)
                    {
                        SortIkConstraint(constraint);
                        goto continue_outer;                         //continue outer;
                    }
                }
                for (int ii = 0; ii < transformCount; ii++)
                {
                    TransformConstraint constraint = transformConstraints.Items[ii];
                    if (constraint.data.order == i)
                    {
                        SortTransformConstraint(constraint);
                        goto continue_outer;                         //continue outer;
                    }
                }
                for (int ii = 0; ii < pathCount; ii++)
                {
                    PathConstraint constraint = pathConstraints.Items[ii];
                    if (constraint.data.order == i)
                    {
                        SortPathConstraint(constraint);
                        goto continue_outer;                         //continue outer;
                    }
                }
                continue_outer : {}
            }

            for (int i = 0, n = bones.Count; i < n; i++)
            {
                SortBone(bones.Items[i]);
            }
        }
Beispiel #3
0
 public void ClipEnd()
 {
     if (clipAttachment == null)
     {
         return;
     }
     clipAttachment   = null;
     clippingPolygons = null;
     clippedVertices.Clear();
     clippedTriangles.Clear();
     clippingPolygon.Clear();
 }
Beispiel #4
0
        public void SetSlotsToSetupPose()
        {
            var slots      = this.slots;
            var slotsItems = slots.Items;

            drawOrder.Clear();
            for (int i = 0, n = slots.Count; i < n; i++)
            {
                drawOrder.Add(slotsItems[i]);
            }

            for (int i = 0, n = slots.Count; i < n; i++)
            {
                slotsItems[i].SetToSetupPose();
            }
        }
Beispiel #5
0
        /** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping
         * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */
        internal bool Clip(float x1, float y1, float x2, float y2, float x3, float y3, ExposedList <float> clippingArea, ExposedList <float> output)
        {
            var originalOutput = output;
            var clipped        = false;

            // Avoid copy at the end.
            ExposedList <float> input = null;

            if (clippingArea.Count % 4 >= 2)
            {
                input  = output;
                output = scratch;
            }
            else
            {
                input = scratch;
            }

            input.Clear();
            input.Add(x1);
            input.Add(y1);
            input.Add(x2);
            input.Add(y2);
            input.Add(x3);
            input.Add(y3);
            input.Add(x1);
            input.Add(y1);
            output.Clear();

            float[] clippingVertices     = clippingArea.Items;
            int     clippingVerticesLast = clippingArea.Count - 4;

            for (int i = 0; ; i += 2)
            {
                float edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
                float edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
                float deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;

                float[] inputVertices = input.Items;
                int     inputVerticesLength = input.Count - 2, outputStart = output.Count;
                for (int ii = 0; ii < inputVerticesLength; ii += 2)
                {
                    float inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
                    float inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
                    bool  side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
                    if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0)
                    {
                        if (side2)                           // v1 inside, v2 inside
                        {
                            output.Add(inputX2);
                            output.Add(inputY2);
                            continue;
                        }
                        // v1 inside, v2 outside
                        float c0 = inputY2 - inputY, c2 = inputX2 - inputX;
                        float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
                        output.Add(edgeX + (edgeX2 - edgeX) * ua);
                        output.Add(edgeY + (edgeY2 - edgeY) * ua);
                    }
                    else if (side2)                       // v1 outside, v2 inside
                    {
                        float c0 = inputY2 - inputY, c2 = inputX2 - inputX;
                        float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
                        output.Add(edgeX + (edgeX2 - edgeX) * ua);
                        output.Add(edgeY + (edgeY2 - edgeY) * ua);
                        output.Add(inputX2);
                        output.Add(inputY2);
                    }
                    clipped = true;
                }

                if (outputStart == output.Count)                   // All edges outside.
                {
                    originalOutput.Clear();
                    return(true);
                }

                output.Add(output.Items[0]);
                output.Add(output.Items[1]);

                if (i == clippingVerticesLast)
                {
                    break;
                }
                var temp = output;
                output = input;
                output.Clear();
                input = temp;
            }

            if (originalOutput != output)
            {
                originalOutput.Clear();
                for (int i = 0, n = output.Count - 2; i < n; i++)
                {
                    originalOutput.Add(output.Items[i]);
                }
            }
            else
            {
                originalOutput.Resize(originalOutput.Count - 2);
            }

            return(clipped);
        }
Beispiel #6
0
        public void ClipTriangles(float[] vertices, int verticesLength, int[] triangles, int trianglesLength, float[] uvs)
        {
            ExposedList <float> clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
            var clippedTriangles = this.clippedTriangles;
            var polygons      = clippingPolygons.Items;
            int polygonsCount = clippingPolygons.Count;

            int index = 0;

            clippedVertices.Clear();
            clippedUVs.Clear();
            clippedTriangles.Clear();
            //outer:
            for (int i = 0; i < trianglesLength; i += 3)
            {
                int   vertexOffset = triangles[i] << 1;
                float x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
                float u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];

                vertexOffset = triangles[i + 1] << 1;
                float x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
                float u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];

                vertexOffset = triangles[i + 2] << 1;
                float x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
                float u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];

                for (int p = 0; p < polygonsCount; p++)
                {
                    int s = clippedVertices.Count;
                    if (Clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput))
                    {
                        int clipOutputLength = clipOutput.Count;
                        if (clipOutputLength == 0)
                        {
                            continue;
                        }
                        float d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
                        float d = 1 / (d0 * d2 + d1 * (y1 - y3));

                        int     clipOutputCount      = clipOutputLength >> 1;
                        float[] clipOutputItems      = clipOutput.Items;
                        float[] clippedVerticesItems = clippedVertices.Resize(s + clipOutputCount * 2).Items;
                        float[] clippedUVsItems      = clippedUVs.Resize(s + clipOutputCount * 2).Items;
                        for (int ii = 0; ii < clipOutputLength; ii += 2)
                        {
                            float x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
                            clippedVerticesItems[s]     = x;
                            clippedVerticesItems[s + 1] = y;
                            float c0 = x - x3, c1 = y - y3;
                            float a = (d0 * c0 + d1 * c1) * d;
                            float b = (d4 * c0 + d2 * c1) * d;
                            float c = 1 - a - b;
                            clippedUVsItems[s]     = u1 * a + u2 * b + u3 * c;
                            clippedUVsItems[s + 1] = v1 * a + v2 * b + v3 * c;
                            s += 2;
                        }

                        s = clippedTriangles.Count;
                        int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3 * (clipOutputCount - 2)).Items;
                        clipOutputCount--;
                        for (int ii = 1; ii < clipOutputCount; ii++)
                        {
                            clippedTrianglesItems[s]     = index;
                            clippedTrianglesItems[s + 1] = index + ii;
                            clippedTrianglesItems[s + 2] = index + ii + 1;
                            s += 3;
                        }
                        index += clipOutputCount + 1;
                    }
                    else
                    {
                        float[] clippedVerticesItems = clippedVertices.Resize(s + 3 * 2).Items;
                        float[] clippedUVsItems      = clippedUVs.Resize(s + 3 * 2).Items;
                        clippedVerticesItems[s]     = x1;
                        clippedVerticesItems[s + 1] = y1;
                        clippedVerticesItems[s + 2] = x2;
                        clippedVerticesItems[s + 3] = y2;
                        clippedVerticesItems[s + 4] = x3;
                        clippedVerticesItems[s + 5] = y3;

                        clippedUVsItems[s]     = u1;
                        clippedUVsItems[s + 1] = v1;
                        clippedUVsItems[s + 2] = u2;
                        clippedUVsItems[s + 3] = v2;
                        clippedUVsItems[s + 4] = u3;
                        clippedUVsItems[s + 5] = v3;

                        s = clippedTriangles.Count;
                        int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3).Items;
                        clippedTrianglesItems[s]     = index;
                        clippedTrianglesItems[s + 1] = index + 1;
                        clippedTrianglesItems[s + 2] = index + 2;
                        index += 3;
                        break;                         //continue outer;
                    }
                }
            }
        }