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;
}
Beispiel #2
0
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++;
    }
}