// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // - prototype : CMatrix(const CVector3& pos, // const CVector3& xAxis, // const CVector3& yAxis, // const CVector3& zAxis) // // - Purpose : Constructor based on a space position and 3 axis. // // ----------------------------------------------------------------------------- CMatrix::CMatrix(const CVector3& pos, const CVector3& xAxis, const CVector3& yAxis, const CVector3& zAxis) { m_fM[0][0] = xAxis.X(); m_fM[0][1] = xAxis.Y(); m_fM[0][2] = xAxis.Z(); m_fM[0][3] = pos.X(); m_fM[1][0] = yAxis.X(); m_fM[1][1] = yAxis.Y(); m_fM[1][2] = yAxis.Z(); m_fM[1][3] = pos.Y(); m_fM[2][0] = zAxis.X(); m_fM[2][1] = zAxis.Y(); m_fM[2][2] = zAxis.Z(); m_fM[2][3] = pos.Z(); m_fM[3][0] = 0.0f; m_fM[3][1] = 0.0f; m_fM[3][2] = 0.0f; m_fM[3][3] = 1.0f; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CPlane // - Prototype : void Build(const CVector3& point, const CVector3& normal) // // - Purpose : Builds a plane given a point laying on it and the plane's // normal. // // --------------------------------------------------------------------------- void CPlane::Build(const CVector3& point, const CVector3& normal) { m_fA = normal.X(); m_fB = normal.Y(); m_fC = normal.Z(); m_fD = -((m_fA * point.X()) + (m_fB * point.Y()) + (m_fC * point.Z())); }
// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // // - prototype : bool HasNegativeScale() // // - Purpose : Returns true if matrix has some negative scaling, otherwise // false. // // ----------------------------------------------------------------------------- bool CMatrix::HasNegativeScale() const { CVector3 xAxis = XAxis(); CVector3 yAxis = YAxis(); CVector3 zAxis = ZAxis(); CVector3 c0(xAxis.X(), yAxis.X(), zAxis.X()); CVector3 c1(xAxis.Y(), yAxis.Y(), zAxis.Y()); CVector3 c2(xAxis.Z(), yAxis.Z(), zAxis.Z()); return ((c0 ^ c1) * c2) < 0.0f ? true : false; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // // - prototype : CMatrix Inverse() // // - Purpose : Returns the inverse transformation matrix. // // - Note : IMPORTANT: Algorithm only valid for orthogonal matrices! // // ----------------------------------------------------------------------------- CMatrix CMatrix::Inverse() const { CMatrix result; // Transpose rotation submatrix CVector3 row0(m_fM[0][0], m_fM[1][0], m_fM[2][0]); CVector3 row1(m_fM[0][1], m_fM[1][1], m_fM[2][1]); CVector3 row2(m_fM[0][2], m_fM[1][2], m_fM[2][2]); CVector3 position(m_fM[0][3], m_fM[1][3], m_fM[2][3]); CVector3 invPosition; // Solve ecuation system invPosition.SetX((-row0) * position); invPosition.SetY((-row1) * position); invPosition.SetZ((-row2) * position); // Get scale values CVector3 scale = Scale(); float sqrSclX = scale.X(); sqrSclX *= sqrSclX; float sqrSclY = scale.Y(); sqrSclY *= sqrSclY; float sqrSclZ = scale.Z(); sqrSclZ *= sqrSclZ; // Shouldn't happen: assert(!IS_ZERO(sqrSclX)); assert(!IS_ZERO(sqrSclY)); assert(!IS_ZERO(sqrSclZ)); // Normalize axis and multiply by the inverse scale. row0 = row0 / sqrSclX; row1 = row1 / sqrSclY; row2 = row2 / sqrSclZ; // Insert values result.SetRow0(row0.X(), row0.Y(), row0.Z(), invPosition.X()); result.SetRow1(row1.X(), row1.Y(), row1.Z(), invPosition.Y()); result.SetRow2(row2.X(), row2.Y(), row2.Z(), invPosition.Z()); result.SetRow3( 0.0f, 0.0f, 0.0f, 1.0f); return result; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // // - prototype : void SetPosition(const CVector3& position) // // - Purpose : Sets matrix's position values. // // ----------------------------------------------------------------------------- void CMatrix::SetPosition(const CVector3& position) { m_fM[0][3] = position.X(); m_fM[1][3] = position.Y(); m_fM[2][3] = position.Z(); }
// --[ Method ]--------------------------------------------------------------- // // - Class : CVector3 // - Prototype : bool operator != (const CVector3& vector) const // // - Purpose : Comparison operator // // --------------------------------------------------------------------------- bool CVector3::operator != (const CVector3& vector) const { if(!ARE_EQUAL(vector.X(), m_fX)) return true; if(!ARE_EQUAL(vector.Y(), m_fY)) return true; if(!ARE_EQUAL(vector.Z(), m_fZ)) return true; return false; }
void CTargetingComputer::render() { // Display surround renderQuad(); char strFont[256]; if (m_pTarget) { // Calculate position of targeting reticle CVector3 pos = m_pTarget->m_ppMasses[0]->m_vecPos; // Get viewport int viewport[4]; double modelview[16]; double projection[16]; glGetIntegerv(GL_VIEWPORT,viewport); glGetDoublev(GL_MODELVIEW_MATRIX,modelview); glGetDoublev(GL_PROJECTION_MATRIX,projection); // Project to 2d screen coords double dX, dY, dZ; gluProject(pos.X(),pos.Y(),pos.Z(), modelview, projection, viewport, &dX, &dY, &dZ); // If behind, invert and scale everything up lots to force it to the edge // This could perhaps work better... not too happy, but it's late if (dZ > 1.0f) { dX = -(dX - (viewport[2]/2)) * viewport[2] + viewport[2]/2; dY = -(dY - (viewport[3]/2)) * viewport[3] + viewport[3]/2; } // Clip if (dX < 0) dX = 0; else if (dX > viewport[2]) dX = viewport[2]; if (dY < 0) dY = 0; else if (dY > viewport[3]) dY = viewport[3]; // Rescale to 0..1 dX /= viewport[2]; dY /= viewport[3]; double dW = 32.0f / viewport[2]; double dH = 32.0f / viewport[3]; // Render reticle m_poTargetingReticle->setPosition(dX-dW, (1-dY)-dH, dW*2, dH*2); m_poTargetingReticle->setTexturePercentage(100.0f); m_poTargetingReticle->renderQuad(); // Radar imagexs m_poHoloTarget->renderQuad(); // Calculate range NSDMath::CVector3 vecTarget = m_pTarget->m_ppMasses[0]->m_vecPos - m_pPlayerShip->m_ppMasses[0]->m_vecPos; int iRange = static_cast<int>(vecTarget.length()); // Range sprintf(strFont,"%5d m", iRange); m_poFont->print("Range:", CVector2(0.03f, 0.25f), 0.0075f, CVector3(0,1,0)); m_poFont->print(strFont, CVector2(0.03f, 0.28f), 0.0075f, CVector3(0,1,0)); // Velocity sprintf(strFont,"%5d m/s", static_cast<int>(m_pTarget->m_fVel)); g_oTextureManager.render(m_auiOffScreenTexture); m_poFont->print("Velocity:", CVector2(0.03f, 0.32f), 0.0075f, CVector3(0,1,0)); m_poFont->print(strFont, CVector2(0.03f, 0.35f), 0.0075f, CVector3(0,1,0)); } }
void CStars::draw(CVector3 vecPos) { glPushMatrix(); glTranslatef(vecPos.X(), vecPos.Y(), vecPos.Z()); for (int iCount = 0 ; iCount < m_iNumStars ; iCount++) { if (m_oFrustum.PointInFrustum(m_aoStars[iCount].m_vecPos)) { // Set size m_oSprite.setSize(m_aoStars[iCount].m_fSize); // Set position m_oSprite.setTranslation(m_aoStars[iCount].m_vecPos); // Render m_oSprite.render(); } } glPopMatrix(); }
//************************************************************************************** // Function name : CFrustum::CubeInFrustum // Author : Gary Ingram // Return type : bool // Date Created : 25/05/2003 // Argument : float x // Argument : float y // Argument : float z // Argument : float size // Description : This test is a bit more work, but not too much more // complicated. Basically, what is going on is, that we are // given the center of the cube, and half the length. Think // of it like a radius. Then we checking each point in the // cube and seeing if it is inside the frustum. If a point // is found in front of a side, then we skip to the next // side. If we get to a plane that does NOT have a point in // front of it, then it will return false. *Note* - This // will sometimes say that a cube is inside the frustum when // it isn't. This happens when all the corners of the // bounding box are not behind any one plane. This is rare // and shouldn't effect the overall rendering speed. //************************************************************************************** bool CFrustum::CubeInFrustum(const CVector3& vecCentre, float size ) { for(int i = 0; i < 6; i++ ) { if(m_Frustum[i][A] * (vecCentre.X() - size) + m_Frustum[i][B] * (vecCentre.Y() - size) + m_Frustum[i][C] * (vecCentre.Z() - size) + m_Frustum[i][D] > 0) continue; if(m_Frustum[i][A] * (vecCentre.X() + size) + m_Frustum[i][B] * (vecCentre.Y() - size) + m_Frustum[i][C] * (vecCentre.Z() - size) + m_Frustum[i][D] > 0) continue; if(m_Frustum[i][A] * (vecCentre.X() - size) + m_Frustum[i][B] * (vecCentre.Y() + size) + m_Frustum[i][C] * (vecCentre.Z() - size) + m_Frustum[i][D] > 0) continue; if(m_Frustum[i][A] * (vecCentre.X() + size) + m_Frustum[i][B] * (vecCentre.Y() + size) + m_Frustum[i][C] * (vecCentre.Z() - size) + m_Frustum[i][D] > 0) continue; if(m_Frustum[i][A] * (vecCentre.X() - size) + m_Frustum[i][B] * (vecCentre.Y() - size) + m_Frustum[i][C] * (vecCentre.Z() + size) + m_Frustum[i][D] > 0) continue; if(m_Frustum[i][A] * (vecCentre.X() + size) + m_Frustum[i][B] * (vecCentre.Y() - size) + m_Frustum[i][C] * (vecCentre.Z() + size) + m_Frustum[i][D] > 0) continue; if(m_Frustum[i][A] * (vecCentre.X() - size) + m_Frustum[i][B] * (vecCentre.Y() + size) + m_Frustum[i][C] * (vecCentre.Z() + size) + m_Frustum[i][D] > 0) continue; if(m_Frustum[i][A] * (vecCentre.X() + size) + m_Frustum[i][B] * (vecCentre.Y() + size) + m_Frustum[i][C] * (vecCentre.Z() + size) + m_Frustum[i][D] > 0) continue; ////////////////////////////////////////////// //If we get here, it isn't in the frustum // ////////////////////////////////////////////// return false; } return true; }
//************************************************************************************** // Function name : CFrustum::PointInFrustum // Author : Gary Ingram // Return type : bool // Date Created : 25/05/2003 // Argument : float x // Argument : float y // Argument : float z // Description : The code below will allow us to make checks within the // frustum. For example, if we want to see if a point, a // sphere, or a cube lies inside of the frustum. Because all // of our planes point INWARDS (The normals are all pointing // inside the frustum) we then can assume that if a point is // in FRONT of all of the planes, it's inside. //************************************************************************************** bool CFrustum::PointInFrustum(const CVector3& vecPoint) { ////////////////////////////////////////////// //If you remember the plane equation (A*x // //+ B*y + C*z + D = 0), then the rest of // //this code should be quite obvious and // //easy to figure out yourself. In case // //don't know the plane equation, it might // //be a good idea to look at our Plane // //Collision tutorial at // //www.GameTutorials.com in OpenGL // //Tutorials. I will briefly go over it // //here. (A,B,C) is the (X,Y,Z) of the // //normal to the plane. They are the same // //thing... but just called ABC because you // //don't want to say: (x*x + y*y + z*z + d // //= 0). That would be wrong, so they // //substitute them. the (x, y, z) in the // //equation is the point that you are // //testing. The D is The distance the // //plane is from the origin. The equation // //ends with "= 0" because that is true // //when the point (x, y, z) is ON the // //plane. When the point is NOT on the // //plane, it is either a negative number // //(the point is behind the plane) or a // //positive number (the point is in front // //of the plane). We want to check if the // //point is in front of the plane, so all // //we have to do is go through each point // //and make sure the plane equation goes // //out to a positive number on each side of // //the frustum. The result (be it positive // //or negative) is the distance the point // //is front the plane. // ////////////////////////////////////////////// ////////////////////////////////////////////// //Go through all the sides of the frustum // ////////////////////////////////////////////// for(int i = 0; i < 6; i++ ) { ////////////////////////////////////////////// //Calculate the plane equation and check // //if the point is behind a side of the // //frustum // ////////////////////////////////////////////// if(m_Frustum[i][A] * vecPoint.X() + m_Frustum[i][B] * vecPoint.Y() + m_Frustum[i][C] * vecPoint.Z() + m_Frustum[i][D] <= 0) { ////////////////////////////////////////////// //The point was behind a side, so it ISN'T // //in the frustum // ////////////////////////////////////////////// return false; } } ////////////////////////////////////////////// //The point was inside of the frustum (In // //front of ALL the sides of the frustum) // ////////////////////////////////////////////// return true; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // // - prototype : void SetZAxis(const CVector3& zAxis) // // - Purpose : Sets matrix's Z axis. // // ----------------------------------------------------------------------------- void CMatrix::SetZAxis(const CVector3& zAxis) { m_fM[2][0] = zAxis.X(); m_fM[2][1] = zAxis.Y(); m_fM[2][2] = zAxis.Z(); }
// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // // - prototype : void SetYAxis(const CVector3& yAxis) // // - Purpose : Sets matrix's Y axis. // // ----------------------------------------------------------------------------- void CMatrix::SetYAxis(const CVector3& yAxis) { m_fM[1][0] = yAxis.X(); m_fM[1][1] = yAxis.Y(); m_fM[1][2] = yAxis.Z(); }
// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // // - prototype : void SetXAxis(const CVector3& xAxis) // // - Purpose : Sets matrix's X axis. // // ----------------------------------------------------------------------------- void CMatrix::SetXAxis(const CVector3& xAxis) { m_fM[0][0] = xAxis.X(); m_fM[0][1] = xAxis.Y(); m_fM[0][2] = xAxis.Z(); }