示例#1
0
文件: ray2.c 项目: QBobble/LevelSVG
kmBool kmRay2IntersectTriangle(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, kmVec2* intersection, kmVec2* normal_out) {
    kmVec2 intersect;
    kmVec2 final_intersect;
    kmVec2 normal;
    kmScalar distance = 10000.0f;
    kmBool intersected = KM_FALSE;

    if(kmRay2IntersectLineSegment(ray, p1, p2, &intersect)) {
        intersected = KM_TRUE;

        kmVec2 tmp;
        kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
        if(this_distance < distance) {
            final_intersect.x = intersect.x;
            final_intersect.y = intersect.y;
            distance = this_distance;

            calculate_line_normal(*p1, *p2, &normal);
        }
    }

    if(kmRay2IntersectLineSegment(ray, p2, p3, &intersect)) {
        intersected = KM_TRUE;

        kmVec2 tmp;
        kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
        if(this_distance < distance) {
            final_intersect.x = intersect.x;
            final_intersect.y = intersect.y;
            distance = this_distance;

            calculate_line_normal(*p2, *p3, &normal);
        }
    }

    if(kmRay2IntersectLineSegment(ray, p3, p1, &intersect)) {
        intersected = KM_TRUE;

        kmVec2 tmp;
        kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));
        if(this_distance < distance) {
            final_intersect.x = intersect.x;
            final_intersect.y = intersect.y;
            distance = this_distance;

            calculate_line_normal(*p3, *p1, &normal);
        }
    }

    if(intersected) {
        intersection->x = final_intersect.x;
        intersection->y = final_intersect.y;
        if(normal_out) {
            normal_out->x = normal.x;
            normal_out->y = normal.y;
        }
    }

    return intersected;
}
示例#2
0
void testVec2Length(void)
{
	kmVec2 vec;
	vec.x = 4.0f;
	vec.y = 3.0f;

	CU_ASSERT(5.0f == kmVec2Length(&vec));
}
示例#3
0
文件: vec2.c 项目: PDKK/PodDisplay
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn)
{
	kmScalar l = 1.0f / kmVec2Length(pIn);

	kmVec2 v;
	v.x = pIn->x * l;
	v.y = pIn->y * l;
    
	pOut->x = v.x;
	pOut->y = v.y;

	return pOut;
}
示例#4
0
文件: vec2.c 项目: pperon/kazmath
kmVec2* kmVec2Normalize(kmVec2* pOut, const kmVec2* pIn)
{
        if (!pIn->x && !pIn->y)
                return kmVec2Assign(pOut, pIn);

	kmScalar l = 1.0f / kmVec2Length(pIn);

	kmVec2 v;
	v.x = pIn->x * l;
	v.y = pIn->y * l;
    
	pOut->x = v.x;
	pOut->y = v.y;

	return pOut;
}
示例#5
0
文件: ray2.c 项目: starbugs/kazmath
kmBool kmRay2IntersectBox(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, const kmVec2* p3, const kmVec2* p4,
                          kmVec2* intersection, kmVec2* normal_out) {
    kmBool intersected = KM_FALSE;
    kmVec2 intersect, final_intersect, normal;
    kmScalar distance = 10000.0f;

    const kmVec2* points[4];
    points[0] = p1;
    points[1] = p2;
    points[2] = p3;
    points[3] = p4;

    unsigned int i = 0;
    for(; i < 4; ++i) {
        const kmVec2* this_point = points[i];
        const kmVec2* next_point = (i == 3) ? points[0] : points[i+1];
        const kmVec2* other_point = (i == 3 || i == 0) ? points[1] : points[0];

        if(kmRay2IntersectLineSegment(ray, this_point, next_point, &intersect)) {

            kmVec2 tmp;
            kmScalar this_distance = kmVec2Length(kmVec2Subtract(&tmp, &intersect, &ray->start));

            kmVec2 this_normal;

            calculate_line_normal(*this_point, *next_point, *other_point, &this_normal);
            if(this_distance < distance && kmVec2Dot(&this_normal, &ray->dir) < 0.0f) {
                kmVec2Assign(&final_intersect, &intersect);
                distance = this_distance;
                intersected = KM_TRUE;
                kmVec2Assign(&normal, &this_normal);
            }
        }
    }

    if(intersected) {
        intersection->x = final_intersect.x;
        intersection->y = final_intersect.y;
        if(normal_out) {
            normal_out->x = normal.x;
            normal_out->y = normal.y;
        }
    }

    return intersected;
}
示例#6
0
文件: vec2.c 项目: pperon/kazmath
/**
 * Returns the distance between the two points
 */
kmScalar kmVec2DistanceBetween(const kmVec2* v1, const kmVec2* v2) {
	kmVec2 diff;
	kmVec2Subtract(&diff, v2, v1);
	return fabs(kmVec2Length(&diff));
}
示例#7
0
void BattleManagerScreen::enemyMovementAI( int enemyIdx, float dt )
{
	float speed = 75.0f; //5 pixels/sec
	EntityPair& enemy = m_enemies[enemyIdx];
	
	std::vector<kmVec2> impulses; //x, y
	std::vector<float> impulseWeights;

	//TODO: select from closest player
	EntityPair& player =  m_players[0];
	
	CCSize eSize = enemy.view->getContentSize();
	CCPoint ePos = enemy.view->getPosition();
	ePos.x += eSize.width/2;
	ePos.y += eSize.height/2; //convert to center origin
	CCSize pSize = player.view->getContentSize();
	CCPoint pPos = player.view->getPosition();
	pPos.x += pSize.width/2;
	pPos.y += pSize.height/2; //convert to center origin
	
	float playerLeash = pSize.width * 1.1f;
	float playerLeashSq = playerLeash*playerLeash;

	//impulse towards the player
	kmVec2 toPlayer = { pPos.x - ePos.x, pPos.y - ePos.y };
	kmVec2 u_toPlayer;
	kmVec2Normalize( &u_toPlayer, &toPlayer);
	
	
	if( kmVec2LengthSq( &toPlayer ) < (playerLeashSq * 0.75f) )
	{
		//impulse away from player (too close)
		kmVec2 u_fromPlayer;
		kmVec2Scale(&u_fromPlayer, &u_toPlayer, -1*0.75f); //flip the 'to player' vector
		
		impulses.push_back(u_fromPlayer);
		impulseWeights.push_back(100); //vastly overweigh the impulse to the player
	}else {

		if( kmVec2LengthSq(&toPlayer) > playerLeashSq )
		{
			//kmVec2Scale(&u_toPlayer, &u_toPlayer, 0.51f);
			//impulse towards player
			impulses.push_back(u_toPlayer);
			impulseWeights.push_back(100);

		}
	}
	
	//add impulses away from other enemies
	for( int i=0; i< m_enemies.size(); i++) {
		if( i == enemyIdx ) continue;
		
		CCSize nSize = m_enemies[i].view->getContentSize();
		CCPoint nPos = m_enemies[i].view->getPosition();
		nPos.x += nSize.width/2;
		nPos.y += nSize.height/2;
		
		kmVec2 toNeighbor = { nPos.x - ePos.x, nPos.y - ePos.y };

		float neighborLeash = nSize.width;
		if( kmVec2LengthSq(&toNeighbor) < neighborLeash * neighborLeash ) {
			kmVec2 u_toNeighbor;
			kmVec2Normalize(&u_toNeighbor, &toNeighbor);
			kmVec2 u_fromNeighbor;
			kmVec2Scale(&u_fromNeighbor, &u_toNeighbor, -1);
			impulses.push_back(u_fromNeighbor);
			impulseWeights.push_back(50);
		}
	}
	
	if( impulses.size() == 0 ) return;

	//blend impulses
	kmVec2 finalImpulse = impulses[0]; //zero always valid because its the impulse to the player
	float finalImpulseWeight = impulseWeights[0];
	for( int i=1; i< impulses.size(); i++) {

		float w1 = finalImpulseWeight;
		float w2 = impulseWeights[i];
		float wTot =  w1 + w2;
		
		kmVec2 blend;
		blend.x = (finalImpulse.x * w1 / wTot) + (impulses[i].x * w2 / wTot);
		blend.y = (finalImpulse.y * w1 / wTot) + (impulses[i].y * w2 / wTot);
		
		//run-length summation
		finalImpulseWeight = wTot;
		finalImpulse = blend;
	}
	
	kmVec2 scaledImpulse;
	kmVec2Scale(&scaledImpulse, &finalImpulse, speed * dt);
	
	//CCLog("impulse %.4f", kmVec2Length(& finalImpulse));
	if( kmVec2Length(& finalImpulse) <  (0.5f) )
	{
		//CCLog("ignore impulse %.4f", kmVec2Length(& finalImpulse));
		return; //ignore very small changes to avoid leash jitter
	}
	
	ePos.x += scaledImpulse.x;
	ePos.y += scaledImpulse.y;
	ePos.x -= eSize.width/2;
	ePos.y -= eSize.height/2; //back to original anchor coords
	enemy.view->setPosition(ePos);
}
示例#8
0
void BattleManagerScreen::PerformPlayerAi( GameEntity* player )
{
	//select ability
	std::vector<CastCommandState*> abilities;
	abilities = player->getAbilityList();

	if( abilities.size() == 0 ) return; //no abilities, nothing to do

	CastCommandState* cast = abilities[ rand() % abilities.size() ];

	ICastEntity* target = NULL;
	if( player->getTarget()->getEntityList().size() > 0 )
		target = player->getTarget()->getEntityList()[0];
	if( !CastWorldModel::get()->isValid( target ) )
	{
		player->getTarget()->clearTargetEntities();

		if( m_enemies.size() > 0 ) {

			//target closest enemy
			target = m_enemies[0].model;
			kmVec2 distVec;
			GetVecBetween(player, target, distVec);
			float closestEnemy = kmVec2Length( &distVec );

			for( int i=1; i< m_enemies.size(); i++)
			{
				GetVecBetween(player, m_enemies[i].model, distVec);
				float distTo = kmVec2Length( &distVec );

				if( distTo < closestEnemy ) {
					closestEnemy = distTo;
					target = m_enemies[i].model;
				}
				
			}

			
			player->getTarget()->addTargetEntity(target);
		}
	}

	kmVec2 toTarget;
	if( GetVecBetween(player, target, toTarget) && player->canCast() && cast->canAfford() ) {
		
		float dTargetSq = kmVec2LengthSq( &toTarget );
		float range = cast->getRange();

		float meleeRange = 1.0f;

		if( range*range >= dTargetSq ) {
		
			bool dontCast = false;
			if( cast->getName().compare("Death Grip") == 0 )
			{
				//abort if in melee range already
				if( dTargetSq <= meleeRange*meleeRange ) {
					dontCast = true;
					//CCLog("target in melee range, abort death grip");
				}
			}
			else if( cast->getName().compare("Curse of Weakness") == 0 ) {
				//abort if already has curse of weakness and time left greater than 2s
				GameEntity* geTarget = dynamic_cast<GameEntity*>(target);
				if( geTarget != NULL ) {
					float lt = geTarget->getDebuffTimeLeft("Curse of Weakness");
					if( lt > 2 ) 
						dontCast = true;
				}
			}

#ifndef DISABLE_ATTACKS
			if( !dontCast ) {
				cast->startCast();
			}
#endif
		}

	}


}