/// // 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. /// protected void UpdateRadial() { if (m_pSprite == null) { return; } float alpha = m_fPercentage / 100f; float angle = 2f * (MathHelper.Pi) * (m_bReverseDirection ? 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(m_tMidpoint.X, 1f); CCPoint percentagePt = CCPoint.RotateByAngle(topMid, m_tMidpoint, 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 <= kProgressTextureCoordsCount; ++i) { int pIndex = (i + (kProgressTextureCoordsCount - 1)) % kProgressTextureCoordsCount; CCPoint edgePtA = BoundaryTexCoord(i % kProgressTextureCoordsCount); 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 - m_tMidpoint.X); } else if (i == 4) { edgePtA = CCPoint.Lerp(edgePtA, edgePtB, 1 - m_tMidpoint.X); } // s and t are returned by ccpLineIntersect float s = 0, t = 0; if (CCPoint.LineIntersect(edgePtA, edgePtB, m_tMidpoint, 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 = m_tMidpoint + ((percentagePt - m_tMidpoint) * 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 (m_nVertexDataCount != index + 3) { sameIndexCount = false; m_pVertexData = null; } if (m_pVertexData == null) { m_nVertexDataCount = index + 3; m_pVertexData = new CCV3F_C4B_T2F[m_nVertexDataCount]; } UpdateColor(); 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 m_pVertexData[0].TexCoords = TextureCoordFromAlphaPoint(m_tMidpoint); m_pVertexData[0].Vertices = VertexFromAlphaPoint(m_tMidpoint); m_pVertexData[1].TexCoords = TextureCoordFromAlphaPoint(topMid); m_pVertexData[1].Vertices = VertexFromAlphaPoint(topMid); for (int i = 0; i < index; ++i) { CCPoint alphaPoint = BoundaryTexCoord(i); m_pVertexData[i + 2].TexCoords = TextureCoordFromAlphaPoint(alphaPoint); m_pVertexData[i + 2].Vertices = VertexFromAlphaPoint(alphaPoint); } } // hitpoint will go last m_pVertexData[m_nVertexDataCount - 1].TexCoords = TextureCoordFromAlphaPoint(hit); m_pVertexData[m_nVertexDataCount - 1].Vertices = VertexFromAlphaPoint(hit); }