/// \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; }
// 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); }