Esempio n. 1
0
/// \param angles The orientation (unit) vector that you want to reflect
/// \return Euler angles that are reflected about the slope of the plane.
EulerAngles Plane::reflectOrientation(const EulerAngles& angles) const
{
  EulerAngles out;
  Vector3 look, up, right;  
  RotationMatrix rotMat;
    
  // get look and up vector from euler angles
  rotMat.setup(angles); 
  look = rotMat.objectToInertial(Vector3(0.0f,0.0f,1.0f));
  up = rotMat.objectToInertial(Vector3(0.0f,1.0f,0.0f));

  // reflect the look and up vectors over the plane
  look = reflectOrientation(look);
  up = -reflectOrientation(up); 
  
  // calculate right vector
  right = Vector3::crossProduct( up, look);
  right.normalize();
    
  // create a rotation matrix from right, up, and look
  rotMat.m11 = right.x; rotMat.m12 = right.y; rotMat.m13 = right.z;
  rotMat.m21 = up.x; rotMat.m22 = up.y; rotMat.m23 = up.z;
  rotMat.m31 = look.x; rotMat.m32 = look.y; rotMat.m33 = look.z;
  
  // calculate new euler angles from the matrix
  out.fromRotationMatrix(rotMat);

  return out;
}
Esempio n. 2
0
// Resets camera to behind target object
void TetherCamera::reset() 
{
  Vector3 target;
  float targetHeading;

  assert(m_objects); // object manager doesn't exist
  GameObject* obj = m_objects->getObjectPointer(m_targetObjectID);    
  
  assert(obj); // object to follow doesn't exist  
  targetHeading = obj->getOrientation().heading;
  target = obj->getPosition();

  
  target.y += 3.0f;

  cameraOrient.set(targetHeading, 0.0f,0.0f);

  RotationMatrix cameraMatrix;
  cameraMatrix.setup(cameraOrient);

  Vector3 bOffset(0.0f,0.0f, -maxDist);
  
  Vector3 iOffset = cameraMatrix.objectToInertial(bOffset);
  cameraPos = target + iOffset;
}
void BulletObject::updateRay()
{
  EulerAngles lookEuler = getOrientation();
  lookEuler.bank = 0.0f;
  RotationMatrix look;
  look.setup(lookEuler);
  m_bulletRay = look.objectToInertial(Vector3(0.0f,0.0f,m_range));
}
bool Ned3DObjectManager::interactPlaneTerrain(PlaneObject &plane, TerrainObject &terrain)
{
  Terrain *terr = terrain.getTerrain();
  if(terr == NULL) return false;

  //test for plane collision with terrain
  Vector3 planePos = plane.getPosition();
  EulerAngles planeOrient = plane.getOrientation();
  Vector3 disp = planePos - disp;
  RotationMatrix planeMatrix;
  planeMatrix.setup(plane.getOrientation()); // get plane's orientation

  float planeBottom = plane.getBoundingBox().min.y;
  float terrainHeight = terr->getHeight(planePos.x,planePos.z);
  if(plane.isPlaneAlive() && planeBottom < terrainHeight)
  { //collision
    Vector3 viewVector = planeMatrix.objectToInertial(Vector3(0,0,1));
    if(viewVector * terr->getNormal(planePos.x,planePos.z) < -0.5f // dot product
      || plane.isCrashing())
    { 
      plane.killPlane();
      int partHndl = gParticle.createSystem("planeexplosion");
      gParticle.setSystemPos(partHndl, plane.getPosition());
      int boomHndl = gSoundManager.requestSoundHandle("Boom.wav");
      int boomInst = gSoundManager.requestInstance(boomHndl);
      if(boomInst != SoundManager::NOINSTANCE)
      {
        gSoundManager.setPosition(boomHndl,boomInst,plane.getPosition());
        gSoundManager.play(boomHndl,boomInst);
        gSoundManager.releaseInstance(boomHndl,boomInst);
      }
      plane.setSpeed(0.0f);
      planePos += 2.0f * viewVector;
      planeOrient.pitch = kPi / 4.0f;
      planeOrient.bank = kPi / 4.0f;
      plane.setOrientation(planeOrient);
    }
    else planePos.y = terrainHeight + planePos.y - planeBottom;
    //plane.setPPosition(planePos);
    return true;
  }
  return false;
}
void PlaneObject::damage(int hp)
{
  // if god mode is on leave 
  if (!takeDamage)
    return;

  m_hp -= hp;
  setTextureAndSmoke(); // change to a texture with more damange on it
        
  if(m_isPlaneAlive && m_hp <= 0)
  {
    m_planeState = PS_CRASHING;
    m_velocity = Vector3::kForwardVector;
    m_eaOrient[0].pitch = degToRad(20);
    RotationMatrix r; r.setup(m_eaOrient[0]);
    m_velocity = r.objectToInertial(m_velocity);
    m_velocity *= m_maxSpeed * m_speedRatio * 20.0f;
  }
}
bool Ned3DObjectManager::interactPlaneWater(PlaneObject &plane, WaterObject &water)
{
  Water *pWater = water.getWater();
  if(pWater == NULL) return false;
  
  // Test for plane collision with water
  
  Vector3 planePos = plane.getPosition();
  EulerAngles planeOrient = plane.getOrientation();
  Vector3 disp = planePos - disp;
  RotationMatrix planeMatrix;
  planeMatrix.setup(plane.getOrientation()); // get plane's orientation
  float planeBottom = plane.getBoundingBox().min.y;
  float waterHeight = pWater->getWaterHeight();
  
  if(plane.isPlaneAlive() && planeBottom < waterHeight)
  { //collision
    Vector3 viewVector = planeMatrix.objectToInertial(Vector3(0,0,1));
    plane.killPlane();
    plane.setSpeed(0.0f);
    planePos += 2.0f * viewVector;
    planeOrient.pitch = kPi / 4.0f;
    planeOrient.bank = kPi / 4.0f;
    plane.setOrientation(planeOrient);
    plane.setPPosition(planePos);
    
    int partHndl = gParticle.createSystem("planeexplosion");
    gParticle.setSystemPos(partHndl, plane.getPosition());
    int boomHndl = gSoundManager.requestSoundHandle("Boom.wav");
    int boomInst = gSoundManager.requestInstance(boomHndl);
    if(boomInst != SoundManager::NOINSTANCE)
    {
      gSoundManager.setPosition(boomHndl,boomInst,plane.getPosition());
      gSoundManager.play(boomHndl,boomInst);
      gSoundManager.releaseInstance(boomHndl,boomInst);
    }
    return true;
  }
  return false;
}
/// Rendering the particles involves looping through every live particle
/// and writing it's relevant data to a vertex buffer, and then rendering
/// that vertex buffer.
void ParticleEffect::render()
{
    if(m_nLiveParticleCount == 0) // make sure we have something to render
        return;

    if(m_sort)
        sort();

    // save render states before starting
    DWORD lighting;
    DWORD alphablend;
    DWORD zwrite;
    DWORD zenable;
    DWORD srcblend;
    DWORD destblend;

    pD3DDevice->GetRenderState(D3DRS_LIGHTING, &lighting);
    pD3DDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &alphablend);
    pD3DDevice->GetRenderState(D3DRS_ZWRITEENABLE, &zwrite);
    pD3DDevice->GetRenderState(D3DRS_ZENABLE, &zenable);
    pD3DDevice->GetRenderState(D3DRS_SRCBLEND, &srcblend);
    pD3DDevice->GetRenderState(D3DRS_DESTBLEND, &destblend);

    // set up particle engine states
    pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    if(m_sort)
        pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
    else
        pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
    pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    //pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    //pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);

    // set texture operations for alpha blending by setting the color
    // to texture color times diffuse color, and alpha taken entirely from
    // texture value
    pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
    pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
    pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
    pD3DDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
    pD3DDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
    pD3DDevice->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);

    // get camera right and up vectors to figure out how to orient the sprites
    D3DXMATRIXA16 view;
    pD3DDevice->GetTransform(D3DTS_VIEW, &view);

    Vector3 vecRight = Vector3(view._11, view._21, view._31);
    Vector3 vecUp = Vector3(view._12, view._22, view._32);
    Vector3 vecForward = Vector3(view._13, view._23, view._33);

    // precalculate corners
    Vector3 ul, ur, bl, br;
    //ul = -vecRight + vecUp; // upper left
    //ur = vecRight + vecUp;  // upper right
    //bl = -vecRight - vecUp; // bottom left
    //br = vecRight - vecUp;  // bottom right

    pD3DDevice->SetTexture(0, m_txtParticleTexture);

    if(!m_vertBuffer->lock())
    {
        return;
    }

    // shorthand to the current vertex
    RenderVertexL *vert = &((*m_vertBuffer)[0]);

    // although these values are the same for all particles (except color.alpha),
    // you could implement some randomness, at which point there would be a
    // reason to assign to them with every iteration of the loop
    unsigned int color;
    float size = m_fPISize/2.0f; // half of m_fPISize in each direction
    float tTop = 0;
    float tBottom = 1.0f;
    float tLeft = 0;
    float tRight = 1.0f;

    // loop through all live particles to assign proper values to the vertices
    for (int i=0; i<m_nLiveParticleCount; i++)
    {
        Vector3 pos = m_Particles[m_drawOrder[i]].position;
        color = m_Particles[m_drawOrder[i]].color;

        Vector3 myUp, myRight;
        Quaternion q;
        q.setToRotateAboutAxis(vecForward, m_Particles[m_drawOrder[i]].rotation);

        RotationMatrix r;
        r.fromObjectToInertialQuaternion(q);

        myUp = r.objectToInertial(vecUp);
        myRight = r.objectToInertial(vecRight);

        ul = -myRight + myUp; // upper left
        ur = myRight + myUp;  // upper right
        bl = -myRight - myUp; // bottom left
        br = myRight - myUp;  // bottom right

        vert->p = pos + ul*size;
        vert->argb = color;
        vert->u = tLeft;
        vert->v = tTop;
        vert++;

        vert->p = pos + ur*size;
        vert->argb = color;
        vert->u = tRight;
        vert->v = tTop;
        vert++;

        vert->p = pos + bl*size;
        vert->argb = color;
        vert->u = tLeft;
        vert->v = tBottom;
        vert++;

        vert->p = pos + br*size;
        vert->argb = color;
        vert->u = tRight;
        vert->v = tBottom;
        vert++;
    }

    m_vertBuffer->unlock();

    gRenderer.render(
        m_vertBuffer,
        m_nLiveParticleCount * 4,
        m_indexBuffer,
        m_nLiveParticleCount * 2);

    // restore render states
    pD3DDevice->SetRenderState(D3DRS_LIGHTING, lighting);
    pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, alphablend);
    pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, zwrite);
    pD3DDevice->SetRenderState(D3DRS_ZENABLE, zenable);
    pD3DDevice->SetRenderState(D3DRS_SRCBLEND, srcblend);
    pD3DDevice->SetRenderState(D3DRS_DESTBLEND, destblend);

}