//*********************************************************** // // Name: Terrain.Cpp // Last Update: 23/2/02 // Author: Poya Manouchehri // // Description: CTerrain handles the terrain portion of the // engine. It holds open the file to the terrain // information, so terrain data can be loaded // dynamically. We use a ROAM method to render // the terrain, ie using binary triangle trees. // The terrain consists of smaller PATCHS, which // do most of the work. // //*********************************************************** #include "res/res.h" #include "Terrain.h" #include "LightEnv.h" #include "SHCoeffs.h" bool g_HillShading = true; CVector3D SeasonLight[2]; float SeasonColor[2][3]; CTerrain::CTerrain () { m_pVertices = NULL; } CTerrain::~CTerrain () { delete [] m_pVertices; } bool CTerrain::Load(char *filename) { Handle ht = tex_load(filename); if(!ht) return false; void* p; tex_info(ht, 0, 0, &p); return InitFromHeightmap((const u8*)p); } bool CTerrain::InitFromHeightmap(const u8* data) { int j; delete[] m_pVertices; m_pVertices = new STerrainVertex[MAP_SIZE*MAP_SIZE]; if (m_pVertices == NULL) return false; for (j=0; j0) left = m_pVertices[j*MAP_SIZE + i - 1].m_Position - m_pVertices[j*MAP_SIZE + i].m_Position; if (i0) up = m_pVertices[(j-1)*MAP_SIZE + i].m_Position - m_pVertices[j*MAP_SIZE + i].m_Position; if (j0.0001f) n[0]*=1.0f/n0len; float n1len=n[1].GetLength(); if (n1len>0.0001f) n[1]*=1.0f/n1len; float n2len=n[2].GetLength(); if (n2len>0.0001f) n[2]*=1.0f/n2len; float n3len=n[3].GetLength(); if (n3len>0.0001f) n[3]*=1.0f/n3len; CVector3D Normal = n[0] + n[1] + n[2] + n[3]; float nlen=Normal.GetLength(); if (nlen>0.00001f) Normal*=1.0f/nlen; m_pVertices[j*MAP_SIZE + i].m_Normal=Normal; } } } void CTerrain::SetNeighbors () { CPatch *ThisPatch, *RightPatch; for (int pj=0; pjm_MiniPatches[tj][ti]; MPatch->m_pParrent = ThisPatch; if (ti < 15) MPatch->m_pRightNeighbor = &ThisPatch->m_MiniPatches[tj][ti+1]; else { if (RightPatch) MPatch->m_pRightNeighbor = &RightPatch->m_MiniPatches[tj][0]; else MPatch->m_pRightNeighbor = NULL; } } } } } }