]> git.jsancho.org Git - lugaru.git/blob - Source/Objects.cpp
Removed most of the commented out code
[lugaru.git] / Source / Objects.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Lugaru is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "Objects.h"
21 extern XYZ viewer;
22 extern float viewdistance;
23 extern float fadestart;
24 extern int environment;
25 extern float texscale;
26 extern Light light;
27 extern float multiplier;
28 extern float gravity;
29 extern FRUSTUM frustum;
30 extern Terrain terrain;
31 extern bool foliage;
32 extern int detail;
33 extern float blurness;
34 extern float windvar;
35 extern float playerdist;
36 extern bool skyboxtexture;
37
38 //Functions
39
40 bool Objects::checkcollide(XYZ startpoint, XYZ endpoint, int which)
41 {
42     static XYZ colpoint, colviewer, coltarget;
43     static int i;
44
45     startpoint.y += .1;
46     endpoint.y += .1;
47     startpoint.y -= .1;
48     endpoint.y -= .1;
49
50     for (i = 0; i < numobjects; i++) {
51         if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype && i != which) {
52             colviewer = startpoint;
53             coltarget = endpoint;
54             if (model[i].LineCheck(&colviewer, &coltarget, &colpoint, &position[i], &yaw[i]) != -1)
55                 return 1;
56         }
57     }
58
59     return 0;
60 }
61
62 void Objects::SphereCheckPossible(XYZ *p1, float radius)
63 {
64     static int i, j;
65     static int whichpatchx;
66     static int whichpatchz;
67
68     whichpatchx = p1->x / (terrain.size / subdivision * terrain.scale);
69     whichpatchz = p1->z / (terrain.size / subdivision * terrain.scale);
70
71     if (whichpatchx >= 0 && whichpatchz >= 0 && whichpatchx < subdivision && whichpatchz < subdivision)
72         if (terrain.patchobjectnum[whichpatchx][whichpatchz] > 0 && terrain.patchobjectnum[whichpatchx][whichpatchz] < 500)
73             for (j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
74                 i = terrain.patchobjects[whichpatchx][whichpatchz][j];
75                 possible[i] = 0;
76                 if (model[i].SphereCheckPossible(p1, radius, &position[i], &yaw[i]) != -1) {
77                     possible[i] = 1;
78                 }
79             }
80 }
81
82 void Objects::Draw()
83 {
84     static float distance;
85     static int i;
86     static XYZ moved, terrainlight;
87     bool hidden;
88
89     for (i = 0; i < numobjects; i++) {
90         if (type[i] != firetype) {
91             moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
92             if (type[i] == tunneltype || frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
93                 distance = distsq(&viewer, &position[i]);
94                 distance *= 1.2;
95                 hidden = !(distsqflat(&viewer, &position[i]) > playerdist + 3 || (type[i] != bushtype && type[i] != treeleavestype));
96                 if (!hidden) {
97
98                     if (detail == 2 && distance > viewdistance * viewdistance / 4 && environment == desertenvironment)
99                         glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness );
100                     else
101                         glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
102                     distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
103                     if (distance > 1)
104                         distance = 1;
105                     if (distance > 0) {
106
107                         if (occluded[i] < 6) {
108                             glMatrixMode(GL_MODELVIEW);
109                             glPushMatrix();
110                             if (!model[i].color)
111                                 glEnable(GL_LIGHTING);
112                             else
113                                 glDisable(GL_LIGHTING);
114                             glDepthMask(1);
115                             glTranslatef(position[i].x, position[i].y, position[i].z);
116                             if (type[i] == bushtype) {
117                                 messedwith[i] -= multiplier;
118                                 if (rotxvel[i] || rotx[i]) {
119                                     if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
120                                     if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
121                                     if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
122                                     if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
123                                     if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
124                                     if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
125                                     if (fabs(rotx[i]) < multiplier * 4)
126                                         rotx[i] = 0;
127                                     if (fabs(rotxvel[i]) < multiplier * 4)
128                                         rotxvel[i] = 0;
129
130                                     rotx[i] += rotxvel[i] * multiplier * 4;
131                                 }
132                                 if (rotyvel[i] || roty[i]) {
133                                     if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
134                                     if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
135                                     if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
136                                     if (roty[i] < 0) rotyvel[i] += multiplier * 4;
137                                     if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
138                                     if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
139                                     if (fabs(roty[i]) < multiplier * 4)
140                                         roty[i] = 0;
141                                     if (fabs(rotyvel[i]) < multiplier * 4)
142                                         rotyvel[i] = 0;
143
144                                     roty[i] += rotyvel[i] * multiplier * 4;
145                                 }
146                                 if (roty[i]) {
147                                     glRotatef(roty[i], 1, 0, 0);
148                                 }
149                                 if (rotx[i]) {
150                                     glRotatef(-rotx[i], 0, 0, 1);
151                                 }
152                                 if (rotx[i] > 10)
153                                     rotx[i] = 10;
154                                 if (rotx[i] < -10)
155                                     rotx[i] = -10;
156                                 if (roty[i] > 10)
157                                     roty[i] = 10;
158                                 if (roty[i] < -10)
159                                     roty[i] = -10;
160                             }
161                             if (type[i] == treetrunktype || type[i] == treeleavestype) {
162                                 if (type[i] == treetrunktype || environment == 2) {
163                                     messedwith[i] -= multiplier;
164                                     if (rotxvel[i] || rotx[i]) {
165                                         if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
166                                         if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
167                                         if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
168                                         if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
169                                         if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
170                                         if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
171                                         if (fabs(rotx[i]) < multiplier * 4)
172                                             rotx[i] = 0;
173                                         if (fabs(rotxvel[i]) < multiplier * 4)
174                                             rotxvel[i] = 0;
175
176                                         rotx[i] += rotxvel[i] * multiplier * 4;
177                                     }
178                                     if (rotyvel[i] || roty[i]) {
179                                         if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
180                                         if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
181                                         if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
182                                         if (roty[i] < 0) rotyvel[i] += multiplier * 4;
183                                         if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
184                                         if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
185                                         if (fabs(roty[i]) < multiplier * 4)
186                                             roty[i] = 0;
187                                         if (fabs(rotyvel[i]) < multiplier * 4)
188                                             rotyvel[i] = 0;
189
190                                         roty[i] += rotyvel[i] * multiplier * 4;
191                                     }
192                                     if (roty[i]) {
193                                         glRotatef(roty[i] / 6, 1, 0, 0);
194                                     }
195                                     if (rotx[i]) {
196                                         glRotatef(-rotx[i] / 6, 0, 0, 1);
197                                     }
198                                     if (rotx[i] > 10)
199                                         rotx[i] = 10;
200                                     if (rotx[i] < -10)
201                                         rotx[i] = -10;
202                                     if (roty[i] > 10)
203                                         roty[i] = 10;
204                                     if (roty[i] < -10)
205                                         roty[i] = -10;
206                                 } else {
207                                     messedwith[i] -= multiplier;
208                                     if (rotxvel[i] || rotx[i]) {
209                                         if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
210                                         if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
211                                         if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
212                                         if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
213                                         if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
214                                         if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
215                                         if (fabs(rotx[i]) < multiplier * 4)
216                                             rotx[i] = 0;
217                                         if (fabs(rotxvel[i]) < multiplier * 4)
218                                             rotxvel[i] = 0;
219
220                                         rotx[i] += rotxvel[i] * multiplier * 4;
221                                     }
222                                     if (rotyvel[i] || roty[i]) {
223                                         if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
224                                         if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
225                                         if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
226                                         if (roty[i] < 0) rotyvel[i] += multiplier * 4;
227                                         if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
228                                         if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
229                                         if (fabs(roty[i]) < multiplier * 4)
230                                             roty[i] = 0;
231                                         if (fabs(rotyvel[i]) < multiplier * 4)
232                                             rotyvel[i] = 0;
233
234                                         roty[i] += rotyvel[i] * multiplier * 4;
235                                     }
236                                     if (roty[i]) {
237                                         glRotatef(roty[i] / 4, 1, 0, 0);
238                                     }
239                                     if (rotx[i]) {
240                                         glRotatef(-rotx[i] / 4, 0, 0, 1);
241                                     }
242                                     if (rotx[i] > 10)
243                                         rotx[i] = 10;
244                                     if (rotx[i] < -10)
245                                         rotx[i] = -10;
246                                     if (roty[i] > 10)
247                                         roty[i] = 10;
248                                     if (roty[i] < -10)
249                                         roty[i] = -10;
250                                 }
251
252                             }
253                             if (/*detail==2&&*/environment == snowyenvironment) {
254                                 if (type[i] == treeleavestype) {
255                                     glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
256                                 }
257                                 if (type[i] == treetrunktype) {
258                                     glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
259                                 }
260                                 if (type[i] == bushtype) {
261                                     glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
262                                 }
263                             }
264                             if (/*detail==2&&*/environment == grassyenvironment) {
265                                 if (type[i] == treeleavestype) {
266                                     glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
267                                 }
268                                 if (type[i] == treetrunktype) {
269                                     glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
270                                 }
271                                 if (type[i] == bushtype) {
272                                     glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
273                                 }
274                             }
275                             if (/*detail==2&&*/environment == desertenvironment) {
276                                 if (type[i] == bushtype) {
277                                     glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
278                                 }
279                             }
280                             glRotatef(yaw[i], 0, 1, 0);
281                             if (distance > 1)
282                                 distance = 1;
283                             glColor4f((1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, distance);
284                             if (distance >= 1) {
285                                 glDisable(GL_BLEND);
286                                 glAlphaFunc(GL_GREATER, 0.5);
287                             }
288                             if (distance < 1) {
289                                 glEnable(GL_BLEND);
290                                 glAlphaFunc(GL_GREATER, 0.1);
291                             }
292                             if (type[i] != treetrunktype && type[i] != treeleavestype && type[i] != bushtype && type[i] != rocktype) {
293                                 glEnable(GL_CULL_FACE);
294                                 glAlphaFunc(GL_GREATER, 0.0001);
295                                 model[i].drawdifftex(boxtextureptr);
296                                 model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
297                             }
298                             if (type[i] == rocktype) {
299                                 glEnable(GL_CULL_FACE);
300                                 glAlphaFunc(GL_GREATER, 0.0001);
301                                 glColor4f((1 - shadowed[i]) / 2 + light.ambient[0], (1 - shadowed[i]) / 2 + light.ambient[1], (1 - shadowed[i]) / 2 + light.ambient[2], distance);
302                                 model[i].drawdifftex(rocktextureptr);
303                                 model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
304                             }
305                             if (type[i] == treeleavestype) {
306                                 glDisable(GL_CULL_FACE);
307                                 glDisable(GL_LIGHTING);
308                                 terrainlight = terrain.getLighting(position[i].x, position[i].z);
309                                 if (!hidden) {
310                                     glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
311                                     if (distance < 1)
312                                         glAlphaFunc(GL_GREATER, 0.2);
313                                 }
314                                 if (hidden) {
315                                     glDepthMask(0);
316                                     glEnable(GL_BLEND);
317                                     glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
318                                     glAlphaFunc(GL_GREATER, 0);
319                                 }
320                                 model[i].drawdifftex(treetextureptr);
321                             }
322                             if (type[i] == bushtype) {
323                                 glDisable(GL_CULL_FACE);
324                                 glDisable(GL_LIGHTING);
325                                 terrainlight = terrain.getLighting(position[i].x, position[i].z);
326                                 if (!hidden) {
327                                     glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
328                                     if (distance < 1)
329                                         glAlphaFunc(GL_GREATER, 0.2);
330                                 }
331                                 if (hidden) {
332                                     glDepthMask(0);
333                                     glEnable(GL_BLEND);
334                                     glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
335                                     glAlphaFunc(GL_GREATER, 0);
336                                 }
337                                 model[i].drawdifftex(bushtextureptr);
338                             }
339                             if (type[i] == treetrunktype) {
340                                 glEnable(GL_CULL_FACE);
341                                 terrainlight = terrain.getLighting(position[i].x, position[i].z);
342                                 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
343                                 model[i].drawdifftex(treetextureptr);
344                             }
345                             glPopMatrix();
346                         }
347                     }
348                 }
349             }
350         }
351     }
352
353     glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
354     for (i = 0; i < numobjects; i++) {
355         if (type[i] == treeleavestype || type[i] == bushtype) {
356             moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
357             if (frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
358                 hidden = distsqflat(&viewer, &position[i]) <= playerdist + 3;
359                 if (hidden) {
360                     distance = 1;
361                     glMatrixMode(GL_MODELVIEW);
362                     glPushMatrix();
363                     glEnable(GL_LIGHTING);
364                     glDepthMask(1);
365                     glTranslatef(position[i].x, position[i].y, position[i].z);
366                     if (type[i] == bushtype) {
367                         messedwith[i] -= multiplier;
368                         if (rotxvel[i] || rotx[i]) {
369                             if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
370                             if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
371                             if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
372                             if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
373                             if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
374                             if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
375                             if (fabs(rotx[i]) < multiplier * 4)
376                                 rotx[i] = 0;
377                             if (fabs(rotxvel[i]) < multiplier * 4)
378                                 rotxvel[i] = 0;
379
380                             rotx[i] += rotxvel[i] * multiplier * 4;
381                         }
382                         if (rotyvel[i] || roty[i]) {
383                             if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
384                             if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
385                             if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
386                             if (roty[i] < 0) rotyvel[i] += multiplier * 4;
387                             if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
388                             if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
389                             if (fabs(roty[i]) < multiplier * 4)
390                                 roty[i] = 0;
391                             if (fabs(rotyvel[i]) < multiplier * 4)
392                                 rotyvel[i] = 0;
393
394                             roty[i] += rotyvel[i] * multiplier * 4;
395                         }
396                         if (roty[i]) {
397                             glRotatef(roty[i], 1, 0, 0);
398                         }
399                         if (rotx[i]) {
400                             glRotatef(-rotx[i], 0, 0, 1);
401                         }
402                         if (rotx[i] > 10)
403                             rotx[i] = 10;
404                         if (rotx[i] < -10)
405                             rotx[i] = -10;
406                         if (roty[i] > 10)
407                             roty[i] = 10;
408                         if (roty[i] < -10)
409                             roty[i] = -10;
410                     }
411                     if (type[i] == treetrunktype || type[i] == treeleavestype) {
412                         messedwith[i] -= multiplier;
413                         if (rotxvel[i] || rotx[i]) {
414                             if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
415                             if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
416                             if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
417                             if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
418                             if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
419                             if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
420                             if (fabs(rotx[i]) < multiplier * 4)
421                                 rotx[i] = 0;
422                             if (fabs(rotxvel[i]) < multiplier * 4)
423                                 rotxvel[i] = 0;
424
425                             rotx[i] += rotxvel[i] * multiplier * 4;
426                         }
427                         if (rotyvel[i] || roty[i]) {
428                             if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
429                             if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
430                             if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
431                             if (roty[i] < 0) rotyvel[i] += multiplier * 4;
432                             if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
433                             if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
434                             if (fabs(roty[i]) < multiplier * 4)
435                                 roty[i] = 0;
436                             if (fabs(rotyvel[i]) < multiplier * 4)
437                                 rotyvel[i] = 0;
438
439                             roty[i] += rotyvel[i] * multiplier * 4;
440                         }
441                         if (roty[i]) {
442                             glRotatef(roty[i] / 2, 1, 0, 0);
443                         }
444                         if (rotx[i]) {
445                             glRotatef(-rotx[i] / 2, 0, 0, 1);
446                         }
447                         if (rotx[i] > 10)
448                             rotx[i] = 10;
449                         if (rotx[i] < -10)
450                             rotx[i] = -10;
451                         if (roty[i] > 10)
452                             roty[i] = 10;
453                         if (roty[i] < -10)
454                             roty[i] = -10;
455                     }
456                     if (environment == snowyenvironment) {
457                         if (type[i] == treeleavestype) {
458                             glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
459                         }
460                         if (type[i] == treetrunktype) {
461                             glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
462                         }
463                         if (type[i] == bushtype) {
464                             glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
465                         }
466                     }
467                     if (environment == grassyenvironment) {
468                         if (type[i] == treeleavestype) {
469                             glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
470                         }
471                         if (type[i] == treetrunktype) {
472                             glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
473                         }
474                         if (type[i] == bushtype) {
475                             glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
476                         }
477                     }
478                     glRotatef(yaw[i], 0, 1, 0);
479                     glColor4f(1, 1, 1, distance);
480                     if (type[i] == treeleavestype) {
481                         glDisable(GL_CULL_FACE);
482                         glDisable(GL_LIGHTING);
483                         terrainlight = terrain.getLighting(position[i].x, position[i].z);
484                         glDepthMask(0);
485                         glEnable(GL_BLEND);
486                         glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
487                         glAlphaFunc(GL_GREATER, 0);
488                         glDisable(GL_ALPHA_TEST);
489                         model[i].drawdifftex(treetextureptr);
490                     }
491                     if (type[i] == bushtype) {
492                         glDisable(GL_CULL_FACE);
493                         glDisable(GL_LIGHTING);
494                         terrainlight = terrain.getLighting(position[i].x, position[i].z);
495                         glDepthMask(0);
496                         glEnable(GL_BLEND);
497                         glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
498                         glAlphaFunc(GL_GREATER, 0);
499                         glDisable(GL_ALPHA_TEST);
500                         model[i].drawdifftex(bushtextureptr);
501                     }
502                     glPopMatrix();
503                 }
504             }
505         }
506     }
507     if (environment == desertenvironment)
508         glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
509     glEnable(GL_ALPHA_TEST);
510     SetUpLight(&light, 0);
511 }
512
513 void Objects::DeleteObject(int which)
514 {
515     type[numobjects - 1] = 0;
516     yaw[numobjects - 1] = 0;
517     position[numobjects - 1] = 0;
518     scale[numobjects - 1] = 0;
519     friction[numobjects - 1] = 0;
520
521     numobjects--;
522 }
523
524 void Objects::MakeObject(int atype, XYZ where, float ayaw, float ascale)
525 {
526     if ((atype != treeleavestype && atype != bushtype) || foliage == 1) {
527         scale[numobjects] = ascale;
528         if (atype == treeleavestype)
529             scale[numobjects] += fabs((float)(Random() % 100) / 900) * ascale;
530
531         onfire[numobjects] = 0;
532         flamedelay[numobjects] = 0;
533         type[numobjects] = atype;
534
535         if (atype == firetype)
536             onfire[numobjects] = 1;
537
538         position[numobjects] = where;
539         if (atype == bushtype)
540             position[numobjects].y = terrain.getHeight(position[numobjects].x, position[numobjects].z) - .3;
541         yaw[numobjects] = ayaw;
542
543         rotxvel[numobjects] = 0;
544         rotyvel[numobjects] = 0;
545         rotx[numobjects] = 0;
546         roty[numobjects] = 0;
547
548         if (atype == boxtype)           model[numobjects].loaddecal((char *)":Data:Models:Box.solid", 0);
549         if (atype == cooltype)          model[numobjects].loaddecal((char *)":Data:Models:Cool.solid", 0);
550         if (atype == walltype)          model[numobjects].loaddecal((char *)":Data:Models:Wall.solid", 0);
551         if (atype == tunneltype)        model[numobjects].loaddecal((char *)":Data:Models:Tunnel.solid", 0);
552         if (atype == chimneytype)       model[numobjects].loaddecal((char *)":Data:Models:Chimney.solid", 0);
553         if (atype == spiketype)         model[numobjects].load((char *)":Data:Models:Spike.solid", 0);
554         if (atype == weirdtype)         model[numobjects].loaddecal((char *)":Data:Models:Weird.solid", 0);
555         if (atype == rocktype)          model[numobjects].loaddecal((char *)":Data:Models:Rock.solid", 0);
556         if (atype == treetrunktype)     model[numobjects].load((char *)":Data:Models:Treetrunk.solid", 0);
557         if (atype == treeleavestype)    model[numobjects].load((char *)":Data:Models:Leaves.solid", 0);
558         if (atype == bushtype)          model[numobjects].load((char *)":Data:Models:Bush.solid", 0);
559
560         if (atype == boxtype)           friction[numobjects] = 1.5;
561         if (atype == cooltype)          friction[numobjects] = 1.5;
562         if (atype == walltype)          friction[numobjects] = 1.5;
563         if (atype == platformtype)      friction[numobjects] = 1.5;
564         if (atype == tunneltype)        friction[numobjects] = 1.5;
565         if (atype == chimneytype)       friction[numobjects] = 1.5;
566         if (atype == rocktype)          friction[numobjects] = .5;
567         if (atype == rocktype && ascale>.5) friction[numobjects] = 1.5;
568         if (atype == weirdtype)         friction[numobjects] = 1.5;
569         if (atype == spiketype)         friction[numobjects] = .4;
570         if (atype == treetrunktype)     friction[numobjects] = .4;
571         if (atype == treeleavestype)    friction[numobjects] = 0;
572
573         if (atype == platformtype) {
574             model[numobjects].loaddecal((char *)":Data:Models:Platform.solid", 0);
575             model[numobjects].Rotate(90, 0, 0);
576         }
577
578         if (type[numobjects] == boxtype || type[numobjects] == cooltype || type[numobjects] == spiketype || type[numobjects] == weirdtype || type[numobjects] == walltype || type[numobjects] == chimneytype || type[numobjects] == tunneltype || type[numobjects] == platformtype) {
579             model[numobjects].ScaleTexCoords(scale[numobjects] * 1.5);
580         }
581         if (type[numobjects] == rocktype) {
582             model[numobjects].ScaleTexCoords(scale[numobjects] * 3);
583         }
584         model[numobjects].flat = 1;
585         if (atype == treetrunktype || atype == treeleavestype || atype == rocktype) {
586             model[numobjects].flat = 0;
587         }
588         model[numobjects].Scale(.3 * scale[numobjects], .3 * scale[numobjects], .3 * scale[numobjects]);
589         model[numobjects].Rotate(90, 1, 1);
590         if (type[numobjects] == rocktype) {
591             model[numobjects].Rotate(ayaw * 5, 1, 1);
592         }
593         model[numobjects].CalculateNormals(1);
594         model[numobjects].ScaleNormals(-1, -1, -1);
595
596         if (atype == treetrunktype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
597             if (detail == 2)
598                 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 2, .4, 0);
599         }
600
601         if (atype == bushtype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
602             if (detail == 2)
603                 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 1, .4, 0);
604         }
605
606         if (atype != treeleavestype && atype != bushtype && atype != firetype)
607             terrain.AddObject(where + DoRotation(model[numobjects].boundingspherecenter, 0, ayaw, 0), model[numobjects].boundingsphereradius, numobjects);
608
609         numobjects++;
610     }
611 }
612
613 void Objects::MakeObject(int atype, XYZ where, float ayaw, float apitch, float ascale)
614 {
615     if ((atype != treeleavestype && atype != bushtype) || foliage == 1) {
616         scale[numobjects] = ascale;
617         if (atype == treeleavestype)
618             scale[numobjects] += fabs((float)(Random() % 100) / 900) * ascale;
619
620         onfire[numobjects] = 0;
621         flamedelay[numobjects] = 0;
622         type[numobjects] = atype;
623
624         if (atype == firetype)
625             onfire[numobjects] = 1;
626
627         position[numobjects] = where;
628         if (atype == bushtype)
629             position[numobjects].y = terrain.getHeight(position[numobjects].x, position[numobjects].z) - .3;
630         yaw[numobjects] = ayaw;
631         pitch[numobjects] = apitch;
632
633         rotxvel[numobjects] = 0;
634         rotyvel[numobjects] = 0;
635         rotx[numobjects] = 0;
636         roty[numobjects] = 0;
637
638         if (atype == boxtype)           model[numobjects].loaddecal((char *)":Data:Models:Box.solid", 0);
639         if (atype == cooltype)          model[numobjects].loaddecal((char *)":Data:Models:Cool.solid", 0);
640         if (atype == walltype)          model[numobjects].loaddecal((char *)":Data:Models:Wall.solid", 0);
641         if (atype == tunneltype)        model[numobjects].loaddecal((char *)":Data:Models:Tunnel.solid", 0);
642         if (atype == chimneytype)       model[numobjects].loaddecal((char *)":Data:Models:Chimney.solid", 0);
643         if (atype == spiketype)         model[numobjects].load((char *)":Data:Models:Spike.solid", 0);
644         if (atype == weirdtype)         model[numobjects].loaddecal((char *)":Data:Models:Weird.solid", 0);
645         if (atype == rocktype)          model[numobjects].loaddecal((char *)":Data:Models:Rock.solid", 0);
646         if (atype == treetrunktype)     model[numobjects].load((char *)":Data:Models:Treetrunk.solid", 0);
647         if (atype == treeleavestype)    model[numobjects].load((char *)":Data:Models:Leaves.solid", 0);
648         if (atype == bushtype)          model[numobjects].load((char *)":Data:Models:Bush.solid", 0);
649
650         if (atype == boxtype)           friction[numobjects] = 1.5;
651         if (atype == cooltype)          friction[numobjects] = 1.5;
652         if (atype == walltype)          friction[numobjects] = 1.5;
653         if (atype == platformtype)      friction[numobjects] = 1.5;
654         if (atype == tunneltype)        friction[numobjects] = 1.5;
655         if (atype == chimneytype)       friction[numobjects] = 1.5;
656         if (atype == rocktype)          friction[numobjects] = .5;
657         if (atype == rocktype && ascale>.5) friction[numobjects] = 1.5;
658         if (atype == weirdtype)         friction[numobjects] = 1.5;
659         if (atype == spiketype)         friction[numobjects] = .4;
660         if (atype == treetrunktype)     friction[numobjects] = .4;
661         if (atype == treeleavestype)    friction[numobjects] = 0;
662
663         if (friction[numobjects] == 1.5 && fabs(apitch) > 5)
664             friction[numobjects] = .5;
665
666         if (atype == platformtype) {
667             model[numobjects].loaddecal((char *)":Data:Models:Platform.solid", 0);
668             model[numobjects].Rotate(90, 0, 0);
669         }
670
671         if (type[numobjects] == boxtype || type[numobjects] == cooltype || type[numobjects] == spiketype || type[numobjects] == weirdtype || type[numobjects] == walltype || type[numobjects] == chimneytype || type[numobjects] == tunneltype || type[numobjects] == platformtype) {
672             model[numobjects].ScaleTexCoords(scale[numobjects] * 1.5);
673         }
674         if (type[numobjects] == rocktype) {
675             model[numobjects].ScaleTexCoords(scale[numobjects] * 3);
676         }
677         model[numobjects].flat = 1;
678         if (atype == treetrunktype || atype == treeleavestype || atype == rocktype) {
679             model[numobjects].flat = 0;
680         }
681         model[numobjects].Scale(.3 * scale[numobjects], .3 * scale[numobjects], .3 * scale[numobjects]);
682         model[numobjects].Rotate(90, 1, 1);
683         model[numobjects].Rotate(apitch, 0, 0);
684         if (type[numobjects] == rocktype) {
685             model[numobjects].Rotate(ayaw * 5, 0, 0);
686         }
687         model[numobjects].CalculateNormals(1);
688         model[numobjects].ScaleNormals(-1, -1, -1);
689
690         if (atype == treetrunktype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
691             if (detail == 2)
692                 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 2, .4, 0);
693         }
694
695         if (atype == bushtype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
696             if (detail == 2)
697                 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 1, .4, 0);
698         }
699
700         if (atype != treeleavestype && atype != bushtype && atype != firetype)
701             terrain.AddObject(where + DoRotation(model[numobjects].boundingspherecenter, 0, ayaw, 0), model[numobjects].boundingsphereradius, numobjects);
702
703         numobjects++;
704     }
705 }
706
707 void Objects::DoStuff()
708 {
709     XYZ spawnpoint;
710     for (int i = 0; i < numobjects; i++) {
711         if (type[i] == firetype)
712             onfire[i] = 1;
713         if (onfire[i]) {
714             if (type[i] == bushtype)
715                 flamedelay[i] -= multiplier * 3;
716             if (type[i] == firetype)
717                 flamedelay[i] -= multiplier * 3;
718             if (type[i] == treeleavestype)
719                 flamedelay[i] -= multiplier * 4;
720             while (flamedelay[i] < 0 && onfire[i]) {
721                 flamedelay[i] += .006;
722                 if (type[i] == bushtype || type[i] == firetype) {
723                     spawnpoint.x = ((float)(Random() % 100)) / 30 * scale[i];
724                     spawnpoint.y = ((float)(Random() % 100) + 60) / 30 * scale[i];
725                     spawnpoint.z = 0;
726                     spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
727                     spawnpoint += position[i];
728                     Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 5 * scale[i], 1);
729                 }
730                 if (type[i] == treeleavestype) {
731                     spawnpoint.x = ((float)(Random() % 100)) / 80 * scale[i];
732                     spawnpoint.y = ((float)(Random() % 100) + 80) / 12 * scale[i];
733                     spawnpoint.z = 0;
734                     spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
735                     spawnpoint += position[i];
736                     Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 6, 1);
737                 }
738             }
739
740         }
741     }
742 }
743
744 void Objects::DoShadows()
745 {
746     int i, j, k, l;
747     static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
748     lightloc = light.location;
749     if (!skyboxtexture)
750         lightloc = 0;
751     lightloc.y += 10;
752     Normalise(&lightloc);
753     int patchx, patchz;
754
755     if (numobjects > 0)
756         for (i = 0; i < numobjects; i++) {
757             if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype) {
758                 for (j = 0; j < model[i].vertexNum; j++) {
759                     terrainpoint = position[i] + DoRotation(model[i].vertex[j] + model[i].normals[j] * .1, 0, yaw[i], 0);
760                     //terrainpoint.y+=model[i].boundingsphereradius;
761                     shadowed[i] = 0;
762                     patchx = terrainpoint.x / (terrain.size / subdivision * terrain.scale);
763                     patchz = terrainpoint.z / (terrain.size / subdivision * terrain.scale);
764                     if (patchx >= 0 && patchz >= 0 && patchx < subdivision && patchz < subdivision)
765                         if (terrain.patchobjectnum[patchx][patchz])
766                             for (k = 0; k < terrain.patchobjectnum[patchx][patchz]; k++) {
767                                 l = terrain.patchobjects[patchx][patchz][k];
768                                 if (type[l] != treetrunktype/*&&l!=i*/) {
769                                     testpoint = terrainpoint;
770                                     testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed[i]);
771                                     if (model[l].LineCheck(&testpoint, &testpoint2, &col, &position[l], &yaw[l]) != -1) {
772                                         shadowed[i] = 1 - (findDistance(&terrainpoint, &col) / 50);
773                                     }
774                                 }
775                             }
776                     if (shadowed[i] > 0) {
777                         col = model[i].normals[j] - DoRotation(lightloc * shadowed[i], 0, -yaw[i], 0);
778                         Normalise(&col);
779                         for (k = 0; k < model[i].TriangleNum; k++) {
780                             if (model[i].Triangles[k].vertex[0] == j) {
781                                 l = k * 24;
782                                 model[i].vArray[l + 2] = col.x;
783                                 model[i].vArray[l + 3] = col.y;
784                                 model[i].vArray[l + 4] = col.z;
785                             }
786                             if (model[i].Triangles[k].vertex[1] == j) {
787                                 l = k * 24;
788                                 model[i].vArray[l + 10] = col.x;
789                                 model[i].vArray[l + 11] = col.y;
790                                 model[i].vArray[l + 12] = col.z;
791                             }
792                             if (model[i].Triangles[k].vertex[2] == j) {
793                                 l = k * 24;
794                                 model[i].vArray[l + 18] = col.x;
795                                 model[i].vArray[l + 19] = col.y;
796                                 model[i].vArray[l + 20] = col.z;
797                             }
798                         }
799                     }
800                 }
801             }
802             shadowed[i] = 0;
803         }
804 }
805
806 Objects::Objects()
807 {
808     center = 0;
809     radius = 0;
810     numobjects = 0;
811
812     memset(position, 0, sizeof(position));
813     memset(type, 0, sizeof(type));
814     memset(yaw, 0, sizeof(yaw));
815     memset(pitch, 0, sizeof(pitch));
816     memset(rotx, 0, sizeof(rotx));
817     memset(rotxvel, 0, sizeof(rotxvel));
818     memset(roty, 0, sizeof(roty));
819     memset(rotyvel, 0, sizeof(rotyvel));
820     memset(possible, 0, sizeof(possible));
821     memset(model, 0, sizeof(model));
822     memset(displaymodel, 0, sizeof(displaymodel));
823     memset(friction, 0, sizeof(friction));
824     memset(scale, 0, sizeof(scale));
825     memset(messedwith, 0, sizeof(messedwith));
826     memset(checked, 0, sizeof(checked));
827     memset(shadowed, 0, sizeof(shadowed));
828     memset(occluded, 0, sizeof(occluded));
829     memset(onfire, 0, sizeof(onfire));
830     memset(flamedelay, 0, sizeof(flamedelay));
831 }
832
833 Objects::~Objects()
834 {
835     boxtextureptr.destroy();
836     treetextureptr.destroy();
837     bushtextureptr.destroy();
838     rocktextureptr.destroy();
839 };
840