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