bool LaserPhysicsComponent::testIntersectionWithAsteroid(Laser &laser, Asteroid &asteroid) { D3DXVECTOR3 currLaserPos = laser.getPosition(), lastLaserPos = laser.getLastPosition(), laserDir = laser.getDirection(), asteroidPosition = asteroid.getPosition(); float asteroidRadius = getAsteroidBoundingSphereRadius(asteroid); float asteroidPosToLaserEnd; //check if the laser ray intersects a rough bounding sphere of the asteroid if (!D3DXSphereBoundProbe(&asteroidPosition, asteroidRadius, &lastLaserPos, &laserDir)) { return false; } asteroidPosToLaserEnd = D3DXVec3LengthSq(&(currLaserPos - asteroidPosition)); //if this is true then the laser's current position does not fall within the sphere, and a ray starting at the laser's //current point crosses the circle. A ray starting at the last point already crosses the sphere, so this means both //points are "before" the sphere, along the ray in the direction the laser is travelling. if (asteroidRadius * asteroidRadius < asteroidPosToLaserEnd && D3DXSphereBoundProbe(&asteroidPosition, asteroidRadius, &currLaserPos, &laserDir)) { return false; } //it may have collided. Now check ray against mesh shared_ptr<GraphicsComponent> gfx = asteroid.getGraphicsComponent(); AsteroidGraphicsComponent *asteroidGraphicsComponent = dynamic_cast<AsteroidGraphicsComponent*>(gfx.get()); if (asteroidGraphicsComponent == NULL) { throw "Asteroid didn't have a valid asteroid graphics component!"; } BOOL hit; float dist; D3DXVECTOR3 laserPosRelativeToAsteroid = lastLaserPos - asteroidPosition; D3DXVECTOR3 asteroidScale = asteroid.getScale(); D3DXQUATERNION rotationQuat = asteroid.getRotationQuat(); D3DXMATRIX rot, scale; D3DXMatrixScaling(&scale, 0.8f/asteroidScale.x, 0.8f/asteroidScale.y, 0.8f/asteroidScale.z); D3DXMatrixRotationQuaternion(&rot, &rotationQuat); D3DXVec3TransformCoord(&laserPosRelativeToAsteroid, &laserPosRelativeToAsteroid, &(scale * rot)); D3DXIntersect(asteroidGraphicsComponent->getMesh(), &laserPosRelativeToAsteroid, &laserDir, &hit, NULL, NULL, NULL, &dist, NULL, NULL); float distTravelledSq = D3DXVec3LengthSq(&(currLaserPos - lastLaserPos)); if (!hit || dist * dist > D3DXVec3LengthSq(&(currLaserPos - lastLaserPos))) { return false; } return true; }
void GunTurret::updateLasers(float elapsedtime/*, MapLoader& m_map, Player& p*/) { m_lasergentime += elapsedtime; m_lasersit = m_lasers.begin(); //bool switchhit = false; while (m_lasersit != m_lasers.end()) { //cout << "Number of lasers: " << m_lasers.size(); Laser* l = *m_lasersit; Vector3 pos = l->getPosition(); //Vector3 startpos = l->getStartPosition(); //pos = pos - startpos; if (2500.0f > fabs(pos.x())) if(2500.0f > fabs(pos.y())) if (2500.0f > fabs(pos.z())) { Vector3 planenormal; //if (m_map.checkLaserCollision(l->getBbox(), l->getDirection(), switchhit, planenormal, p, false)) //{ // if (17.5 > l->getLifeTime() && !switchhit) // { // //Create scorch mark at the spot of the laser // createScorchMark(l->getPosition(), -planenormal); // } // //Setup particle system when laser hits something // ParticleSystemManager* psm = getWriteableGameResource()->getParticleSystemManager(); // ParticleEmitter* pe = psm->createEmitter(l->getPosition(), planenormal); // pe->setMaxParticles(5.0f); // pe->setEmissionRate(5.0f); // pe->setParticleStartColor(Color::red()); // pe->setParticleKey1Color(Color::red()); // pe->setParticleKey2Color(Color::red()); // pe->setParticelEndColor(Color::red()); // pe->setParticleKey1Pos(0.33f); // pe->setParticleKey2Pos(0.66f); // pe->setParticleLifetime(1.0f); // pe->setLifeTime(1.0f); // pe->setParticleSize(0.75f); // pe->setStartVelocity(7.5f); // pe->setSpreadAngle(90.0f); // pe->setAlive(true); // //MSG_TRACE_CHANNEL("", sizeof(ParticleEmitter) << endl; // eraseLaser(m_lasersit, l); // continue; //} //l->move(elapsedtime); m_lasersit++; } else eraseLaser(m_lasersit, l); else eraseLaser(m_lasersit, l); else eraseLaser(m_lasersit, l); } m_scorchit = m_scorchmarks.begin(); while (m_scorchit != m_scorchmarks.end()) { //cout << "Number of lasers: " << m_lasers.size(); ScorchMark* sm = *m_scorchit; if (sm->getLifetime() < 0.0f) { delete sm; m_scorchit = m_scorchmarks.erase(m_scorchit); continue; } //sm->move(elapsedtime); update of the scorch mark takes care of this m_scorchit++; } }