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