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