Initial revision
[0ad:0ad.git] / terrain / bak / 1 b4 poya fix / Terrain.cpp
1 //***********************************************************
2 //
3 // Name:                Terrain.Cpp
4 // Last Update: 23/2/02
5 // Author:              Poya Manouchehri
6 //
7 // Description: CTerrain handles the terrain portion of the
8 //                              engine. It holds open the file to the terrain
9 //                              information, so terrain data can be loaded
10 //                              dynamically. We use a ROAM method to render 
11 //                              the terrain, ie using binary triangle trees.
12 //                              The terrain consists of smaller PATCHS, which
13 //                              do most of the work.
14 //
15 //***********************************************************
16
17 #include "Terrain.H"
18 #include "tex.h"
19
20 bool g_HillShading = true;
21
22 CVector3D                       SeasonLight[2];
23 float                           SeasonColor[2][3];
24
25 CTerrain::CTerrain ()
26 {
27         m_pVertices = NULL;
28 }
29
30 CTerrain::~CTerrain ()
31 {
32         delete [] m_pVertices;
33 }
34
35 bool CTerrain::Initalize (char *filename)
36 {
37         SeasonLight[0].Set (3, -1, 3);
38         SeasonLight[0].Normalize();
39         SeasonColor[0][0] = 0.8f; SeasonColor[0][1] = 1.0f; SeasonColor[0][2] = 0.8f;
40
41         SeasonLight[1].Set (2, -1, -3);
42         SeasonLight[1].Normalize();
43         SeasonColor[1][0] = 1.0f; SeasonColor[1][1] = 0.9f; SeasonColor[1][2] = 0.9f;
44
45 TEX tex;
46 Handle h = tex_load(filename, &tex);
47 if(!h)
48 return false;
49 const u8* data = tex.ptr;
50
51         m_pVertices = new STerrainVertex[MAP_SIZE*MAP_SIZE];
52         if (m_pVertices == NULL)
53                 return false;
54
55         for (int j=0; j<MAP_SIZE; j++)
56         {
57                 for (int i=0; i<MAP_SIZE; i++)
58                 {
59                         int pos = j*MAP_SIZE + i;
60
61                         m_pVertices[pos].m_Position.X = ((float)i)*CELL_SIZE;
62                         m_pVertices[pos].m_Position.Y = (*data++)*0.35f;
63                         m_pVertices[pos].m_Position.Z = ((float)j)*CELL_SIZE;
64                 }
65         }
66
67         for (j=0; j<NUM_PATCHES_PER_SIDE; j++)
68         {
69                 for (int i=0; i<NUM_PATCHES_PER_SIDE; i++)
70                 {
71                         int pos = j*MAP_SIZE*PATCH_SIZE;
72                         pos += i*PATCH_SIZE;
73
74                         m_Patches[j][i].Initialize ( &(m_pVertices[pos]) );
75                 }
76         }
77
78         CalcLighting();
79         SetNeighbors();
80
81         return true;
82 }
83
84 void CTerrain::CalcLighting ()
85 {
86         CVector3D left, right, up, down, n[4];
87         
88         for (int j=0; j<MAP_SIZE; j++)
89         {
90                 for (int i=0; i<MAP_SIZE; i++)
91                 {
92                         left.Clear();
93                         right.Clear();
94                         up.Clear();
95                         down.Clear();
96                         
97                         if (i>0)
98                                 left = m_pVertices[j*MAP_SIZE + i - 1].m_Position - 
99                                            m_pVertices[j*MAP_SIZE + i].m_Position;
100
101                         if (i<MAP_SIZE-1)
102                                 right = m_pVertices[j*MAP_SIZE + i + 1].m_Position - 
103                                             m_pVertices[j*MAP_SIZE + i].m_Position;
104
105                         if (j>0)
106                                 up = m_pVertices[(j-1)*MAP_SIZE + i].m_Position - 
107                                      m_pVertices[j*MAP_SIZE + i].m_Position;
108
109                         if (j<MAP_SIZE-1)
110                                 down = m_pVertices[(j+1)*MAP_SIZE + i].m_Position - 
111                                            m_pVertices[j*MAP_SIZE + i].m_Position;
112
113                         n[0] = up.Cross(left);
114                         n[1] = left.Cross(down);
115                         n[2] = down.Cross(right);
116                         n[3] = right.Cross(up);
117
118                         n[0].Normalize();
119                         n[1].Normalize();
120                         n[2].Normalize();
121                         n[3].Normalize();
122
123                         CVector3D Normal = n[0] + n[1] + n[2] + n[3];
124                         Normal.Normalize();
125
126                         float Color1 = Normal.Dot(SeasonLight[0]*-1)/(Normal.GetLength() * SeasonLight[0].GetLength());
127                         Color1 = (Color1+1.0f)/1.4f;
128
129                         if (Color1>1.0f)
130                                 Color1=1.0f;
131                         if (Color1<0.0f)
132                                 Color1=0.0f;
133
134                         float Color2 = Normal.Dot(SeasonLight[1]*-1)/(Normal.GetLength() * SeasonLight[1].GetLength());
135                         Color2 = (Color2+1.0f)/1.4f;
136
137                         if (Color2>1.0f)
138                                 Color2=1.0f;
139                         if (Color2<0.0f)
140                                 Color2=0.0f;
141
142                         m_pVertices[j*MAP_SIZE + i].m_Color[0][0] = Color1*SeasonColor[0][0];
143                         m_pVertices[j*MAP_SIZE + i].m_Color[0][1] = Color1*SeasonColor[0][1];
144                         m_pVertices[j*MAP_SIZE + i].m_Color[0][2] = Color1*SeasonColor[0][2];
145
146                         m_pVertices[j*MAP_SIZE + i].m_Color[1][0] = Color2*SeasonColor[1][0];
147                         m_pVertices[j*MAP_SIZE + i].m_Color[1][1] = Color2*SeasonColor[1][1];
148                         m_pVertices[j*MAP_SIZE + i].m_Color[1][2] = Color2*SeasonColor[1][2];
149
150                 }
151         }
152 }
153
154 void CTerrain::SetNeighbors ()
155 {
156         CPatch *ThisPatch, *RightPatch;
157
158         for (int pj=0; pj<NUM_PATCHES_PER_SIDE; pj++)
159         {
160                 for (int pi=0; pi<NUM_PATCHES_PER_SIDE; pi++)
161                 {
162                         ThisPatch = &m_Patches[pj][pi];
163                         
164                         if (pi < NUM_PATCHES_PER_SIDE-1)
165                                 RightPatch = &m_Patches[pj][pi+1]; 
166                         else
167                                 RightPatch = NULL;
168
169
170                         for (int tj=0; tj<16; tj++)
171                         {
172                                 for (int ti=0; ti<16; ti++)
173                                 {
174                                         CMiniPatch *MPatch = &ThisPatch->m_MiniPatches[tj][ti];
175
176                                         MPatch->m_pParrent = ThisPatch;
177
178                                         if (ti < 15)
179                                                 MPatch->m_pRightNeighbor = &ThisPatch->m_MiniPatches[tj][ti+1];
180                                         else
181                                         {
182                                                 if (RightPatch)
183                                                         MPatch->m_pRightNeighbor = &RightPatch->m_MiniPatches[tj][0];
184                                                 else
185                                                         MPatch->m_pRightNeighbor = NULL;
186                                         }
187                                 }
188                         }
189                 }
190         }
191
192 }