예제 #1
0
    void DynamicsWorld::AddRigidBody(RigidBody &body, short group, short mask)
    {
        auto prevWorld = body.GetWorld();
        if (prevWorld != nullptr)
        {
            prevWorld->RemoveRigidBody(body);
        }

        body.SetWorld(this);
        this->world.addRigidBody(&body, group, mask);
    }
void RocketControllerSystem::processEntities(const vector<Entity*>& p_entities)
{
	float dt = m_world->getDelta();
	float waitUntilActivation = 0.5f;
	float rocketMaxAge = 15.0f;
	for (unsigned int i = 0; i < p_entities.size(); i++)
	{
		StandardRocket* rocket = static_cast<StandardRocket*>(p_entities[i]->getComponent(ComponentType::StandardRocket));

		if (rocket->m_age == 0)
		{
			//Align with movement direction
			MeshOffsetTransform* meshOffset = static_cast<MeshOffsetTransform*>
				( p_entities[i]->getComponent( ComponentType::MeshOffsetTransform) );

			PhysicsBody* pb = static_cast<PhysicsBody*>(p_entities[i]->getComponent(ComponentType::PhysicsBody));
			PhysicsSystem* ps = static_cast<PhysicsSystem*>(m_world->getSystem(SystemType::PhysicsSystem));
			RigidBody* body = static_cast<RigidBody*>(ps->getController()->getBody(pb->m_id));
			AglMatrix world = body->GetWorld();

			world = meshOffset->offset.inverse()*world;
			world = pb->getOffset()*world;
			body->setTransform(world);
		}

		rocket->m_age += dt;
		//Check collision
		if (rocket->m_age > waitUntilActivation && rocket->m_age <= rocketMaxAge)
		{
			//Start targeting ships
			PhysicsBody* pb = static_cast<PhysicsBody*>(p_entities[i]->getComponent(ComponentType::PhysicsBody));
			PhysicsSystem* ps = static_cast<PhysicsSystem*>(m_world->getSystem(SystemType::PhysicsSystem));
			RigidBody* body = static_cast<RigidBody*>(ps->getController()->getBody(pb->m_id));

			if (rocket->m_target >= 0)
			{
				ShipManagerSystem* shipManager = static_cast<ShipManagerSystem*>(m_world->getSystem(SystemType::ShipManagerSystem));

				Entity* ship = m_world->getEntity(rocket->m_target);

				Transform* from = static_cast<Transform*>(p_entities[i]->getComponent(ComponentType::Transform));
				Transform* to = static_cast<Transform*>(ship->getComponent(ComponentType::Transform));

				//START APPLY IMPULSE

				MeshOffsetTransform* meshOffset = static_cast<MeshOffsetTransform*>
					( p_entities[i]->getComponent( ComponentType::MeshOffsetTransform) );

				AglVector3 imp = to->getTranslation() - from->getTranslation();
				float distance = imp.length();
				imp.normalize();

				AglMatrix world = meshOffset->offset * pb->getOffset().inverse() * body->GetWorld();

				AglVector3 rotAxis = AglVector3::crossProduct(imp, -world.GetForward());
				rotAxis.normalize();

				//Compute fraction of turn power that should be applied
				AglVector3 angVel = body->GetAngularVelocity();

				float angVelAxis = max(AglVector3::dotProduct(angVel, rotAxis), 0);

				float amountToRotate = min(1.0f - AglVector3::dotProduct(imp, world.GetForward()), 1.0f); //0 -> 1

				float frac = 1.0f;
				if (amountToRotate / angVelAxis < 0.25f)
				{
					frac = (amountToRotate / angVelAxis) / 0.25f;
				}

				rotAxis *= m_turnPower * dt * frac;

				frac = 1-frac;

				AglVector3 impulse = imp*0.25f + world.GetForward();
				impulse.normalize();
				impulse *= dt*m_enginePower*frac;

				ps->getController()->ApplyExternalImpulse(pb->m_id, impulse, rotAxis);
			}
			else
			{
				MeshOffsetTransform* meshOffset = static_cast<MeshOffsetTransform*>
					( p_entities[i]->getComponent( ComponentType::MeshOffsetTransform) );

				AglMatrix world = meshOffset->offset * pb->getOffset().inverse() * body->GetWorld();
				AglVector3 impulse = world.GetForward() * m_enginePower * dt;
				ps->getController()->ApplyExternalImpulse(pb->m_id, impulse, AglVector3(0, 0, 0));
			}


			//END APPLY IMPULSE

			//Check collision	
			vector<unsigned int> cols = ps->getController()->CollidesWith(pb->m_id);
			bool staticCol = ps->getController()->CollidesWithStaticEnvironment(pb->m_id);
			if (cols.size() > 0 || staticCol)
			{
				explodeRocket(ps, pb, body, p_entities[i]);
			}
		}// if (rocket->m_age > waitUntilActivation && rocket->m_age <= rocketMaxAge)
		else if(rocket->m_age > rocketMaxAge)
		{
			PhysicsBody* pb = static_cast<PhysicsBody*>(p_entities[i]->getComponent(ComponentType::PhysicsBody));
			PhysicsSystem* ps = static_cast<PhysicsSystem*>(m_world->getSystem(SystemType::PhysicsSystem));
			RigidBody* body = static_cast<RigidBody*>(ps->getController()->getBody(pb->m_id));
			explodeRocket(ps, pb, body, p_entities[i]);
		}
	}
}