// --[ 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; }
//************************************************************************************** // 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; }
// --[ 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::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; }
bool CFXTransExplodingCubes::LoadData(CResourceList* pResourceList) { // Create RTT Texture CVarInt::CValueInt valueInt; EvaluateVar("RenderTex Width", 0.0f, &valueInt); if(valueInt.GetValue() < 1) valueInt.SetValue(1); int nWidthPwr = MYROUND(log10f(valueInt.GetValue()) / log10f(2)); EvaluateVar("RenderTex Height", 0.0f, &valueInt); if(valueInt.GetValue() < 1) valueInt.SetValue(1); int nHeightPwr = MYROUND(log10f(valueInt.GetValue()) / log10f(2)); int nWidth = pow(2, nWidthPwr); int nHeight = pow(2, nHeightPwr); UtilGL::Texturing::STexLoadOptions texOptions; texOptions.SetDefaults(); texOptions.eFilter = UtilGL::Texturing::FILTER_LINEAR; m_textureRTT.LoadFlat(nWidth, nHeight, CVector4(0.0f, 0.0f, 0.0f, 1.0f), false, false, &texOptions); // Create cubes CVarInt::CValueInt valueXCubes; CVarInt::CValueInt valueYCubes; CVarInt::CValueInt valueSeed; CVarFloat::CValueFloat valueAngleMultiple; CVarFloat::CValueFloat valueDepth; CVarFloat::CValueFloat valueAngleStep; CVarFloat::CValueFloat valueAccelX; CVarFloat::CValueFloat valueAccelY; CVarFloat::CValueFloat valueAccelZ; CVarFloat::CValueFloat valueSpeedX; CVarFloat::CValueFloat valueSpeedY; CVarFloat::CValueFloat valueSpeedZ; CVarFloat::CValueFloat valueAssimetry; CVarFloat::CValueFloat valueMaxRotation; CVarFloat::CValueFloat valueVariation; EvaluateVar("X Cubes", 0.0f, &valueXCubes); EvaluateVar("Y Cubes", 0.0f, &valueYCubes); EvaluateVar("Seed", 0.0f, &valueSeed); EvaluateVar("Z Depth", 0.0f, &valueDepth); EvaluateVar("Angle Step", 0.0f, &valueAngleStep); EvaluateVar("Accel X", 0.0f, &valueAccelX); EvaluateVar("Accel Y", 0.0f, &valueAccelY); EvaluateVar("Accel Z", 0.0f, &valueAccelZ); EvaluateVar("Start Speed X", 0.0f, &valueSpeedX); EvaluateVar("Start Speed Y", 0.0f, &valueSpeedY); EvaluateVar("Start Speed Z", 0.0f, &valueSpeedZ); EvaluateVar("Assimetry", 0.0f, &valueAssimetry); EvaluateVar("Max Rotation", 0.0f, &valueMaxRotation); EvaluateVar("Variation", 0.0f, &valueVariation); CVector3 v3Accel(valueAccelX.GetValue(), valueAccelY.GetValue(), valueAccelZ.GetValue()); CVector3 v3Speed(valueSpeedX.GetValue(), valueSpeedY.GetValue(), valueSpeedZ.GetValue()); int xRes = valueXCubes.GetValue() > 1 ? valueXCubes.GetValue() : 1; int yRes = valueYCubes.GetValue() > 1 ? valueYCubes.GetValue() : 1; float fSizeX = 1.0f / xRes; float fSizeY = 1.0f / yRes; srand(valueSeed.GetValue()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0f, 1.33f, 1.0f, 100.0f); UtilGL::Transforming::ClearMatrix(UtilGL::Transforming::MATRIX_WORLD); UtilGL::Transforming::ClearMatrix(UtilGL::Transforming::MATRIX_VIEW); for(int y = 0; y < yRes; y++) { for(int x = 0; x < xRes; x++) { SCube cube; cube.fU = x * fSizeX; cube.fV = 1.0f - (y * fSizeY); cube.fU2 = x * fSizeX + fSizeX; cube.fV2 = 1.0f - (y * fSizeY + fSizeY); CVector3 upLeft (x * fSizeX, y * fSizeY, 0.5f); CVector3 botRight(x * fSizeX + fSizeX, y * fSizeY + fSizeY, 0.5f); UtilGL::Transforming::NormViewportToLocal(&upLeft); UtilGL::Transforming::NormViewportToLocal(&botRight); float fHalfX = (botRight.X() - upLeft.X()) * 0.5f; float fHalfY = (botRight.Y() - upLeft.Y()) * 0.5f; float fHalfZ = valueDepth.GetValue() * 0.5f; cube.v1.Set(-fHalfX, -fHalfY, +fHalfZ); cube.v2.Set(-fHalfX, +fHalfY, +fHalfZ); cube.v3.Set(+fHalfX, +fHalfY, +fHalfZ); cube.v4.Set(+fHalfX, -fHalfY, +fHalfZ); cube.v5.Set(-fHalfX, -fHalfY, -fHalfZ); cube.v6.Set(-fHalfX, +fHalfY, -fHalfZ); cube.v7.Set(+fHalfX, +fHalfY, -fHalfZ); cube.v8.Set(+fHalfX, -fHalfY, -fHalfZ); cube.v3Center.Set( (x * fSizeX) + (fSizeX * 0.5f), (y * fSizeY) + (fSizeY * 0.5f), 0.5f); cube.v3Accel = v3Accel * ComputeRandWithVariation(1.0f, valueVariation.GetValue()) * ((botRight.Y() - upLeft.Y()) * xRes); cube.v3Speed = v3Speed * ComputeRandWithVariation(1.0f, valueVariation.GetValue()) * ((botRight.Y() - upLeft.Y()) * xRes); cube.fStartTime = (MYFABSF(x - (xRes / 2.0f)) / (float)(xRes / 2.0f)) * valueAssimetry.GetValue(); cube.fRotation = ComputeRand(0.0f, valueMaxRotation.GetValue()); UtilGL::Transforming::NormViewportToLocal(&cube.v3Center); cube.fTStart = 0.0f; cube.fTEnd = 1.0f; m_vecCubes.push_back(cube); } } 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(); }