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;
36 extern float blurness;
38 extern float playerdist;
39 extern bool skyboxtexture;
43 bool Objects::checkcollide(XYZ startpoint,XYZ endpoint,int which){
44 static XYZ colpoint,colviewer,coltarget;
52 for(i=0;i<numobjects;i++){
53 if(type[i]!=treeleavestype&&type[i]!=treetrunktype&&type[i]!=bushtype&&type[i]!=firetype&&i!=which){
56 if(model[i].LineCheck(&colviewer,&coltarget,&colpoint,&position[i],&rotation[i])!=-1)return 1;
63 void Objects::SphereCheckPossible(XYZ *p1,float radius)
66 static int whichpatchx;
67 static int whichpatchz;
69 whichpatchx=p1->x/(terrain.size/subdivision*terrain.scale);
70 whichpatchz=p1->z/(terrain.size/subdivision*terrain.scale);
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];
77 if(model[i].SphereCheckPossible(p1, radius, &position[i], &rotation[i])!=-1){
85 static float distance;
87 static XYZ moved,terrainlight;
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]);
96 hidden=!(findDistancefastflat(&viewer,&position[i])>playerdist+3||(type[i]!=bushtype&&type[i]!=treeleavestype));
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;
105 /*if(checkcollide(viewer,DoRotation(model[i].vertex[model[i].vertexNum],0,rotation[i],0)*scale[i]+position[i],i)){
108 else occluded[i]=0;*/
110 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
112 if(!model[i].color)glEnable(GL_LIGHTING);
113 else glDisable(GL_LIGHTING);
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;
128 rotx[i]+=rotxvel[i]*multiplier*4;
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;
140 roty[i]+=rotyvel[i]*multiplier*4;
143 glRotatef(roty[i],1,0,0);
146 glRotatef(-rotx[i],0,0,1);
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;
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;
166 rotx[i]+=rotxvel[i]*multiplier*4;
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;
178 roty[i]+=rotyvel[i]*multiplier*4;
181 glRotatef(roty[i]/6,1,0,0);
184 glRotatef(-rotx[i]/6,0,0,1);
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;
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;
204 rotx[i]+=rotxvel[i]*multiplier*4;
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;
216 roty[i]+=rotyvel[i]*multiplier*4;
219 glRotatef(roty[i]/4,1,0,0);
222 glRotatef(-rotx[i]/4,0,0,1);
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;
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);
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);
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);
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);
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);
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);
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);
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);
263 glAlphaFunc(GL_GREATER, 0.5);
267 glAlphaFunc(GL_GREATER, 0.1);
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);
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);
282 if(type[i]==treeleavestype){
283 glDisable(GL_CULL_FACE);
284 glDisable(GL_LIGHTING);
285 terrainlight=terrain.getLighting(position[i].x,position[i].z);
287 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance);
288 if(distance<1)glAlphaFunc(GL_GREATER, 0.2);
293 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance/3);
294 glAlphaFunc(GL_GREATER, 0);
296 model[i].drawdifftex(treetextureptr);
298 if(type[i]==bushtype){
299 glDisable(GL_CULL_FACE);
300 glDisable(GL_LIGHTING);
301 terrainlight=terrain.getLighting(position[i].x,position[i].z);
303 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance);
304 if(distance<1)glAlphaFunc(GL_GREATER, 0.2);
309 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance/3);
310 glAlphaFunc(GL_GREATER, 0);
312 model[i].drawdifftex(bushtextureptr);
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);
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;
337 if(1==1||occluded[i]<6){
338 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
340 glEnable(GL_LIGHTING);
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;
355 rotx[i]+=rotxvel[i]*multiplier*4;
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;
367 roty[i]+=rotyvel[i]*multiplier*4;
370 glRotatef(roty[i],1,0,0);
373 glRotatef(-rotx[i],0,0,1);
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;
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;
392 rotx[i]+=rotxvel[i]*multiplier*4;
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;
404 roty[i]+=rotyvel[i]*multiplier*4;
407 glRotatef(roty[i]/2,1,0,0);
410 glRotatef(-rotx[i]/2,0,0,1);
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;
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);
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);
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);
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);
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);
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);
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);
447 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,.3);
448 glAlphaFunc(GL_GREATER, 0);
449 glDisable(GL_ALPHA_TEST);
450 model[i].drawdifftex(treetextureptr);
452 if(type[i]==bushtype){
453 glDisable(GL_CULL_FACE);
454 glDisable(GL_LIGHTING);
455 terrainlight=terrain.getLighting(position[i].x,position[i].z);
458 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,.3);
459 glAlphaFunc(GL_GREATER, 0);
460 glDisable(GL_ALPHA_TEST);
461 model[i].drawdifftex(bushtextureptr);
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);
475 void Objects::DeleteObject(int which)
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;
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;
491 onfire[numobjects]=0;
492 flamedelay[numobjects]=0;
493 type[numobjects]=atype;
495 if(atype==firetype)onfire[numobjects]=1;
497 position[numobjects]=where;
498 if(atype==bushtype)position[numobjects].y=terrain.getHeight(position[numobjects].x,position[numobjects].z)-.3;
499 rotation[numobjects]=arotation;
501 rotxvel[numobjects]=0;
502 rotyvel[numobjects]=0;
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);
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;
531 if(atype==platformtype){
532 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid",0);
533 model[numobjects].Rotate(90,0,0);
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);
539 if(type[numobjects]==rocktype){
540 model[numobjects].ScaleTexCoords(scale[numobjects]*3);
542 model[numobjects].flat=1;
543 if(atype==treetrunktype||atype==treeleavestype||atype==rocktype){
544 model[numobjects].flat=0;
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);
551 model[numobjects].CalculateNormals(1);
552 model[numobjects].ScaleNormals(-1,-1,-1);
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);
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);
562 if(atype!=treeleavestype&&atype!=bushtype&&atype!=firetype)
563 terrain.AddObject(where+DoRotation(model[numobjects].boundingspherecenter,0,arotation,0),model[numobjects].boundingsphereradius,numobjects);
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;
574 onfire[numobjects]=0;
575 flamedelay[numobjects]=0;
576 type[numobjects]=atype;
578 if(atype==firetype)onfire[numobjects]=1;
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;
586 rotation[numobjects]=arotation;
587 rotation2[numobjects]=arotation2;
589 rotxvel[numobjects]=0;
590 rotyvel[numobjects]=0;
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);
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;
619 if(friction[numobjects]==1.5&&fabs(arotation2)>5)friction[numobjects]=.5;
621 if(atype==platformtype){
622 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid",0);
623 model[numobjects].Rotate(90,0,0);
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);
629 if(type[numobjects]==rocktype){
630 model[numobjects].ScaleTexCoords(scale[numobjects]*3);
632 model[numobjects].flat=1;
633 if(atype==treetrunktype||atype==treeleavestype||atype==rocktype){
634 model[numobjects].flat=0;
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);
642 model[numobjects].CalculateNormals(1);
643 model[numobjects].ScaleNormals(-1,-1,-1);
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);
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);
653 if(atype!=treeleavestype&&atype!=bushtype&&atype!=firetype)
654 terrain.AddObject(where+DoRotation(model[numobjects].boundingspherecenter,0,arotation,0),model[numobjects].boundingsphereradius,numobjects);
660 void Objects::DoStuff()
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);
668 if(type[i]==firetype)onfire[i]=1;
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]){
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];
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);
683 if(type[i]==treeleavestype){
684 spawnpoint.x=((float)(Random()%100))/80*scale[i];
685 spawnpoint.y=((float)(Random()%100)+80)/12*scale[i];
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);
697 void Objects::DoShadows()
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;
705 Normalise(&lightloc);
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;
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);
730 col=model[i].normals[j]-DoRotation(lightloc*shadowed[i],0,-rotation[i],0);
732 for(k=0;k<model[i].TriangleNum;k++){
733 if(model[i].Triangles[k].vertex[0]==j){
735 model[i].vArray[l+2]=col.x;
736 model[i].vArray[l+3]=col.y;
737 model[i].vArray[l+4]=col.z;
739 if(model[i].Triangles[k].vertex[1]==j){
741 model[i].vArray[l+10]=col.x;
742 model[i].vArray[l+11]=col.y;
743 model[i].vArray[l+12]=col.z;
745 if(model[i].Triangles[k].vertex[2]==j){
747 model[i].vArray[l+18]=col.x;
748 model[i].vArray[l+19]=col.y;
749 model[i].vArray[l+20]=col.z;
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));
792 if (boxtextureptr) glDeleteTextures( 1, &boxtextureptr );
793 if (treetextureptr) glDeleteTextures( 1, &treetextureptr );
794 if (bushtextureptr) glDeleteTextures( 1, &bushtextureptr );
795 if (rocktextureptr) glDeleteTextures( 1, &rocktextureptr );