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