2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
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.
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.
15 See the GNU General Public License for more details.
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.
24 extern float viewdistance;
25 extern float lightambient[3],lightbrightness[3];
26 extern float fadestart;
27 extern int environment;
28 extern float texscale;
30 extern float multiplier;
32 extern FRUSTUM frustum;
33 extern Terrain terrain;
34 extern float terraindetail;
37 extern float blurness;
39 extern float playerdist;
40 extern bool skyboxtexture;
41 extern Sprites sprites;
45 bool Objects::checkcollide(XYZ startpoint,XYZ endpoint,int which){
46 static XYZ colpoint,colviewer,coltarget;
54 for(i=0;i<numobjects;i++){
55 if(type[i]!=treeleavestype&&type[i]!=treetrunktype&&type[i]!=bushtype&&type[i]!=firetype&&i!=which){
58 if(model[i].LineCheck(&colviewer,&coltarget,&colpoint,&position[i],&rotation[i])!=-1)return 1;
65 void Objects::SphereCheckPossible(XYZ *p1,float radius)
68 static int whichpatchx;
69 static int whichpatchz;
71 whichpatchx=p1->x/(terrain.size/subdivision*terrain.scale*terraindetail);
72 whichpatchz=p1->z/(terrain.size/subdivision*terrain.scale*terraindetail);
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];
79 if(model[i].SphereCheckPossible(p1, radius, &position[i], &rotation[i])!=-1){
87 static float distance;
89 static XYZ moved,terrainlight;
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]);
98 hidden=!(findDistancefastflat(&viewer,&position[i])>playerdist+3||(type[i]!=bushtype&&type[i]!=treeleavestype));
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;
107 /*if(checkcollide(viewer,DoRotation(model[i].vertex[model[i].vertexNum],0,rotation[i],0)*scale[i]+position[i],i)){
110 else occluded[i]=0;*/
112 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
114 if(!model[i].color)glEnable(GL_LIGHTING);
115 else glDisable(GL_LIGHTING);
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;
130 rotx[i]+=rotxvel[i]*multiplier*4;
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;
142 roty[i]+=rotyvel[i]*multiplier*4;
145 glRotatef(roty[i],1,0,0);
148 glRotatef(-rotx[i],0,0,1);
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;
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;
168 rotx[i]+=rotxvel[i]*multiplier*4;
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;
180 roty[i]+=rotyvel[i]*multiplier*4;
183 glRotatef(roty[i]/6,1,0,0);
186 glRotatef(-rotx[i]/6,0,0,1);
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;
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;
206 rotx[i]+=rotxvel[i]*multiplier*4;
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;
218 roty[i]+=rotyvel[i]*multiplier*4;
221 glRotatef(roty[i]/4,1,0,0);
224 glRotatef(-rotx[i]/4,0,0,1);
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;
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);
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);
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);
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);
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);
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);
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);
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);
265 glAlphaFunc(GL_GREATER, 0.5);
269 glAlphaFunc(GL_GREATER, 0.1);
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);
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);
284 if(type[i]==treeleavestype){
285 glDisable(GL_CULL_FACE);
286 glDisable(GL_LIGHTING);
287 terrainlight=terrain.getLighting(position[i].x,position[i].z);
289 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance);
290 if(distance<1)glAlphaFunc(GL_GREATER, 0.2);
295 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance/3);
296 glAlphaFunc(GL_GREATER, 0);
298 model[i].drawdifftex(treetextureptr);
300 if(type[i]==bushtype){
301 glDisable(GL_CULL_FACE);
302 glDisable(GL_LIGHTING);
303 terrainlight=terrain.getLighting(position[i].x,position[i].z);
305 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance);
306 if(distance<1)glAlphaFunc(GL_GREATER, 0.2);
311 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance/3);
312 glAlphaFunc(GL_GREATER, 0);
314 model[i].drawdifftex(bushtextureptr);
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);
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;
339 if(1==1||occluded[i]<6){
340 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
342 glEnable(GL_LIGHTING);
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;
357 rotx[i]+=rotxvel[i]*multiplier*4;
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;
369 roty[i]+=rotyvel[i]*multiplier*4;
372 glRotatef(roty[i],1,0,0);
375 glRotatef(-rotx[i],0,0,1);
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;
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;
394 rotx[i]+=rotxvel[i]*multiplier*4;
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;
406 roty[i]+=rotyvel[i]*multiplier*4;
409 glRotatef(roty[i]/2,1,0,0);
412 glRotatef(-rotx[i]/2,0,0,1);
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;
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);
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);
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);
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);
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);
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);
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);
449 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,.3);
450 glAlphaFunc(GL_GREATER, 0);
451 glDisable(GL_ALPHA_TEST);
452 model[i].drawdifftex(treetextureptr);
454 if(type[i]==bushtype){
455 glDisable(GL_CULL_FACE);
456 glDisable(GL_LIGHTING);
457 terrainlight=terrain.getLighting(position[i].x,position[i].z);
460 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,.3);
461 glAlphaFunc(GL_GREATER, 0);
462 glDisable(GL_ALPHA_TEST);
463 model[i].drawdifftex(bushtextureptr);
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);
477 void Objects::DeleteObject(int which)
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;
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;
493 onfire[numobjects]=0;
494 flamedelay[numobjects]=0;
495 type[numobjects]=atype;
497 if(atype==firetype)onfire[numobjects]=1;
499 position[numobjects]=where;
500 if(atype==bushtype)position[numobjects].y=terrain.getHeight(position[numobjects].x,position[numobjects].z)-.3;
501 rotation[numobjects]=arotation;
503 rotxvel[numobjects]=0;
504 rotyvel[numobjects]=0;
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);
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;
533 if(atype==platformtype){
534 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid",0);
535 model[numobjects].Rotate(90,0,0);
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);
541 if(type[numobjects]==rocktype){
542 model[numobjects].ScaleTexCoords(scale[numobjects]*3);
544 model[numobjects].flat=1;
545 if(atype==treetrunktype||atype==treeleavestype||atype==rocktype){
546 model[numobjects].flat=0;
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);
553 model[numobjects].CalculateNormals(1);
554 model[numobjects].ScaleNormals(-1,-1,-1);
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);
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);
564 if(atype!=treeleavestype&&atype!=bushtype&&atype!=firetype)
565 terrain.AddObject(where+DoRotation(model[numobjects].boundingspherecenter,0,arotation,0),model[numobjects].boundingsphereradius,numobjects);
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;
576 onfire[numobjects]=0;
577 flamedelay[numobjects]=0;
578 type[numobjects]=atype;
580 if(atype==firetype)onfire[numobjects]=1;
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;
588 rotation[numobjects]=arotation;
589 rotation2[numobjects]=arotation2;
591 rotxvel[numobjects]=0;
592 rotyvel[numobjects]=0;
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);
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;
621 if(friction[numobjects]==1.5&&fabs(arotation2)>5)friction[numobjects]=.5;
623 if(atype==platformtype){
624 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid",0);
625 model[numobjects].Rotate(90,0,0);
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);
631 if(type[numobjects]==rocktype){
632 model[numobjects].ScaleTexCoords(scale[numobjects]*3);
634 model[numobjects].flat=1;
635 if(atype==treetrunktype||atype==treeleavestype||atype==rocktype){
636 model[numobjects].flat=0;
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);
644 model[numobjects].CalculateNormals(1);
645 model[numobjects].ScaleNormals(-1,-1,-1);
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);
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);
655 if(atype!=treeleavestype&&atype!=bushtype&&atype!=firetype)
656 terrain.AddObject(where+DoRotation(model[numobjects].boundingspherecenter,0,arotation,0),model[numobjects].boundingsphereradius,numobjects);
662 void Objects::DoStuff()
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);
670 if(type[i]==firetype)onfire[i]=1;
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]){
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];
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);
685 if(type[i]==treeleavestype){
686 spawnpoint.x=((float)(Random()%100))/80*scale[i];
687 spawnpoint.y=((float)(Random()%100)+80)/12*scale[i];
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);
699 void Objects::DoShadows()
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;
707 Normalise(&lightloc);
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;
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);
732 col=model[i].normals[j]-DoRotation(lightloc*shadowed[i],0,-rotation[i],0);
734 for(k=0;k<model[i].TriangleNum;k++){
735 if(model[i].Triangles[k].vertex[0]==j){
737 model[i].vArray[l+2]=col.x;
738 model[i].vArray[l+3]=col.y;
739 model[i].vArray[l+4]=col.z;
741 if(model[i].Triangles[k].vertex[1]==j){
743 model[i].vArray[l+10]=col.x;
744 model[i].vArray[l+11]=col.y;
745 model[i].vArray[l+12]=col.z;
747 if(model[i].Triangles[k].vertex[2]==j){
749 model[i].vArray[l+18]=col.x;
750 model[i].vArray[l+19]=col.y;
751 model[i].vArray[l+20]=col.z;
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));
794 if (boxtextureptr) glDeleteTextures( 1, &boxtextureptr );
795 if (treetextureptr) glDeleteTextures( 1, &treetextureptr );
796 if (bushtextureptr) glDeleteTextures( 1, &bushtextureptr );
797 if (rocktextureptr) glDeleteTextures( 1, &rocktextureptr );