bool CollisionDetector::CylinderSphereCollision(PhysicsNode& p0, PhysicsNode& p1, CollisionData* data) { CollisionCylinder& cylinder = *(CollisionCylinder*)p0.GetCollisionVolume(); CollisionSphere& sphere = *(CollisionSphere*)p1.GetCollisionVolume(); Vector3 cylCenterVector = cylinder.GetEnd() - cylinder.GetStart(); Vector3 pos1 = p1.GetPosition() - cylinder.GetStart(); float distanceFactorFromEP1 = Vector3::Dot(p1.GetPosition() - cylinder.GetStart(), cylCenterVector) / Vector3::Dot(cylCenterVector, cylCenterVector); if(distanceFactorFromEP1 < 0) distanceFactorFromEP1 = 0;// clamp to endpoints if neccesary if(distanceFactorFromEP1 > 1) distanceFactorFromEP1 = 1; Vector3 closestPoint = cylinder.GetStart() + (cylCenterVector * distanceFactorFromEP1); Vector3 collisionVector = p1.GetPosition() - closestPoint; float distance = collisionVector.Length(); Vector3 collisionNormal = collisionVector / distance; if(distance < sphere.GetRadius() + cylinder.GetRadius()) { //collision occurred. use collisionNormal to reflect sphere off cyl float factor = Vector3::Dot(p1.GetLinearVelocity(), collisionNormal); p1.SetLinearVelocity(p1.GetLinearVelocity() - (collisionNormal * factor * 0.8f)); const float distSq = LengthSq(collisionNormal); //get the max distance before collision const float sumRadius = sphere.GetRadius() + cylinder.GetRadius(); p1.SetPosition(p1.GetPosition() + Vector3(collisionNormal * (sumRadius - sqrtf(distSq)))); return true; } return false; }
GameEntity* MyGame::ShotProjectile(float msec){ GameEntity* g = new MoveSphere(new Cube(), new MoveSpherePhy(Quaternion::AxisAngleToQuaterion(Vector3(0, 1, 0), 0.0f),Vector3(100,0,0))); SceneNode* s = &g->GetRenderNode(); PhysicsNode* p = &g->GetPhysicsNode(); Vector3 CamDir = gameCamera->GetCamDir(); s->SetColour(Vector4(0, 0, 1, 1)); s->type = 1; s->SetBoundingRadius(50); s->SetTransform(Matrix4::Translation(Vector3(1, 1, 1)) * Matrix4::Rotation( 270.0f, Vector3(1, 0, 0))); s->SetModelScale(Vector3(10,10,20)); p->SetDimension(s->GetModelScale()); m_speed = m_speed * 1000; p->SetInverseMass(9.0f); p->SetSphereRadius(50); p->AddForce(CamDir * 7000); p->SetPosition(gameCamera->GetPosition()); p->SetOrientation(Quaternion::EulerAnglesToQuaternion(gameCamera->GetPitch(), gameCamera->GetYaw(), 0.0)); p->isMissile = true; g->ConnectToSystems(); return g; }
void TerrainClass::BuildFloorEntity() { for (int i = 0; i < ChunckManager::NUM_VOXEL_CHUNCKS; i++) { SceneNode* sNode = new SceneNode(); sNode->SetMesh(terrain->getMeshAt(i)); sNode->SetModelScale(Vector3(SCALE_TERRAIN, SCALE_TERRAIN, SCALE_TERRAIN)); PhysicsNode* pNode = new PhysicsNode(); pNode->SetPosition(START_TERRAIN_POSITION); pNode->SetLinearVelocity(Vector3(0, 0, linearVelocityZ)); pNode->setLD(false); pNode->setSkyBox(true); terrainPhysicsNodes.push_back(pNode); countTerrainEntities++; GameEntity* geFirst = new GameEntity(sNode, pNode); geFirst->ConnectToSystems(); terrainEntities.push_back(geFirst); //add the id of the chunck just created //terrainChuncksId.push_back(geFirst->getId()); //reset the chunck id to be the same as the entity added; for consistency purposes //terrain->getChunckAt(i)->setId(i); } }