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