Beispiel #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 CCProgressTimer::updateRadial()
{
    if (!m_pSprite) {
        return;
    }
    float alpha = m_fPercentage / 100.f;

    float angle = 2.f*((float)M_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
    CCPoint topMid = ccp(m_tMidpoint.x, 1.f);
    CCPoint percentagePt = ccpRotateByAngle(topMid, m_tMidpoint, angle);


    int index = 0;
    CCPoint hit = CCPoint::zero;

    if (alpha == 0.f) {
        //    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 == 1.f) {
        //    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 = FLT_MAX;

        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 = ccpLerp(edgePtA, edgePtB, 1-m_tMidpoint.x);
            } else if(i == 4){
                edgePtA = ccpLerp(edgePtA, edgePtB, 1-m_tMidpoint.x);
            }

            //    s and t are returned by ccpLineIntersect
            float s = 0, t = 0;
            if(ccpLineIntersect(edgePtA, edgePtB, m_tMidpoint, percentagePt, &s, &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 (!(0.f <= s && s <= 1.f)) {
                        continue;
                    }
                }
                //    As long as our t isn't negative we are at least finding a
                //    correct hitpoint from m_tMidpoint to percentagePt.
                if (t >= 0.f) {
                    //    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 = ccpAdd(m_tMidpoint, ccpMult(ccpSub(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;
        CC_SAFE_FREE(m_pVertexData);
        m_nVertexDataCount = 0;
    }


    if(!m_pVertexData) {
        m_nVertexDataCount = index + 3;
        m_pVertexData = (ccV2F_C4B_T2F*)malloc(m_nVertexDataCount * sizeof(ccV2F_C4B_T2F));
        CCAssert( m_pVertexData, "CCProgressTimer. Not enough memory");
    }
    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);

}
Beispiel #2
0
void wyProgressTimer::updateRadial() {
	//	Texture Max is the actual max coordinates to deal with non-power of 2 textures
	wyTexture2D* tex = m_sprite->getTexture();
	wyRect texRect = m_sprite->getTextureRect();
	float tOffsetX = texRect.x / tex->getPixelWidth();
	float tOffsetY = texRect.y / tex->getPixelHeight();
	wyPoint tMax = {
			texRect.width / tex->getPixelWidth(),
			texRect.height / tex->getPixelHeight()
	};

	// if texture is get from opengl, it is natural born y-flipped
	bool flipY = tex->getSource() == SOURCE_OPENGL;
	if(m_sprite->isFlipY())
		flipY = !flipY;

	//	Grab the midpoint
	wyPoint midpoint = {
		0.5f * tMax.x,
		0.5f * tMax.y
	};

    // get percentage value in [0, 1] range
	float alpha = m_percentage / 100.f;

	//	Otherwise we can get the angle from the alpha
	float angle = 2.0f * M_PI * (m_style == RADIAL_CW ? 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 midpoint pivot
	wyPoint topMid = { midpoint.x, 0.0f };
	wyPoint percentagePt = wypRotateByAngle(topMid, midpoint, angle);

    // helper variables
	int index = 0;
	wyPoint hit = wypZero;

    // check percentage
	if(alpha == 0.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 == 1.0f) {
		//	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 = MAX_FLOAT;
		for(int i = 0; i <= PROGRESS_TEXTURE_COORDS_COUNT; ++i) {
			int pIndex = (i + (PROGRESS_TEXTURE_COORDS_COUNT - 1)) % PROGRESS_TEXTURE_COORDS_COUNT;

			wyPoint edgePtA = boundaryTexCoord(i % PROGRESS_TEXTURE_COORDS_COUNT);
			edgePtA = wypMul(edgePtA, tMax);
			wyPoint edgePtB = boundaryTexCoord(pIndex);
			edgePtB = wypMul(edgePtB, tMax);

			//	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 = wypLerp(edgePtA, edgePtB, .5f);
			} else if(i == 4) {
				edgePtA = wypLerp(edgePtA, edgePtB, .5f);
			}

			//	s and t are returned by lineIntersect
			float st[] = { 0.0f, 0.0f };
			if(wypLineIntersect(edgePtA, edgePtB, midpoint, percentagePt, st)) {
				float s = st[0];
				float t = st[1];

				//	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(!(0.f <= s && s <= 1.f)) {
						continue;
					}
				}
				//	As long as our t isn't negative we are at least finding a
				//	correct hitpoint from midpoint to percentagePt.
				if(t >= 0.f) {
					//	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
		wyPoint tmp1 = wypSub(percentagePt, midpoint);
		tmp1 = wypMul(tmp1, wyp(min_t, min_t));
		hit = wypAdd(midpoint, tmp1);
	}

	//	The size of the vertex data is the index from the hitpoint
	//	the 3 is for the midpoint, 12 o'clock point and hitpoint position.
	if(m_vertexCount < index + 3) {
        resetCapacity(index + 3);
		updateColor();
    }
    m_vertexCount = index + 3;

	// First we populate the array with the midpoint, then all
	// vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint
	int pos = 0;
	m_texCoords[pos] = midpoint.x;
	m_texCoords[pos + 1] = midpoint.y;
	wyPoint vertex = vertexFromTexCoord(midpoint.x, midpoint.y);
	m_vertices[pos] = vertex.x;
	m_vertices[pos + 1] = vertex.y;
	pos += 2;

	m_texCoords[pos] = midpoint.x;
	m_texCoords[pos + 1] = 0.0f;
	vertex = vertexFromTexCoord(midpoint.x, 0.0f);
	m_vertices[pos] = vertex.x;
	m_vertices[pos + 1] = vertex.y;
	pos += 2;

	for(int i = 0; i < index; ++i) {
		wyPoint texCoord = boundaryTexCoord(i);
		texCoord = wypMul(texCoord, tMax);

		m_texCoords[pos] = texCoord.x;
		m_texCoords[pos + 1] = texCoord.y;
		vertex = vertexFromTexCoord(texCoord.x, texCoord.y);
		m_vertices[pos] = vertex.x;
		m_vertices[pos + 1] = vertex.y;
		pos += 2;
	}

	//	hitpoint will go last
	index = (m_vertexCount - 1) * 2;
	m_texCoords[index] = hit.x;
	m_texCoords[index + 1] = hit.y;
	vertex = vertexFromTexCoord(hit.x, hit.y);
	m_vertices[index] = vertex.x;
	m_vertices[index + 1] = vertex.y;

    // if sprite is from a rotated zwoptex image, need rotate texture coordinate
    if(m_sprite->isRotatedZwoptex()) {
        float t_x = tMax.x;
        tMax.x = tMax.y;
        tMax.y = t_x;
    }
    
    // fill all texture coordinates
    for(int i = 0; i < m_vertexCount; i++) {
        if(m_sprite->isRotatedZwoptex()) {
            float t_x = m_texCoords[i * 2];
            float t_y = m_texCoords[i * 2 + 1];
            m_texCoords[i*2] = t_y / (tMax.x / tMax.y);
            m_texCoords[i * 2 + 1] = t_x * (tMax.x / tMax.y); 
        }
        if (flipY || m_sprite->isFlipX()) {
            if (m_sprite->isFlipX()) {
                m_texCoords[i * 2] = tMax.x - m_texCoords[i * 2];
            }
            if(flipY) {
                m_texCoords[i * 2 + 1] = tMax.y - m_texCoords[i * 2 + 1];
            }
        }
        m_texCoords[i * 2] += tOffsetX;
        m_texCoords[i * 2 + 1] += tOffsetY;
    }

	// The vertices order should be in counter clockwise direction, or else it will be culled if 
	// the director->setCullFace() is enabled.
	if(RADIAL_CW == m_style) {
		for(int i = 1; i < m_vertexCount; ++i) {
			int targetIndex = m_vertexCount - i;
			if( i < targetIndex) {
				wyUtils::swap(m_texCoords, i * 2, targetIndex * 2);
				wyUtils::swap(m_texCoords, i * 2 + 1, targetIndex * 2 + 1);
				wyUtils::swap(m_vertices, i * 2, targetIndex * 2);
				wyUtils::swap(m_vertices, i * 2 + 1, targetIndex * 2 + 1);
			}
		}
	}
}