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