Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Terrain.h ----------------------------------------------
- #pragma once
- #include <glaux.h> // Include glaux.h Global
- #include <vector> // Include vector Global
- struct vec3{
- float x;
- float y;
- float z;
- };
- class CTerrain : public C3DObject
- {
- public:
- CTerrain(void); // Constructor
- CTerrain(char * f_, float x_, float y_, float z_, float w_, float h_, float d_, int id_); // Constructor with Overloads
- ~CTerrain(void); // Destructor
- void Render(); // Render
- float getYAt(float x_, float z_); // Return the Height
- private:
- int m_iMapVerticesx; // ???
- int m_iMapVerticesz; // ???
- float m_fTerrainStepWidth; // ???
- float m_fTerrainStepHeight; // ???
- AUX_RGBImageRec * m_pImage_RGB; // ???
- void LoadBitmapFile(char *filename); // Load Bitmap Data
- void UnloadBitmapFile(); // Unload Bitmap Data
- void CreateDisplayList(); // ???
- vec3 * ComputeCrossProduct(int x1,int z1,int x2,int z2,int x3,int z3); // Compute Cross Product
- bool bDisplayListCreated; // Display list created
- GLuint m_iDisplayList; // ???
- void ComputeVertexHeights(); // Calculate Vertex Height
- void ComputeNormals(); // Calculate Normals
- std::vector <float> m_vHeights; // ???
- float * ptr; // Store Height Data
- std::vector <vec3 *> m_vNormals; // ???
- void NormalizeVector(vec3 *v); // Normalize Vectors
- void AddVector(vec3 *a, vec3 *b); // Add Vectors
- void DumpVertexData(); // Used for Debugging
- void InitPhysics(); // Initialize Physics
- // Comment This /\ //
- };
- // Terrain.cpp ----------------------------------------------
- #include "stdafx.h" // Include stdafx.h Local
- #include "3DObject.h" // Include C3DObject.h Local
- #include "Terrain.h" // Include Terrain.h Local
- #include "Physics.h" // Include Physics.h Local
- #include <math.h> // Include math.h Global
- #include "Sprite.h" // Include Sprite.h Local
- #include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
- #include "btBulletDynamicsCommon.h"
- CTerrain::CTerrain(void)
- {
- } // Constructor
- CTerrain::CTerrain(char * f_, float x_, float y_, float z_, float w_, float h_, float d_, int id_):C3DObject(x_,y_,z_,w_,h_,d_,id_,TTERRAIN)
- {
- LoadBitmapFile(f_);
- m_iMapVerticesx = m_pImage_RGB->sizeX;
- m_iMapVerticesz = m_pImage_RGB->sizeY;
- m_fW = m_pImage_RGB->sizeX; // Set the Width
- m_fD = m_pImage_RGB->sizeY; // Set the Depth
- bDisplayListCreated = 0;
- m_vHeights.resize(m_iMapVerticesx * m_iMapVerticesz);
- m_vNormals.resize(m_iMapVerticesx * m_iMapVerticesz);
- m_fTerrainStepWidth = 1.0f / m_iMapVerticesx;
- m_fTerrainStepHeight = 1.0f / m_iMapVerticesz;
- ComputeVertexHeights();
- ComputeNormals();
- } // Constructor with Overloads
- CTerrain::~CTerrain(void)
- {
- UnloadBitmapFile();
- } // Destructor
- void CTerrain::InitPhysics()
- {
- if(CPhysics::getInstance()->Init)
- {
- ptr = static_cast<float *>(&m_vHeights[0]);
- btHeightfieldTerrainShape * m_cColShape = new btHeightfieldTerrainShape(m_fW,m_fD,ptr,1,0,m_fH,1,PHY_FLOAT,false); // Create Terrain
- CPhysics::getInstance()->m_collisionShapes.push_back(m_cColShape); // Create Collision Shape
- btTransform m_cTransform; // Define Transform
- m_cTransform.setIdentity(); // Set Transform
- btScalar mass(0); // Set the Mass
- btVector3 localInertia(0,0,0); // Set Inertia
- m_cTransform.setOrigin(SCALING * btVector3(m_fX,m_fY*0.5f,m_fZ)); // Set Position
- btDefaultMotionState * myMotionState = new btDefaultMotionState(m_cTransform); // Create Motion State
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,m_cColShape,localInertia); // Create Rigid Body Info
- m_rBound = new btRigidBody(rbInfo); // Create new Rigid Body
- CPhysics::getInstance()->dynamicsWorld->addRigidBody(m_rBound); // Add to Dynamic World
- m_bPhysics = true; // Physics Enabled
- }
- else
- {
- m_bPhysics = false; // Physics Disabled
- }
- } // Enable Physics
- void CTerrain::ComputeVertexHeights()
- {
- float xfactor = 1.0 / (m_iMapVerticesx - 1);
- float zfactor = 1.0 / (m_iMapVerticesz - 1);
- for(int z = 0;z < (m_iMapVerticesz-1);z++)
- {
- for(int x = 0;x < (m_iMapVerticesx-1);x++)
- {
- //char txt[64];
- int vertxindex = x;
- int vertzindex = z;
- float xprop = xfactor * vertxindex;
- float zprop = zfactor * vertzindex;
- float y = (m_pImage_RGB->data[(vertzindex*m_iMapVerticesz+vertxindex)*3]) / 255.0;
- m_vHeights[vertxindex + m_iMapVerticesx * vertzindex] = y;
- vertxindex = x;
- vertzindex = z + 1;
- xprop = xfactor * vertxindex;
- zprop = zfactor * vertzindex;
- glTexCoord2f(xprop,zprop);
- y = (m_pImage_RGB->data[(vertzindex*m_iMapVerticesz+vertxindex)*3]) / 255.0;
- m_vHeights[vertxindex + m_iMapVerticesx * vertzindex] = y;
- vertxindex = x + 1;
- vertzindex = z;
- xprop = xfactor * vertxindex;
- zprop = zfactor * vertzindex;
- y = (m_pImage_RGB->data[(vertzindex * m_iMapVerticesz + vertxindex) * 3]) / 255.0;
- m_vHeights[vertxindex + m_iMapVerticesx * vertzindex] = y;
- vertxindex = x + 1;
- vertzindex = z + 1;
- xprop = xfactor * vertxindex;
- zprop = zfactor * vertzindex;
- y = (m_pImage_RGB->data[(vertzindex * m_iMapVerticesz + vertxindex) * 3]) / 255.0;
- m_vHeights[vertxindex + m_iMapVerticesx * vertzindex] = y;
- }
- }
- } // Calculate Vertex Height
- void CTerrain::CreateDisplayList()
- {
- m_iDisplayList = glGenLists(1);
- glNewList(m_iDisplayList,GL_COMPILE);
- float xfactor = 1.0 / (m_iMapVerticesx - 1);
- float zfactor = 1.0 / (m_iMapVerticesz - 1);
- for (int z = 0;z < (m_iMapVerticesz - 1);z++)
- {
- for (int x = 0;x < (m_iMapVerticesx - 1);x++)
- {
- glBegin(GL_TRIANGLES);
- int vertxindex = x;
- int vertzindex = z;
- float xprop = xfactor * vertxindex;
- float zprop = zfactor * vertzindex;
- float y = (m_pImage_RGB->data[(vertzindex * m_iMapVerticesz + vertxindex) * 3]) / 255.0;
- vec3 * norm = m_vNormals[vertxindex + m_iMapVerticesx * vertzindex];
- glNormal3f(norm->x,norm->y,norm->z);
- glTexCoord2f(xprop,zprop);
- glVertex3f(-0.5 + xprop,y,-0.5 + zprop); // V0
- vertxindex = x;
- vertzindex = z + 1;
- xprop = xfactor * vertxindex;
- zprop = zfactor * vertzindex;
- norm = m_vNormals[vertxindex + m_iMapVerticesx * vertzindex];
- glNormal3f(norm->x,norm->y,norm->z);
- glTexCoord2f(xprop,zprop);
- y = (m_pImage_RGB->data[(vertzindex * m_iMapVerticesz + vertxindex) * 3]) / 255.0;
- glVertex3f(-0.5 + xprop,y,-0.5 + zprop); // V1
- vertxindex = x + 1;
- vertzindex = z;
- xprop = xfactor * vertxindex;
- zprop = zfactor * vertzindex;
- norm = m_vNormals[vertxindex + m_iMapVerticesx * vertzindex];
- glNormal3f(norm->x,norm->y,norm->z);
- glTexCoord2f(xprop,zprop);
- y = (m_pImage_RGB->data[(vertzindex * m_iMapVerticesz + vertxindex) * 3]) / 255.0;
- glVertex3f(-0.5 + xprop,y,-0.5 + zprop); // V2
- vertxindex = x + 1;
- vertzindex = z;
- xprop = xfactor * vertxindex;
- zprop = zfactor * vertzindex;
- norm = m_vNormals[vertxindex + m_iMapVerticesx * vertzindex];
- glNormal3f(norm->x,norm->y,norm->z);
- glTexCoord2f(xprop,zprop);
- y = (m_pImage_RGB->data[(vertzindex * m_iMapVerticesz + vertxindex) * 3]) / 255.0;
- glVertex3f(-0.5+xprop,y,-0.5+zprop); // V3
- vertxindex = x;
- vertzindex = z + 1;
- xprop = xfactor * vertxindex;
- zprop = zfactor * vertzindex;
- norm = m_vNormals[vertxindex + m_iMapVerticesx * vertzindex];
- glNormal3f(norm->x,norm->y,norm->z);
- glTexCoord2f(xprop,zprop);
- y = (m_pImage_RGB->data[(vertzindex * m_iMapVerticesz + vertxindex) * 3]) / 255.0;
- glVertex3f(-0.5 + xprop,y,-0.5 + zprop); // V1
- vertxindex = x + 1;
- vertzindex = z + 1;
- xprop = xfactor * vertxindex;
- zprop = zfactor * vertzindex;
- norm = m_vNormals[vertxindex + m_iMapVerticesx * vertzindex];
- glNormal3f(norm->x,norm->y,norm->z);
- glTexCoord2f(xprop,zprop);
- y = (m_pImage_RGB->data[(vertzindex * m_iMapVerticesz + vertxindex) * 3]) / 255.0;
- glVertex3f(-0.5 + xprop,y,-0.5 + zprop); // V3
- glEnd();
- }
- }
- glEndList();
- GLenum error = glGetError();
- int x = 1;
- }
- void CTerrain::Render()
- {
- if(!bDisplayListCreated)
- {
- bDisplayListCreated = true;
- CreateDisplayList();
- InitPhysics();
- }
- glPushMatrix();
- glDisable(GL_CULL_FACE);
- glEnable(GL_TEXTURE_2D);
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- glBindTexture(GL_TEXTURE_2D, m_iTextureID);
- GLfloat white[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
- GLfloat grey[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
- glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
- glMaterialfv(GL_FRONT, GL_AMBIENT, grey);
- glTranslatef(m_fX,m_fY,m_fZ);
- glScalef(m_fW, m_fH, m_fD);
- glCallList(m_iDisplayList);
- glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );
- glEnable(GL_CULL_FACE);
- glPopMatrix();
- return;
- }
- void CTerrain::LoadBitmapFile(char *filename)
- {
- m_pImage_RGB = auxDIBImageLoadA(filename);
- } // Load Bitmap Data
- void CTerrain::UnloadBitmapFile()
- {
- if(m_pImage_RGB)
- {
- if(m_pImage_RGB->data)
- {
- free(m_pImage_RGB->data);
- }
- free(m_pImage_RGB);
- }
- } // Unload Bitmap Data
- float CTerrain::getYAt(float x_,float z_)
- {
- float x_relative = x_ - m_fX;
- float z_relative = z_ - m_fZ;
- x_relative /= m_fW;
- z_relative /= m_fD;
- x_relative += 0.5;
- z_relative += 0.5;
- //float xmin,xmax,zmin,zmax;
- if(x_relative < 0.0 || x_relative > 1.0)
- {
- return 0;
- }
- if(z_relative < 0.0 || z_relative > 1.0)
- {
- return 0;
- }
- int whichvertexx, whichvertexz;
- whichvertexx = (int)(x_relative * (m_iMapVerticesx - 1));
- whichvertexz = (int)(z_relative * (m_iMapVerticesz - 1));
- int col0 = whichvertexx;
- int row0 = whichvertexz;
- int col1 = col0 + 1;
- int row1 = row0 + 1;
- if(col1 > m_iMapVerticesx)
- {
- col1 = 0;
- }
- if(row1 > m_iMapVerticesz)
- {
- row1 = 0;
- }
- // get the four corner heights of the cell from the height field
- int h00 = m_pImage_RGB->data[3 * (col0 + row0 * m_iMapVerticesz)];
- int h01 = m_pImage_RGB->data[3 * (col1 + row0 * m_iMapVerticesz)];
- int h11 = m_pImage_RGB->data[3 * (col1 + row1 * m_iMapVerticesz)];
- int h10 = m_pImage_RGB->data[3 * (col0 + row1 * m_iMapVerticesz)];
- float tx = (x_relative - float(col0) / m_iMapVerticesx) * 64;
- float tz = (z_relative - float(row0) / m_iMapVerticesz) * 64;
- float txtz = tx * tz;
- float final_height = (float)h00 * (1.0f - tz - tx + txtz) + (float)h01 * (tx - txtz) + (float)h11 * txtz + (float)h10 * (tz - txtz);
- final_height *= m_fH / 255.0;
- return final_height;
- } // Return the Height
- vec3 * CTerrain::ComputeCrossProduct(int x1,int z1,int x2,int z2,int x3,int z3)
- {
- float v1[3],v2[3];
- v1[0] = (x2-x1) * m_fTerrainStepWidth;
- v1[1] = -m_vHeights[z1 * m_iMapVerticesx + x1] + m_vHeights[z2 * m_iMapVerticesx + x2];
- v1[2] = (z2-z1) * m_fTerrainStepHeight;
- v2[0] = (x3-x1) * m_fTerrainStepWidth;
- v2[1] = -m_vHeights[z1 * m_iMapVerticesx + x1] + m_vHeights[z3 * m_iMapVerticesx + x3];
- v2[2] = (z3-z1) * m_fTerrainStepHeight;
- vec3 * pAuxNormal = new vec3();
- pAuxNormal->x = v1[1] * v2[2] - v1[2] * v2[1];
- pAuxNormal->y = v1[2] * v2[0] - v1[0] * v2[2];
- pAuxNormal->z = v1[0] * v2[1] - v1[1] * v2[0];
- return(pAuxNormal);
- } // Compute Cross Product
- void CTerrain::ComputeNormals()
- {
- float xfactor = 1.0 / (m_iMapVerticesx - 1);
- float zfactor = 1.0 / (m_iMapVerticesz - 1);
- for (int z = 0;z < (m_iMapVerticesz);z++)
- {
- for (int x = 0;x < (m_iMapVerticesx);x++)
- {
- vec3 * norm1 = new vec3();
- vec3 * norm2 = new vec3();
- if(x == 0 && z == 0) {
- norm1 = ComputeCrossProduct(0,0, 0,1, 1,0);
- NormalizeVector(norm1);
- }
- else if(x == m_iMapVerticesx-1 && z == m_iMapVerticesz-1)
- {
- norm1 = ComputeCrossProduct(x,z, x,z-1, x-1,z);
- NormalizeVector(norm1);
- }
- else if(x == 0 && z == m_iMapVerticesz-1)
- {
- norm1 = ComputeCrossProduct(x,z, x+1,z,x,z-1 );
- NormalizeVector(norm1);
- }
- else if(x == m_iMapVerticesx-1 && z == 0)
- {
- norm1 = ComputeCrossProduct(x,z, x-1,z, x,z+1);
- NormalizeVector(norm1);
- }
- else if (z == 0)
- {
- norm1 = ComputeCrossProduct(x,0, x-1,0, x,1);
- NormalizeVector(norm1);
- norm2 = ComputeCrossProduct(x,0,x,1,x+1,0);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- NormalizeVector(norm1);
- }
- else if (x == 0)
- {
- norm1 = ComputeCrossProduct(0,z,1,z, 0,z-1 );
- NormalizeVector(norm1);
- norm2 = ComputeCrossProduct(0,z,0,z+1,1,z);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- NormalizeVector(norm1);
- }
- else if (x == m_iMapVerticesx-1)
- {
- norm1 = ComputeCrossProduct(x,z, x,z-1, x-1,z);
- NormalizeVector(norm1);
- norm2 = ComputeCrossProduct(x,z,x-1,z,x,z+1);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- NormalizeVector(norm1);
- }
- else if (z == m_iMapVerticesz-1)
- {
- norm1 = ComputeCrossProduct(x,z, x+1,z, x,z-1);
- NormalizeVector(norm1);
- norm2 = ComputeCrossProduct(x,z,x,z-1,x-1,z);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- NormalizeVector(norm1);
- }
- else
- {
- norm1 = ComputeCrossProduct(x,z, x-1,z, x-1,z+1);
- NormalizeVector(norm1);
- norm2 = ComputeCrossProduct(x,z, x-1,z+1, x,z+1);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- norm2 = ComputeCrossProduct(x,z, x,z+1, x+1,z+1);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- norm2 = ComputeCrossProduct(x,z, x+1,z+1, x+1,z);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- norm2 = ComputeCrossProduct(x,z, x+1,z, x+1,z-1);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- norm2 = ComputeCrossProduct(x,z, x+1,z-1, x,z-1);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- norm2 = ComputeCrossProduct(x,z, x,z-1, x-1,z-1);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- norm2 = ComputeCrossProduct(x,z, x-1,z-1, x-1,z);
- NormalizeVector(norm2);
- AddVector(norm1,norm2);
- NormalizeVector(norm1);
- }
- int index = x + m_iMapVerticesx * z;
- m_vNormals[index] = norm1;
- }
- }
- } // Calculate Normals
- void CTerrain::NormalizeVector(vec3 *v)
- {
- double d;
- d = sqrt((v->x * v->x) + (v->y * v->y) + (v->z * v->z));
- v->x /= d;
- v->y /= d;
- v->z /= d;
- } // Normalize Vectors
- void CTerrain::AddVector(vec3 *a, vec3 *b)
- {
- a->x += b->x;
- a->y += b->y;
- a->z += b->z;
- } // Add Vectors
- void CTerrain::DumpVertexData()
- {
- /*
- int x=0;
- int z=0;
- for(int i=0;i<m_vHeights.size();i++)
- {
- float value=m_vHeights[i];
- vec3 * normal=m_vNormals[i];
- char txt[200];
- sprintf(txt,"(%d,%d) y=%2.2f, normal =(%2.2f,%2.2f,%2.2f)\n",x,z,value,normal->x,normal->y,normal->z);
- // Output stuff goes here!
- x++;
- if (x>=m_iMapVerticesx)
- {
- x=0;
- z++;
- }
- }
- */
- } // Used for Debugging
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement