void CollisionSystem::CollideBodies(std::shared_ptr<Entity> entity1, std::shared_ptr<Entity> entity2) { LOG_D("[CollisionSystem] Colliding entities: " << entity1->GetId() << " and " << entity2->GetId()); auto particleComponent1 = std::static_pointer_cast<ParticleComponent>(Engine::GetInstance().GetSingleComponentOfClass(entity1, "ParticleComponent")); auto particleComponent2 = std::static_pointer_cast<ParticleComponent>(Engine::GetInstance().GetSingleComponentOfClass(entity2, "ParticleComponent")); auto colliderComponent1 = std::static_pointer_cast<ColliderComponent>(Engine::GetInstance().GetSingleComponentOfClass(entity1, "ColliderComponent")); auto colliderComponent2 = std::static_pointer_cast<ColliderComponent>(Engine::GetInstance().GetSingleComponentOfClass(entity2, "ColliderComponent")); float radius1 = colliderComponent1->GetRadius(); float radius2 = colliderComponent2->GetRadius(); Vector position1 = particleComponent1->GetPosition(); Vector position2 = particleComponent2->GetPosition(); float distance = position1.CalculateDistance(position2); float difference = radius1 + radius2 - distance; Vector direction = position2 - position1; direction.Normalize(); // Applying force contrary to the collision direction. This force should // depend on the energy of the collision float forceMag = 100; Vector force1 = direction*(-forceMag); Vector force2 = direction*(forceMag); particleComponent1->SetForce(force1); particleComponent2->SetForce(force2); // Avoiding overlapping position1 += direction*(-difference/2); position2 += direction*(difference/2); particleComponent1->SetPosition(position1); particleComponent2->SetPosition(position2); }
//下がってきて停滞して上がっていく void Enemy::MoverDownToUp(){ VECTOR force={0,0,0}; if(mObjCount == 0){ force.y = mObjMoveSpeed; SetForce(&force); mObjTransform.SetAngle(90 * M_PI/180); } if(mObjCount == 40){ SetForce(&force); } if(mObjCount == 40+mState.WaitTime){ SetForce(&force); mObjTransform.SetAngle(-90 * M_PI/180); } }
void CollisionSystem::EmitParticles(std::shared_ptr<Entity> entity) { auto particleComponent = std::static_pointer_cast<ParticleComponent>(Engine::GetInstance().GetSingleComponentOfClass(entity, "ParticleComponent")); auto spriteComponents = Engine::GetInstance().GetComponentsOfClass(entity, "SpriteComponent"); auto complexityComponent = std::static_pointer_cast<ComplexityComponent>(Engine::GetInstance().GetSingleComponentOfClass(entity, "ComplexityComponent")); if (spriteComponents.size() == 1) return; Engine::GetInstance().GetEntityManager()->DeleteComponentsOfClass(entity, "SpriteComponent"); Engine::GetInstance().AddComponent(spriteComponents[0], entity); for (unsigned int i = 1; i < spriteComponents.size(); ++i) { auto sprite = std::static_pointer_cast<SpriteComponent>(spriteComponents[i]); Vector cellParticlePosition = sprite->GetPosition(); cellParticlePosition.Rotate(particleComponent->GetAngle()); cellParticlePosition += particleComponent->GetPosition(); Vector cellParticleForce = sprite->GetPosition(); cellParticleForce.Rotate(particleComponent->GetAngle()); cellParticleForce.Normalize(); cellParticleForce *= CFG_GETF("COMPLEXITY_PARTICLE_EMIT_FORCE")*particleComponent->GetVelocity().GetMagnitude()/500; auto cellParticle = EntityFactory::CreateCellParticle(cellParticlePosition); auto cellParticleComponent = std::static_pointer_cast<ParticleComponent>(Engine::GetInstance().GetSingleComponentOfClass(cellParticle, "ParticleComponent")); cellParticleComponent->SetForce(cellParticleForce); cellParticleComponent->SetVelocity(particleComponent->GetVelocity()); } complexityComponent->SetComplexity(0); }
void Ship::Blastoff() { if (m_flightState != LANDED) return; ClearThrusterState(); m_flightState = FLYING; m_testLanded = false; m_dockedWith = 0; m_launchLockTimeout = 2.0; // two second of applying thrusters vector3d up = GetPosition().Normalized(); Enable(); assert(GetFrame()->m_astroBody->IsType(Object::PLANET)); const double planetRadius = 2.0 + static_cast<Planet*>(GetFrame()->m_astroBody)->GetTerrainHeight(up); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetForce(vector3d(0, 0, 0)); SetTorque(vector3d(0, 0, 0)); Aabb aabb; GetAabb(aabb); // XXX hm. we need to be able to get sbre aabb SetPosition(up*planetRadius - aabb.min.y*up); SetThrusterState(1, 1.0); // thrust upwards Pi::luaOnShipTakeOff->Queue(this, GetFrame()->m_astroBody); }
RigidBody::RigidBody(Rect rect) { float width = (rect.right - rect.left); float height = (rect.bottom - rect.top); // Create a Rectangle shape - origin middle mShape = new Shape(); mShape->setOrigin(Vector(rect.left + width/2, rect.top + height/2, 0)); mShape->addPoint(Vector(-width/2, -height/2, 0)); // top - left mShape->addPoint(Vector(-width/2, height/2, 0)); // bottom - left mShape->addPoint(Vector(width/2, height/2, 0)); // bottom - right mShape->addPoint(Vector(width/2, -height/2, 0)); // top - right setStatic(false); mAlive = true; mTexture = NULL; SetMass(1); SetVelocity(0, 0); SetAngularVelocity(0.0f); SetForce(Vector(0, 0, 0)); SetTorque(Vector(0, 0, 0)); SetMomentum(Vector(0, 0, 0)); SetFriction(1.0f); SetSleeping(false); }
void CPowerUp::Respawn() { int x, y; CRenderer *pRenderer = CRenderer::Instance(); CUniverse* universe = CODEManager::Instance()->m_pUniverse; do { x = rand()%((int) universe->m_fWidth*2) - (int) universe->m_fWidth; y = rand()%((int) universe->m_fHeight*2) - (int) universe->m_fHeight; } while ( pRenderer->ObjectsInRange( x, y, 100 ) ); Vector v = Vector( (float)x, (float)y, 0.0f ); SetPosition( v ); Vector n; Vector vel((float) (rand() % 10), (float) (rand() % 10), 0); m_oPhysicsData.m_pOwner->SetLinVelocity(vel); SetForce(n); this->m_bIsGrabable = true; this->m_oPhysicsData.m_bHasCollision = true; CSound *pSound = (CSound *)CResourceManager::Instance()->GetResource("media/sounds/powerup_spawn.wav", RT_SOUND); if ( pSound ) pSound->Play(); }
void CAsteroid::Respawn() { int stochast = rand()%100; int sum = 0; bool isRepossed = false; CODEManager* ode = CODEManager::Instance(); for(unsigned int i = 0; i < ode->m_pUniverse->m_vRespawnAreas.size(); i++) { if(isRepossed) continue; sum += ode->m_pUniverse->m_vRespawnAreas[i].chance; if(stochast < sum) { ReposAtArea(ode->m_pUniverse->m_vRespawnAreas[i]); isRepossed = true; } } if(!isRepossed) ReposAtOrbit(); Vector n; m_oPhysicsData.m_pOwner->SetLinVelocity(n); m_oPhysicsData.m_pOwner->SetAngVelocity(n); SetForce(n); m_fThrowTime = 0; m_fTemperatureTime = 0.0f; m_iMilliSecsInOrbit = 0; m_iWallBounces = 0; m_pHoldingPlayer = NULL; m_pThrowingPlayer = NULL; SetDepth(-1.0); SetAlpha(1.0); }
// 下に下る void Enemy::MoverDown(){ if(mObjCount == 0){ VECTOR force={0,mObjMoveSpeed,0}; SetForce(&force); mObjTransform.SetAngle(90 * M_PI/180); } }
// ひたすら右へ void Enemy::MoverRight(){ if(mObjCount == 0){ VECTOR force={mObjMoveSpeed,0,0}; SetForce(&force); mObjTransform.SetAngle(0 * M_PI/180); } }
void RigidBody::ApplyForce(Vector force, Vector pos) { SetForce(GetForce() + force); // Torque = r x F //SetTorque(force.cross(pos)); SetTorque((pos - GetPosition()).cross(force)); }
// ゆらゆら揺れながら降りてくる void Enemy::MoverCos(){ VECTOR force={0,0,0}; SetForce(&force); mObjTransform.SetAngle((360 * (mObjCount % 180/180.0)) * M_PI/180.0); VECTOR point; mObjTransform.SetX(mObjTransform.GetX() + (float)cos(mObjTransform.GetAngle())*mObjMoveSpeed); mObjTransform.SetY(mObjTransform.GetY() + mObjMoveSpeed); }
// the end application need to overload this function from dNetwonDynamicBody void OnForceAndTorque (dFloat timestep, int threadIndex) { // apply gravity force to the body dFloat mass; dFloat Ixx; dFloat Iyy; dFloat Izz; GetMassAndInertia (mass, Ixx, Iyy, Izz); dVector gravityForce (0.0f, -9.8f * mass, 0.0f, 0.0f); SetForce (&gravityForce[0]); }
void Ship::TestLanded() { m_testLanded = false; if (m_launchLockTimeout > 0.0f) return; if (m_wheelState < 1.0f) return; if (GetFrame()->GetBodyFor()->IsType(Object::PLANET)) { double speed = GetVelocity().Length(); vector3d up = GetPosition().Normalized(); const double planetRadius = static_cast<Planet*>(GetFrame()->GetBodyFor())->GetTerrainHeight(up); if (speed < MAX_LANDING_SPEED) { // orient the damn thing right // Q: i'm totally lost. why is the inverse of the body rot matrix being used? // A: NFI. it just works this way matrix4x4d rot; GetRotMatrix(rot); matrix4x4d invRot = rot.InverseOf(); // check player is sortof sensibly oriented for landing const double dot = vector3d(invRot[1], invRot[5], invRot[9]).Normalized().Dot(up); if (dot > 0.99) { Aabb aabb; GetAabb(aabb); // position at zero altitude SetPosition(up * (planetRadius - aabb.min.y)); vector3d forward = rot * vector3d(0,0,1); vector3d other = up.Cross(forward).Normalized(); forward = other.Cross(up); rot = matrix4x4d::MakeRotMatrix(other, up, forward); rot = rot.InverseOf(); SetRotMatrix(rot); SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); SetForce(vector3d(0, 0, 0)); SetTorque(vector3d(0, 0, 0)); // we don't use DynamicBody::Disable because that also disables the geom, and that must still get collisions DisableBodyOnly(); ClearThrusterState(); m_flightState = LANDED; Sound::PlaySfx("Rough_Landing", 1.0f, 1.0f, 0); Pi::luaOnShipLanded->Queue(this, GetFrame()->GetBodyFor()); } } } }
RigidBody::RigidBody(float x, float y, int width, int height) { // Create a Rectangle shape - origin middle mShape = new Shape(); mShape->setOrigin(Vector(x, y, 0)); mShape->addPoint(Vector(-width/2, -height/2, 0)); // top - left mShape->addPoint(Vector(-width/2, height/2, 0)); // bottom - left mShape->addPoint(Vector(width/2, height/2, 0)); // bottom - right mShape->addPoint(Vector(width/2, -height/2, 0)); // top - right SetMass(1); SetVelocity(0, 0); SetAngularVelocity(0.0f); SetForce(Vector(0, 0, 0)); SetTorque(Vector(0, 0, 0)); SetFriction(1.0f); SetFriction(0.5f), SetSimulate(true); SetOwner(NULL); }
RigidBody::RigidBody(float x, float y, int width, int height) { // Create a Rectangle shape - origin middle mShape = new Shape(); mShape->setOrigin(Vector(x, y, 0)); mShape->addPoint(Vector(-width/2, -height/2, 0)); // top - left mShape->addPoint(Vector(-width/2, height/2, 0)); // bottom - left mShape->addPoint(Vector(width/2, height/2, 0)); // bottom - right mShape->addPoint(Vector(width/2, -height/2, 0)); // top - right setStatic(false); mAlive = true; SetMass(1); SetVelocity(0, 0); SetAngularVelocity(0.0f); SetForce(Vector(0, 0, 0)); SetTorque(Vector(0, 0, 0)); SetMomentum(Vector(0, 0, 0)); SetFriction(1.0f); SetSleeping(false); SetRepeatX(false); }
void OgreNewtonDynamicBody::OnForceAndTorque (dFloat timestep, int threadIndex) { const OgreNewtonWorld* const world = (OgreNewtonWorld*) GetNewton(); SetForce (world->GetGravity() * GetMass()); }