Esempio n. 1
0
        ///
        //    Update does the work of mapping the texture onto the triangles
        //    It now doesn't occur the cost of free/alloc data every update cycle.
        //    It also only changes the percentage point but no other points if they have not
        //    been modified.
        //
        //    It now deals with flipped texture. If you run into this problem, just use the
        //    sprite property and enable the methods flipX, flipY.
        ///
        void UpdateRadial()
        {
            if (Sprite == null)
            {
                return;
            }

            float alpha = Percentage / 100f;

            float angle = 2f * (MathHelper.Pi) * (ReverseDirection ? alpha : 1.0f - alpha);

            //    We find the vector to do a hit detection based on the percentage
            //    We know the first vector is the one @ 12 o'clock (top,mid) so we rotate
            //    from that by the progress angle around the m_tMidpoint pivot
            var     topMid       = new CCPoint(Midpoint.X, 1f);
            CCPoint percentagePt = CCPoint.RotateByAngle(topMid, Midpoint, angle);


            int     index = 0;
            CCPoint hit;

            if (alpha == 0f)
            {
                //    More efficient since we don't always need to check intersection
                //    If the alpha is zero then the hit point is top mid and the index is 0.
                hit   = topMid;
                index = 0;
            }
            else if (alpha == 1f)
            {
                //    More efficient since we don't always need to check intersection
                //    If the alpha is one then the hit point is top mid and the index is 4.
                hit   = topMid;
                index = 4;
            }
            else
            {
                //    We run a for loop checking the edges of the texture to find the
                //    intersection point
                //    We loop through five points since the top is split in half

                float min_t = float.MaxValue;

                for (int i = 0; i <= ProgressTextureCoordsCount; ++i)
                {
                    int pIndex = (i + (ProgressTextureCoordsCount - 1)) % ProgressTextureCoordsCount;

                    CCPoint edgePtA = BoundaryTexCoord(i % ProgressTextureCoordsCount);
                    CCPoint edgePtB = BoundaryTexCoord(pIndex);

                    //    Remember that the top edge is split in half for the 12 o'clock position
                    //    Let's deal with that here by finding the correct endpoints
                    if (i == 0)
                    {
                        edgePtB = CCPoint.Lerp(edgePtA, edgePtB, 1 - Midpoint.X);
                    }
                    else if (i == 4)
                    {
                        edgePtA = CCPoint.Lerp(edgePtA, edgePtB, 1 - Midpoint.X);
                    }

                    //    s and t are returned by ccpLineIntersect
                    float s = 0, t = 0;
                    if (CCPoint.LineIntersect(edgePtA, edgePtB, Midpoint, percentagePt, ref s, ref t))
                    {
                        //    Since our hit test is on rays we have to deal with the top edge
                        //    being in split in half so we have to test as a segment
                        if ((i == 0 || i == 4))
                        {
                            //    s represents the point between edgePtA--edgePtB
                            if (!(0f <= s && s <= 1f))
                            {
                                continue;
                            }
                        }
                        //    As long as our t isn't negative we are at least finding a
                        //    correct hitpoint from m_tMidpoint to percentagePt.
                        if (t >= 0f)
                        {
                            //    Because the percentage line and all the texture edges are
                            //    rays we should only account for the shortest intersection
                            if (t < min_t)
                            {
                                min_t = t;
                                index = i;
                            }
                        }
                    }
                }

                //    Now that we have the minimum magnitude we can use that to find our intersection
                hit = Midpoint + ((percentagePt - Midpoint) * min_t);
            }


            //    The size of the vertex data is the index from the hitpoint
            //    the 3 is for the m_tMidpoint, 12 o'clock point and hitpoint position.

            bool sameIndexCount = true;

            if (vertexData != null && vertexData.Length != index + 3)
            {
                sameIndexCount = false;
                vertexData     = null;
            }

            if (vertexData == null)
            {
                vertexData = new CCV3F_C4B_T2F[index + 3];
            }

            if (!sameIndexCount)
            {
                //    First we populate the array with the m_tMidpoint, then all
                //    vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint
                vertexData[0].TexCoords = TextureCoordFromAlphaPoint(Midpoint);
                vertexData[0].Vertices  = VertexFromAlphaPoint(Midpoint);

                vertexData[1].TexCoords = TextureCoordFromAlphaPoint(topMid);
                vertexData[1].Vertices  = VertexFromAlphaPoint(topMid);

                for (int i = 0; i < index; ++i)
                {
                    CCPoint alphaPoint = BoundaryTexCoord(i);
                    vertexData[i + 2].TexCoords = TextureCoordFromAlphaPoint(alphaPoint);
                    vertexData[i + 2].Vertices  = VertexFromAlphaPoint(alphaPoint);
                }
            }

            // hitpoint will go last
            vertexData[vertexData.Length - 1].TexCoords = TextureCoordFromAlphaPoint(hit);
            vertexData[vertexData.Length - 1].Vertices  = VertexFromAlphaPoint(hit);
        }