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