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