void PaintLayer::fillLineEndPointAt(CCPoint center, CCPoint aLineDir, float radius, ccColor4F color)
{
    int numberOfSegments = 32;
    LineVertex *vertices = (LineVertex *)malloc(sizeof(LineVertex) * numberOfSegments * 9);
    float anglePerSegment = (float)(M_PI / (numberOfSegments - 1));

    //! we need to cover M_PI from this, dot product of normalized vectors is equal to cos angle between them... and if you include rightVec dot you get to know the correct direction :)
    CCPoint perpendicular = ccpPerp(aLineDir);
    float angle = acosf(ccpDot(perpendicular, CCPointMake(0, 1)));
    float rightDot = ccpDot(perpendicular, CCPointMake(1, 0));
    if (rightDot < 0.0f)
    {
        angle *= -1;
    }

    CCPoint prevPoint = center;
    CCPoint prevDir = ccp(sinf(0), cosf(0));
    for (unsigned int i = 0; i < numberOfSegments; ++i)
    {
        CCPoint dir = ccp(sinf(angle), cosf(angle));
        CCPoint curPoint = ccp(center.x + radius * dir.x, center.y + radius * dir.y);
        vertices[i * 9 + 0].pos = center;
        vertices[i * 9 + 1].pos = prevPoint;
        vertices[i * 9 + 2].pos = curPoint;

        //! fill rest of vertex data
        for (unsigned int j = 0; j < 9; ++j)
        {
            vertices[i * 9 + j].z = j < 3 ? 1.0f : 2.0f;
            vertices[i * 9 + j].color = color;
        }

        //! add overdraw
        vertices[i * 9 + 3].pos = ccpAdd(prevPoint, ccpMult(prevDir, overdraw));
        vertices[i * 9 + 3].color.a = 0;
        vertices[i * 9 + 4].pos = prevPoint;
        vertices[i * 9 + 5].pos = ccpAdd(curPoint, ccpMult(dir, overdraw));
        vertices[i * 9 + 5].color.a = 0;

        vertices[i * 9 + 6].pos = prevPoint;
        vertices[i * 9 + 7].pos = curPoint;
        vertices[i * 9 + 8].pos = ccpAdd(curPoint, ccpMult(dir, overdraw));
        vertices[i * 9 + 8].color.a = 0;

        prevPoint = curPoint;
        prevDir = dir;
        angle += anglePerSegment;
    }

    glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, sizeof(LineVertex), &vertices[0].pos);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, sizeof(LineVertex), &vertices[0].color);
    glDrawArrays(GL_TRIANGLES, 0, numberOfSegments * 9);

    free(vertices);
}
float ccpAngleSigned(CCPoint a, CCPoint b)
{
	CCPoint a2 = ccpNormalize(a);	CCPoint b2 = ccpNormalize(b);
	float angle = atan2f(a2.x * b2.y - a2.y * b2.x, ccpDot(a2, b2));
	if( fabs(angle) < kCCPointEpsilon ) return 0.f;
	return angle;
}
Beispiel #3
0
float ccpAngle(const CCPoint& a, const CCPoint& b)
{
    float angle = acosf(ccpDot(ccpNormalize(a), ccpNormalize(b)));

    if (fabs(angle) < kCCPointEpsilon)
    {
        return 0.f;
    }
    return angle;
}
Beispiel #4
0
    HitTestResult* hitTestStripStrip(StripBodyNode* a, StripBodyNode* b)
    {
        Point Atop[4];
        Point Btop[4];
        a->getTops(Atop, Atop + 1, Atop + 2, Atop + 3);
        b->getTops(Btop, Btop + 1, Btop + 2, Btop + 3);
        int cpcount = 0;
        Point cp[12];
        bool hit = isRectCrossRect(Atop[0], Atop[1], Atop[2], Atop[3],
            Btop[0], Btop[1], Btop[2], Btop[3], &cpcount, cp);

        if(hit)
        {
            if(cpcount < 0)
                cpcount = 0;

            Point ca = a->getCenter();
            float wa = a->getWidth();
            float ha = ccpDistance(a->getBegin(), a->getEnd());
            Vector2 aa = ccpNormalize(a->getEnd() - a->getBegin());
            for(int i = 0; i < 4; i++)
            {
                if(isPointInRect(Btop[i], ca, wa, ha, aa))
                {
                    cp[cpcount++] = Btop[i];
                }
            }

            // use dot result for comparing directly
            // get true distance when receive a minimun dot result
            int iMin = 0;
            float dMin = 0;
            Vector2 direction = a->getEnd() - a->getBegin();
            for(int i = 0; i < cpcount; i++)
            {
                float d = ccpDot(cp[i], direction);
                if( i == 0 && d < dMin)
                {
                    dMin = d;
                    iMin = i;
                }
            }

            dMin /= ccpLength(direction);
            return HitTestResult::create(HTRT_CROSS, cp[iMin], dMin);
        }
        else
        {
            return HitTestResult::create(HTRT_NONE);
        }
    }
bool ccpLineIntersect(CCPoint p1, CCPoint p2, 
					  CCPoint p3, CCPoint p4,
					  float *s, float *t){
	CCPoint p13, p43, p21;
	float d1343, d4321, d1321, d4343, d2121;
	float numer, denom;
	
	p13 = ccpSub(p1, p3);
	
	p43 = ccpSub(p4, p3);
	
	//Roughly equal to zero but with an epsilon deviation for float 
	//correction
	if (ccpFuzzyEqual(p43, CCPointZero, kCCPointEpsilon))
		return false;
	
	p21 = ccpSub(p2, p1);
	
	//Roughly equal to zero
	if (ccpFuzzyEqual(p21,CCPointZero, kCCPointEpsilon))
		return false;
	
	d1343 = ccpDot(p13, p43);
	d4321 = ccpDot(p43, p21);
	d1321 = ccpDot(p13, p21);
	d4343 = ccpDot(p43, p43);
	d2121 = ccpDot(p21, p21);
	
	denom = d2121 * d4343 - d4321 * d4321;
	if (fabs(denom) < kCCPointEpsilon)
		return false;
	numer = d1343 * d4321 - d1321 * d4343;
	
	*s = numer / denom;
	*t = (d1343 + d4321 *(*s)) / d4343;
	
	return true;
}
void Canon ::shoot(MyObject* m_enemy, float dt)
{
	CCPoint totarget =  ccpSub(m_enemy->m_pos, this->m_pos);
	float a = ccpDot(m_enemy->m_velocity,m_enemy->m_velocity) - (m_maxVelocity *m_maxVelocity);
	float b = 2 * ccpDot(m_enemy->m_velocity, totarget);
	float c = ccpDot(totarget,totarget);

	float p = -b / (2 * a);
	float q = (float)sqrt((b * b) - 4 * a * c) / (2 * a);

	float t1 = p - q;
	float t2 = p + q;
	float t;

	if (t1 > t2 && t2 > 0)
	{
		t = t2;
	}
	else
	{
		t = t1;
	}

	CCPoint aimSpot = ccpAdd(m_enemy->m_pos ,ccpMult(m_enemy->m_velocity,t)); //position of target in future after t seconds
	CCPoint BoomPath = ccpSub (aimSpot , m_pos );
	float timeToImpact = ccpLength(BoomPath) / m_maxVelocity/60; //speed must be in units per second


	m_BoomManager->addBoom(new Boom(layer, m_pos,timeToImpact,m_maxVelocity));

	for (int i =0; i < m_BoomManager->getListBoom().size(); i++)
	{
		m_BoomManager->getBoom(i)->setTarget(aimSpot);
		m_BoomManager->getBoom(i)->m_Active = true;
	}

}
Beispiel #7
0
CCPoint calculateCosASinAOfVec1ToVec2(const CCPoint&vec1,const CCPoint&vec2)
//return {cos(vec1,vec2),sin(vec1,vec2)}
{
    float cosA=ccpDot(vec1, vec2)/(ccpLength(vec1)*ccpLength(vec2));
    float signalOfSinA;
    {
        float _vec1[3]={vec1.x,vec1.y,0};
        float _vec2[3]={vec2.x,vec2.y,0};
        float _rs[3];
        __cross(_vec1, _vec2, _rs);
        if (_rs[2]==0) {
            signalOfSinA=0;
        }else if(_rs[2]>0){
            signalOfSinA=1;
        }else{
            signalOfSinA=-1;
        }
    }
    float sinA=signalOfSinA*sqrtf(MAX(0,1-cosA*cosA));
    return CCPoint(cosA,sinA);
}
Beispiel #8
0
NS_CC_BEGIN

void ccVertexLineToPolygon(DPoint *points, float stroke, ccVertex2F *vertices, unsigned int offset, unsigned int nuPoints)
{
    nuPoints += offset;
    if(nuPoints<=1) return;

    stroke *= 0.5f;

    unsigned int idx;
    unsigned int nuPointsMinus = nuPoints-1;

    for(unsigned int i = offset; i<nuPoints; i++)
    {
        idx = i*2;
        DPoint p1 = points[i];
        DPoint perpVector;

        if(i == 0)
            perpVector = ccpPerp(ccpNormalize(ccpSub(p1, points[i+1])));
        else if(i == nuPointsMinus)
            perpVector = ccpPerp(ccpNormalize(ccpSub(points[i-1], p1)));
        else
        {
            DPoint p2 = points[i+1];
            DPoint p0 = points[i-1];

            DPoint p2p1 = ccpNormalize(ccpSub(p2, p1));
            DPoint p0p1 = ccpNormalize(ccpSub(p0, p1));

            // Calculate angle between vectors
            float angle = acosf(ccpDot(p2p1, p0p1));

            if(angle < CC_DEGREES_TO_RADIANS(70))
                perpVector = ccpPerp(ccpNormalize(ccpMidpoint(p2p1, p0p1)));
            else if(angle < CC_DEGREES_TO_RADIANS(170))
                perpVector = ccpNormalize(ccpMidpoint(p2p1, p0p1));
            else
                perpVector = ccpPerp(ccpNormalize(ccpSub(p2, p0)));
        }
        perpVector = ccpMult(perpVector, stroke);

        vertices[idx] = vertex2(p1.x+perpVector.x, p1.y+perpVector.y);
        vertices[idx+1] = vertex2(p1.x-perpVector.x, p1.y-perpVector.y);

    }

    // Validate vertexes
    offset = (offset==0) ? 0 : offset-1;
    for(unsigned int i = offset; i<nuPointsMinus; i++)
    {
        idx = i*2;
        const unsigned int idx1 = idx+2;

        ccVertex2F p1 = vertices[idx];
        ccVertex2F p2 = vertices[idx+1];
        ccVertex2F p3 = vertices[idx1];
        ccVertex2F p4 = vertices[idx1+1];

        float s;
        //BOOL fixVertex = !ccpLineIntersect(DPoint(p1.x, p1.y), DPoint(p4.x, p4.y), DPoint(p2.x, p2.y), DPoint(p3.x, p3.y), &s, &t);
        bool fixVertex = !ccVertexLineIntersect(p1.x, p1.y, p4.x, p4.y, p2.x, p2.y, p3.x, p3.y, &s);
        if(!fixVertex)
            if (s<0.0f || s>1.0f)
                fixVertex = true;

        if(fixVertex)
        {
            vertices[idx1] = p4;
            vertices[idx1+1] = p3;
        }
    }
}
float ccpAngle(CCPoint a, CCPoint b)
{
	float angle = acosf(ccpDot(ccpNormalize(a), ccpNormalize(b)));
	if( fabs(angle) < kCCPointEpsilon ) return 0.f;
	return angle;
}
float CCRibbon::sideOfLine(CCPoint p, CCPoint l1, CCPoint l2)
{
    CCPoint vp = ccpPerp(ccpSub(l1, l2));
    CCPoint vx = ccpSub(p, l1);
    return ccpDot(vx, vp);
}
bool ElfEffectAnimHandler::Entered()
{
	ElfBaseState::Entered();

	m_pEffect = NULL;
	m_continueTime = 0.0f;

	if(m_pSkill->effectID > 0)
	{
		if(m_pSkill->effectSoundID > 0)
		{
			GameAudioManager::sharedManager()->playEffect(m_pSkill->effectSoundID, false);
		}

		m_pEffect = GetEffect(m_pSkill->effectID);
		
		Push(new MagicCheckerHandler(new MagicCheckerEvt(m_pRole, m_actionId, m_pEffect)));


		ATTACH_POINT_TYPE apt = kType_SHOOT_HOR;
		switch(GetAnimDir())
		{
		case DIRECTION_UP:
			apt = kType_SHOOT_UP;
			break;
		case DIRECTION_BOTTOM:
			apt = kType_SHOOT_DOWN;
			break;
		case DIRECTION_LEFT:
		case DIRECTION_RIGHT:
			apt = kType_SHOOT_HOR;
			break;
		default:
			apt = kType_SHOOT_HOR;
			break;
		}

		m_dir = m_attackDir;
		m_displacement = m_attackDisplacement;

		if(m_pSkill->type != FAIRY_SKILL_INFO::E_BUFFER)
		{
			if(!m_pSkill->bLock)
			{
				m_pEffect->setPosition(ccp(0.0f, 0.0f));
				m_initDir.setPoint(0.0f, 1.0f);
				float degree = acosf(ccpDot(m_initDir, m_dir)) / 3.1415926 * 180.0f;
				if(m_dir.x < 0)
					degree = -degree;
				m_pEffect->getRoot()->setRotation(degree);
			}
		}
		



		m_speed = m_pSkill->longDistanceEffectSpeed;
		
		CCPoint pos = m_pElf->getAttachPoint(apt);
		switch(m_pSkill->aim)
		{
		case FAIRY_SKILL_INFO::E_HERO:
			{
				CCPoint pos = m_pRole->getPosition();
				pos.y += 16.0f;
				m_pEffect->setPosition(pos);
				m_continueTime = m_pSkill->continueTime;
			}
			break;
		case FAIRY_SKILL_INFO::E_FULL_SCREEN:
			{
				CCPoint cameraOffset = CCDirector::sharedDirector()->getLevelRenderCameraOffset();
				CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
				m_pEffect->setPosition(ccp(cameraOffset.x + visibleSize.width / 2, cameraOffset.y + visibleSize.height / 2));
			}
			break;
		default:
			m_pEffect->setPosition( m_pElf->getPosition() + pos );
			break;
		}
		
		if(m_speed <= 0.0f && m_displacement > 0.0f)
		{
			m_pEffect->SetAnim(kType_Play,1,false);

		}
		else
		{
			m_pEffect->SetAnim(kType_Play,1,true);
		}

		if(m_pEffect->getParent() != LevelManager::sShareInstance()->getCurrentLevelLayer()->getObjectLayer())
		{
			LevelManager::sShareInstance()->getCurrentLevelLayer()->getObjectLayer()->addChild(m_pEffect, LevelLayer::sCalcZorder(m_pEffect->getPosition()));
		}
		else
		{
			m_pEffect->setZOrder(LevelLayer::sCalcZorder(m_pEffect->getPosition()));
		}

	}

	return true;
}