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 fadestart;
26 extern int environment;
27 extern float texscale;
29 extern float multiplier;
31 extern FRUSTUM frustum;
32 extern Terrain terrain;
35 extern float blurness;
37 extern float playerdist;
38 extern bool skyboxtexture;
42 bool Objects::checkcollide(XYZ startpoint,XYZ endpoint,int which){
43 static XYZ colpoint,colviewer,coltarget;
51 for(i=0;i<numobjects;i++){
52 if(type[i]!=treeleavestype&&type[i]!=treetrunktype&&type[i]!=bushtype&&type[i]!=firetype&&i!=which){
55 if(model[i].LineCheck(&colviewer,&coltarget,&colpoint,&position[i],&yaw[i])!=-1)return 1;
62 void Objects::SphereCheckPossible(XYZ *p1,float radius)
65 static int whichpatchx;
66 static int whichpatchz;
68 whichpatchx=p1->x/(terrain.size/subdivision*terrain.scale);
69 whichpatchz=p1->z/(terrain.size/subdivision*terrain.scale);
71 if(whichpatchx>=0&&whichpatchz>=0&&whichpatchx<subdivision&&whichpatchz<subdivision)
72 if(terrain.patchobjectnum[whichpatchx][whichpatchz]>0&&terrain.patchobjectnum[whichpatchx][whichpatchz]<500)
73 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
74 i=terrain.patchobjects[whichpatchx][whichpatchz][j];
76 if(model[i].SphereCheckPossible(p1, radius, &position[i], &yaw[i])!=-1){
84 static float distance;
86 static XYZ moved,terrainlight;
89 for(i=0;i<numobjects;i++){
90 if(type[i]!=firetype){
91 moved=DoRotation(model[i].boundingspherecenter,0,yaw[i],0);
92 if(type[i]==tunneltype||frustum.SphereInFrustum(position[i].x+moved.x,position[i].y+moved.y,position[i].z+moved.z,model[i].boundingsphereradius)){
93 distance=distsq(&viewer,&position[i]);
95 hidden=!(distsqflat(&viewer,&position[i])>playerdist+3||(type[i]!=bushtype&&type[i]!=treeleavestype));
98 if(detail==2&&distance>viewdistance*viewdistance/4&&environment==desertenvironment)glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness );
99 else glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
100 distance=(viewdistance*viewdistance-(distance-(viewdistance*viewdistance*fadestart))*(1/(1-fadestart)))/viewdistance/viewdistance;
101 if(distance>1)distance=1;
104 /*if(checkcollide(viewer,DoRotation(model[i].vertex[model[i].vertexNum],0,yaw[i],0)*scale[i]+position[i],i)){
107 else occluded[i]=0;*/
109 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
111 if(!model[i].color)glEnable(GL_LIGHTING);
112 else glDisable(GL_LIGHTING);
114 glTranslatef(position[i].x,position[i].y,position[i].z);
115 if(type[i]==bushtype){
116 messedwith[i]-=multiplier;
117 if(rotxvel[i]||rotx[i]){
118 if(rotx[i]>0)rotxvel[i]-=multiplier*8*fabs(rotx[i]);
119 if(rotx[i]<0)rotxvel[i]+=multiplier*8*fabs(rotx[i]);
120 if(rotx[i]>0)rotxvel[i]-=multiplier*4;
121 if(rotx[i]<0)rotxvel[i]+=multiplier*4;
122 if(rotxvel[i]>0)rotxvel[i]-=multiplier*4;
123 if(rotxvel[i]<0)rotxvel[i]+=multiplier*4;
124 if(fabs(rotx[i])<multiplier*4)rotx[i]=0;
125 if(fabs(rotxvel[i])<multiplier*4)rotxvel[i]=0;
127 rotx[i]+=rotxvel[i]*multiplier*4;
129 if(rotyvel[i]||roty[i]){
130 if(roty[i]>0)rotyvel[i]-=multiplier*8*fabs(roty[i]);
131 if(roty[i]<0)rotyvel[i]+=multiplier*8*fabs(roty[i]);
132 if(roty[i]>0)rotyvel[i]-=multiplier*4;
133 if(roty[i]<0)rotyvel[i]+=multiplier*4;
134 if(rotyvel[i]>0)rotyvel[i]-=multiplier*4;
135 if(rotyvel[i]<0)rotyvel[i]+=multiplier*4;
136 if(fabs(roty[i])<multiplier*4)roty[i]=0;
137 if(fabs(rotyvel[i])<multiplier*4)rotyvel[i]=0;
139 roty[i]+=rotyvel[i]*multiplier*4;
142 glRotatef(roty[i],1,0,0);
145 glRotatef(-rotx[i],0,0,1);
147 if(rotx[i]>10)rotx[i]=10;
148 if(rotx[i]<-10)rotx[i]=-10;
149 if(roty[i]>10)roty[i]=10;
150 if(roty[i]<-10)roty[i]=-10;
152 if(type[i]==treetrunktype||type[i]==treeleavestype){
153 if(type[i]==treetrunktype||environment==2){
154 messedwith[i]-=multiplier;
155 if(rotxvel[i]||rotx[i]){
156 if(rotx[i]>0)rotxvel[i]-=multiplier*8*fabs(rotx[i]);
157 if(rotx[i]<0)rotxvel[i]+=multiplier*8*fabs(rotx[i]);
158 if(rotx[i]>0)rotxvel[i]-=multiplier*4;
159 if(rotx[i]<0)rotxvel[i]+=multiplier*4;
160 if(rotxvel[i]>0)rotxvel[i]-=multiplier*4;
161 if(rotxvel[i]<0)rotxvel[i]+=multiplier*4;
162 if(fabs(rotx[i])<multiplier*4)rotx[i]=0;
163 if(fabs(rotxvel[i])<multiplier*4)rotxvel[i]=0;
165 rotx[i]+=rotxvel[i]*multiplier*4;
167 if(rotyvel[i]||roty[i]){
168 if(roty[i]>0)rotyvel[i]-=multiplier*8*fabs(roty[i]);
169 if(roty[i]<0)rotyvel[i]+=multiplier*8*fabs(roty[i]);
170 if(roty[i]>0)rotyvel[i]-=multiplier*4;
171 if(roty[i]<0)rotyvel[i]+=multiplier*4;
172 if(rotyvel[i]>0)rotyvel[i]-=multiplier*4;
173 if(rotyvel[i]<0)rotyvel[i]+=multiplier*4;
174 if(fabs(roty[i])<multiplier*4)roty[i]=0;
175 if(fabs(rotyvel[i])<multiplier*4)rotyvel[i]=0;
177 roty[i]+=rotyvel[i]*multiplier*4;
180 glRotatef(roty[i]/6,1,0,0);
183 glRotatef(-rotx[i]/6,0,0,1);
185 if(rotx[i]>10)rotx[i]=10;
186 if(rotx[i]<-10)rotx[i]=-10;
187 if(roty[i]>10)roty[i]=10;
188 if(roty[i]<-10)roty[i]=-10;
192 messedwith[i]-=multiplier;
193 if(rotxvel[i]||rotx[i]){
194 if(rotx[i]>0)rotxvel[i]-=multiplier*8*fabs(rotx[i]);
195 if(rotx[i]<0)rotxvel[i]+=multiplier*8*fabs(rotx[i]);
196 if(rotx[i]>0)rotxvel[i]-=multiplier*4;
197 if(rotx[i]<0)rotxvel[i]+=multiplier*4;
198 if(rotxvel[i]>0)rotxvel[i]-=multiplier*4;
199 if(rotxvel[i]<0)rotxvel[i]+=multiplier*4;
200 if(fabs(rotx[i])<multiplier*4)rotx[i]=0;
201 if(fabs(rotxvel[i])<multiplier*4)rotxvel[i]=0;
203 rotx[i]+=rotxvel[i]*multiplier*4;
205 if(rotyvel[i]||roty[i]){
206 if(roty[i]>0)rotyvel[i]-=multiplier*8*fabs(roty[i]);
207 if(roty[i]<0)rotyvel[i]+=multiplier*8*fabs(roty[i]);
208 if(roty[i]>0)rotyvel[i]-=multiplier*4;
209 if(roty[i]<0)rotyvel[i]+=multiplier*4;
210 if(rotyvel[i]>0)rotyvel[i]-=multiplier*4;
211 if(rotyvel[i]<0)rotyvel[i]+=multiplier*4;
212 if(fabs(roty[i])<multiplier*4)roty[i]=0;
213 if(fabs(rotyvel[i])<multiplier*4)rotyvel[i]=0;
215 roty[i]+=rotyvel[i]*multiplier*4;
218 glRotatef(roty[i]/4,1,0,0);
221 glRotatef(-rotx[i]/4,0,0,1);
223 if(rotx[i]>10)rotx[i]=10;
224 if(rotx[i]<-10)rotx[i]=-10;
225 if(roty[i]>10)roty[i]=10;
226 if(roty[i]<-10)roty[i]=-10;
230 if(/*detail==2&&*/environment==snowyenvironment){
231 if(type[i]==treeleavestype){
232 glRotatef((sin(windvar+position[i].x*.3)+.5)*1.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
234 if(type[i]==treetrunktype){
235 glRotatef((sin(windvar+position[i].x*.3)+.5)*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
237 if(type[i]==bushtype){
238 glRotatef((sin(windvar+position[i].x*.3)+.5)*4*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
241 if(/*detail==2&&*/environment==grassyenvironment){
242 if(type[i]==treeleavestype){
243 glRotatef((sin(windvar+position[i].x*.3)+.5)*1.5*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
245 if(type[i]==treetrunktype){
246 glRotatef((sin(windvar+position[i].x*.3)+.5)*.5*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
248 if(type[i]==bushtype){
249 glRotatef((sin(windvar+position[i].x*.3)+.5)*4*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
252 if(/*detail==2&&*/environment==desertenvironment){
253 if(type[i]==bushtype){
254 glRotatef((sin(windvar+position[i].x*.3)+.5)*4*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
257 glRotatef(yaw[i],0,1,0);
258 if(distance>1)distance=1;
259 glColor4f((1-shadowed[i])/2+.5,(1-shadowed[i])/2+.5,(1-shadowed[i])/2+.5,distance);
262 glAlphaFunc(GL_GREATER, 0.5);
266 glAlphaFunc(GL_GREATER, 0.1);
268 if(type[i]!=treetrunktype&&type[i]!=treeleavestype&&type[i]!=bushtype&&type[i]!=rocktype){
269 glEnable(GL_CULL_FACE);
270 glAlphaFunc(GL_GREATER, 0.0001);
271 model[i].drawdifftex(boxtextureptr);
272 model[i].drawdecals(terrain.shadowtexture,terrain.bloodtexture,terrain.bloodtexture2,terrain.breaktexture);
274 if(type[i]==rocktype){
275 glEnable(GL_CULL_FACE);
276 glAlphaFunc(GL_GREATER, 0.0001);
277 glColor4f((1-shadowed[i])/2+light.ambient[0],(1-shadowed[i])/2+light.ambient[1],(1-shadowed[i])/2+light.ambient[2],distance);
278 model[i].drawdifftex(rocktextureptr);
279 model[i].drawdecals(terrain.shadowtexture,terrain.bloodtexture,terrain.bloodtexture2,terrain.breaktexture);
281 if(type[i]==treeleavestype){
282 glDisable(GL_CULL_FACE);
283 glDisable(GL_LIGHTING);
284 terrainlight=terrain.getLighting(position[i].x,position[i].z);
286 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance);
287 if(distance<1)glAlphaFunc(GL_GREATER, 0.2);
292 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance/3);
293 glAlphaFunc(GL_GREATER, 0);
295 model[i].drawdifftex(treetextureptr);
297 if(type[i]==bushtype){
298 glDisable(GL_CULL_FACE);
299 glDisable(GL_LIGHTING);
300 terrainlight=terrain.getLighting(position[i].x,position[i].z);
302 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance);
303 if(distance<1)glAlphaFunc(GL_GREATER, 0.2);
308 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance/3);
309 glAlphaFunc(GL_GREATER, 0);
311 model[i].drawdifftex(bushtextureptr);
313 if(type[i]==treetrunktype){
314 glEnable(GL_CULL_FACE);
315 terrainlight=terrain.getLighting(position[i].x,position[i].z);
316 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,distance);
317 model[i].drawdifftex(treetextureptr);
327 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
328 for(i=0;i<numobjects;i++){
329 if(type[i]==treeleavestype||type[i]==bushtype){
330 moved=DoRotation(model[i].boundingspherecenter,0,yaw[i],0);
331 if(frustum.SphereInFrustum(position[i].x+moved.x,position[i].y+moved.y,position[i].z+moved.z,model[i].boundingsphereradius)){
332 hidden=distsqflat(&viewer,&position[i])<=playerdist+3;
336 if(1==1||occluded[i]<6){
337 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
339 glEnable(GL_LIGHTING);
341 glTranslatef(position[i].x,position[i].y,position[i].z);
342 if(type[i]==bushtype){
343 messedwith[i]-=multiplier;
344 if(rotxvel[i]||rotx[i]){
345 if(rotx[i]>0)rotxvel[i]-=multiplier*8*fabs(rotx[i]);
346 if(rotx[i]<0)rotxvel[i]+=multiplier*8*fabs(rotx[i]);
347 if(rotx[i]>0)rotxvel[i]-=multiplier*4;
348 if(rotx[i]<0)rotxvel[i]+=multiplier*4;
349 if(rotxvel[i]>0)rotxvel[i]-=multiplier*4;
350 if(rotxvel[i]<0)rotxvel[i]+=multiplier*4;
351 if(fabs(rotx[i])<multiplier*4)rotx[i]=0;
352 if(fabs(rotxvel[i])<multiplier*4)rotxvel[i]=0;
354 rotx[i]+=rotxvel[i]*multiplier*4;
356 if(rotyvel[i]||roty[i]){
357 if(roty[i]>0)rotyvel[i]-=multiplier*8*fabs(roty[i]);
358 if(roty[i]<0)rotyvel[i]+=multiplier*8*fabs(roty[i]);
359 if(roty[i]>0)rotyvel[i]-=multiplier*4;
360 if(roty[i]<0)rotyvel[i]+=multiplier*4;
361 if(rotyvel[i]>0)rotyvel[i]-=multiplier*4;
362 if(rotyvel[i]<0)rotyvel[i]+=multiplier*4;
363 if(fabs(roty[i])<multiplier*4)roty[i]=0;
364 if(fabs(rotyvel[i])<multiplier*4)rotyvel[i]=0;
366 roty[i]+=rotyvel[i]*multiplier*4;
369 glRotatef(roty[i],1,0,0);
372 glRotatef(-rotx[i],0,0,1);
374 if(rotx[i]>10)rotx[i]=10;
375 if(rotx[i]<-10)rotx[i]=-10;
376 if(roty[i]>10)roty[i]=10;
377 if(roty[i]<-10)roty[i]=-10;
379 if(type[i]==treetrunktype||type[i]==treeleavestype){
380 messedwith[i]-=multiplier;
381 if(rotxvel[i]||rotx[i]){
382 if(rotx[i]>0)rotxvel[i]-=multiplier*8*fabs(rotx[i]);
383 if(rotx[i]<0)rotxvel[i]+=multiplier*8*fabs(rotx[i]);
384 if(rotx[i]>0)rotxvel[i]-=multiplier*4;
385 if(rotx[i]<0)rotxvel[i]+=multiplier*4;
386 if(rotxvel[i]>0)rotxvel[i]-=multiplier*4;
387 if(rotxvel[i]<0)rotxvel[i]+=multiplier*4;
388 if(fabs(rotx[i])<multiplier*4)rotx[i]=0;
389 if(fabs(rotxvel[i])<multiplier*4)rotxvel[i]=0;
391 rotx[i]+=rotxvel[i]*multiplier*4;
393 if(rotyvel[i]||roty[i]){
394 if(roty[i]>0)rotyvel[i]-=multiplier*8*fabs(roty[i]);
395 if(roty[i]<0)rotyvel[i]+=multiplier*8*fabs(roty[i]);
396 if(roty[i]>0)rotyvel[i]-=multiplier*4;
397 if(roty[i]<0)rotyvel[i]+=multiplier*4;
398 if(rotyvel[i]>0)rotyvel[i]-=multiplier*4;
399 if(rotyvel[i]<0)rotyvel[i]+=multiplier*4;
400 if(fabs(roty[i])<multiplier*4)roty[i]=0;
401 if(fabs(rotyvel[i])<multiplier*4)rotyvel[i]=0;
403 roty[i]+=rotyvel[i]*multiplier*4;
406 glRotatef(roty[i]/2,1,0,0);
409 glRotatef(-rotx[i]/2,0,0,1);
411 if(rotx[i]>10)rotx[i]=10;
412 if(rotx[i]<-10)rotx[i]=-10;
413 if(roty[i]>10)roty[i]=10;
414 if(roty[i]<-10)roty[i]=-10;
416 if(environment==snowyenvironment){
417 if(type[i]==treeleavestype){
418 glRotatef((sin(windvar+position[i].x*.3)+.5)*1.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
420 if(type[i]==treetrunktype){
421 glRotatef((sin(windvar+position[i].x*.3)+.5)*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
423 if(type[i]==bushtype){
424 glRotatef((sin(windvar+position[i].x*.3)+.5)*4*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
427 if(environment==grassyenvironment){
428 if(type[i]==treeleavestype){
429 glRotatef((sin(windvar+position[i].x*.3)+.5)*1.5*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
431 if(type[i]==treetrunktype){
432 glRotatef((sin(windvar+position[i].x*.3)+.5)*.5*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
434 if(type[i]==bushtype){
435 glRotatef((sin(windvar+position[i].x*.3)+.5)*4*.5*(sin(windvar*2+position[i].x*.3)+1)/2,1,0,0);
438 glRotatef(yaw[i],0,1,0);
439 glColor4f(1,1,1,distance);
440 if(type[i]==treeleavestype){
441 glDisable(GL_CULL_FACE);
442 glDisable(GL_LIGHTING);
443 terrainlight=terrain.getLighting(position[i].x,position[i].z);
446 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,.3);
447 glAlphaFunc(GL_GREATER, 0);
448 glDisable(GL_ALPHA_TEST);
449 model[i].drawdifftex(treetextureptr);
451 if(type[i]==bushtype){
452 glDisable(GL_CULL_FACE);
453 glDisable(GL_LIGHTING);
454 terrainlight=terrain.getLighting(position[i].x,position[i].z);
457 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,.3);
458 glAlphaFunc(GL_GREATER, 0);
459 glDisable(GL_ALPHA_TEST);
460 model[i].drawdifftex(bushtextureptr);
469 if(environment==desertenvironment)glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
470 glEnable(GL_ALPHA_TEST);
471 SetUpLight(&light,0);
474 void Objects::DeleteObject(int which)
476 type[numobjects-1]=0;
478 position[numobjects-1]=0;
479 scale[numobjects-1]=0;
480 friction[numobjects-1]=0;
485 void Objects::MakeObject(int atype, XYZ where, float ayaw, float ascale){
486 if((atype!=treeleavestype&&atype!=bushtype)||foliage==1){
487 scale[numobjects]=ascale;
488 if(atype==treeleavestype)scale[numobjects]+=fabs((float)(Random()%100)/900)*ascale;
490 onfire[numobjects]=0;
491 flamedelay[numobjects]=0;
492 type[numobjects]=atype;
494 if(atype==firetype)onfire[numobjects]=1;
496 position[numobjects]=where;
497 if(atype==bushtype)position[numobjects].y=terrain.getHeight(position[numobjects].x,position[numobjects].z)-.3;
498 yaw[numobjects]=ayaw;
500 rotxvel[numobjects]=0;
501 rotyvel[numobjects]=0;
505 if(atype==boxtype)model[numobjects].loaddecal((char *)":Data:Models:Box.solid",0);
506 if(atype==cooltype)model[numobjects].loaddecal((char *)":Data:Models:Cool.solid",0);
507 if(atype==walltype)model[numobjects].loaddecal((char *)":Data:Models:Wall.solid",0);
508 if(atype==tunneltype)model[numobjects].loaddecal((char *)":Data:Models:Tunnel.solid",0);
509 if(atype==chimneytype)model[numobjects].loaddecal((char *)":Data:Models:Chimney.solid",0);
510 if(atype==spiketype)model[numobjects].load((char *)":Data:Models:Spike.solid",0);
511 if(atype==weirdtype)model[numobjects].loaddecal((char *)":Data:Models:Weird.solid",0);
512 if(atype==rocktype)model[numobjects].loaddecal((char *)":Data:Models:Rock.solid",0);
513 if(atype==treetrunktype)model[numobjects].load((char *)":Data:Models:Treetrunk.solid",0);
514 if(atype==treeleavestype)model[numobjects].load((char *)":Data:Models:Leaves.solid",0);
515 if(atype==bushtype)model[numobjects].load((char *)":Data:Models:Bush.solid",0);
517 if(atype==boxtype)friction[numobjects]=1.5;
518 if(atype==cooltype)friction[numobjects]=1.5;
519 if(atype==walltype)friction[numobjects]=1.5;
520 if(atype==platformtype)friction[numobjects]=1.5;
521 if(atype==tunneltype)friction[numobjects]=1.5;
522 if(atype==chimneytype)friction[numobjects]=1.5;
523 if(atype==rocktype)friction[numobjects]=.5;
524 if(atype==rocktype&&ascale>.5)friction[numobjects]=1.5;
525 if(atype==weirdtype)friction[numobjects]=1.5;
526 if(atype==spiketype)friction[numobjects]=.4;
527 if(atype==treetrunktype)friction[numobjects]=.4;
528 if(atype==treeleavestype)friction[numobjects]=0;
530 if(atype==platformtype){
531 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid",0);
532 model[numobjects].Rotate(90,0,0);
535 if(type[numobjects]==boxtype||type[numobjects]==cooltype||type[numobjects]==spiketype||type[numobjects]==weirdtype||type[numobjects]==walltype||type[numobjects]==chimneytype||type[numobjects]==tunneltype||type[numobjects]==platformtype){
536 model[numobjects].ScaleTexCoords(scale[numobjects]*1.5);
538 if(type[numobjects]==rocktype){
539 model[numobjects].ScaleTexCoords(scale[numobjects]*3);
541 model[numobjects].flat=1;
542 if(atype==treetrunktype||atype==treeleavestype||atype==rocktype){
543 model[numobjects].flat=0;
545 model[numobjects].Scale(.3*scale[numobjects],.3*scale[numobjects],.3*scale[numobjects]);
546 model[numobjects].Rotate(90,1,1);
547 if(type[numobjects]==rocktype){
548 model[numobjects].Rotate(ayaw*5,1,1);
550 model[numobjects].CalculateNormals(1);
551 model[numobjects].ScaleNormals(-1,-1,-1);
553 if(atype==treetrunktype&&position[numobjects].y<terrain.getHeight(position[numobjects].x,position[numobjects].z)+1){
554 if(detail==2)terrain.MakeDecal(shadowdecalpermanent,position[numobjects],2,.4,0);
557 if(atype==bushtype&&position[numobjects].y<terrain.getHeight(position[numobjects].x,position[numobjects].z)+1){
558 if(detail==2)terrain.MakeDecal(shadowdecalpermanent,position[numobjects],1,.4,0);
561 if(atype!=treeleavestype&&atype!=bushtype&&atype!=firetype)
562 terrain.AddObject(where+DoRotation(model[numobjects].boundingspherecenter,0,ayaw,0),model[numobjects].boundingsphereradius,numobjects);
568 void Objects::MakeObject(int atype, XYZ where, float ayaw, float apitch, float ascale){
569 if((atype!=treeleavestype&&atype!=bushtype)||foliage==1){
570 scale[numobjects]=ascale;
571 if(atype==treeleavestype)scale[numobjects]+=fabs((float)(Random()%100)/900)*ascale;
573 onfire[numobjects]=0;
574 flamedelay[numobjects]=0;
575 type[numobjects]=atype;
577 if(atype==firetype)onfire[numobjects]=1;
579 position[numobjects]=where;
580 if(atype==bushtype)position[numobjects].y=terrain.getHeight(position[numobjects].x,position[numobjects].z)-.3;
581 /*if(atype==firetype){
582 if(position[numobjects].y<terrain.getHeight(position[numobjects].x,position[numobjects].z)-.3)
583 position[numobjects].y=terrain.getHeight(position[numobjects].x,position[numobjects].z)-.3;
585 yaw[numobjects]=ayaw;
586 pitch[numobjects]=apitch;
588 rotxvel[numobjects]=0;
589 rotyvel[numobjects]=0;
593 if(atype==boxtype)model[numobjects].loaddecal((char *)":Data:Models:Box.solid",0);
594 if(atype==cooltype)model[numobjects].loaddecal((char *)":Data:Models:Cool.solid",0);
595 if(atype==walltype)model[numobjects].loaddecal((char *)":Data:Models:Wall.solid",0);
596 if(atype==tunneltype)model[numobjects].loaddecal((char *)":Data:Models:Tunnel.solid",0);
597 if(atype==chimneytype)model[numobjects].loaddecal((char *)":Data:Models:Chimney.solid",0);
598 if(atype==spiketype)model[numobjects].load((char *)":Data:Models:Spike.solid",0);
599 if(atype==weirdtype)model[numobjects].loaddecal((char *)":Data:Models:Weird.solid",0);
600 if(atype==rocktype)model[numobjects].loaddecal((char *)":Data:Models:Rock.solid",0);
601 if(atype==treetrunktype)model[numobjects].load((char *)":Data:Models:Treetrunk.solid",0);
602 if(atype==treeleavestype)model[numobjects].load((char *)":Data:Models:Leaves.solid",0);
603 if(atype==bushtype)model[numobjects].load((char *)":Data:Models:Bush.solid",0);
605 if(atype==boxtype)friction[numobjects]=1.5;
606 if(atype==cooltype)friction[numobjects]=1.5;
607 if(atype==walltype)friction[numobjects]=1.5;
608 if(atype==platformtype)friction[numobjects]=1.5;
609 if(atype==tunneltype)friction[numobjects]=1.5;
610 if(atype==chimneytype)friction[numobjects]=1.5;
611 if(atype==rocktype)friction[numobjects]=.5;
612 if(atype==rocktype&&ascale>.5)friction[numobjects]=1.5;
613 if(atype==weirdtype)friction[numobjects]=1.5;
614 if(atype==spiketype)friction[numobjects]=.4;
615 if(atype==treetrunktype)friction[numobjects]=.4;
616 if(atype==treeleavestype)friction[numobjects]=0;
618 if(friction[numobjects]==1.5&&fabs(apitch)>5)friction[numobjects]=.5;
620 if(atype==platformtype){
621 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid",0);
622 model[numobjects].Rotate(90,0,0);
625 if(type[numobjects]==boxtype||type[numobjects]==cooltype||type[numobjects]==spiketype||type[numobjects]==weirdtype||type[numobjects]==walltype||type[numobjects]==chimneytype||type[numobjects]==tunneltype||type[numobjects]==platformtype){
626 model[numobjects].ScaleTexCoords(scale[numobjects]*1.5);
628 if(type[numobjects]==rocktype){
629 model[numobjects].ScaleTexCoords(scale[numobjects]*3);
631 model[numobjects].flat=1;
632 if(atype==treetrunktype||atype==treeleavestype||atype==rocktype){
633 model[numobjects].flat=0;
635 model[numobjects].Scale(.3*scale[numobjects],.3*scale[numobjects],.3*scale[numobjects]);
636 model[numobjects].Rotate(90,1,1);
637 model[numobjects].Rotate(apitch,0,0);
638 if(type[numobjects]==rocktype){
639 model[numobjects].Rotate(ayaw*5,0,0);
641 model[numobjects].CalculateNormals(1);
642 model[numobjects].ScaleNormals(-1,-1,-1);
644 if(atype==treetrunktype&&position[numobjects].y<terrain.getHeight(position[numobjects].x,position[numobjects].z)+1){
645 if(detail==2)terrain.MakeDecal(shadowdecalpermanent,position[numobjects],2,.4,0);
648 if(atype==bushtype&&position[numobjects].y<terrain.getHeight(position[numobjects].x,position[numobjects].z)+1){
649 if(detail==2)terrain.MakeDecal(shadowdecalpermanent,position[numobjects],1,.4,0);
652 if(atype!=treeleavestype&&atype!=bushtype&&atype!=firetype)
653 terrain.AddObject(where+DoRotation(model[numobjects].boundingspherecenter,0,ayaw,0),model[numobjects].boundingsphereradius,numobjects);
659 void Objects::DoStuff()
662 for(int i=0;i<numobjects;i++){
663 /*if(type[i]==firetype){
664 Sprite::MakeSprite(weaponshinesprite, position[i],position[i]*0, 1,1,1, 5, 1);
667 if(type[i]==firetype)onfire[i]=1;
669 if(type[i]==bushtype)flamedelay[i]-=multiplier*3;
670 if(type[i]==firetype)flamedelay[i]-=multiplier*3;
671 if(type[i]==treeleavestype)flamedelay[i]-=multiplier*4;
672 while(flamedelay[i]<0&&onfire[i]){
674 if(type[i]==bushtype||type[i]==firetype){
675 spawnpoint.x=((float)(Random()%100))/30*scale[i];
676 spawnpoint.y=((float)(Random()%100)+60)/30*scale[i];
678 spawnpoint=DoRotation(spawnpoint,0,Random()%360,0);
679 spawnpoint+=position[i];
680 Sprite::MakeSprite(flamesprite, spawnpoint,spawnpoint*0, 1,1,1, (.6+(float)abs(Random()%100)/200-.25)*5*scale[i], 1);
682 if(type[i]==treeleavestype){
683 spawnpoint.x=((float)(Random()%100))/80*scale[i];
684 spawnpoint.y=((float)(Random()%100)+80)/12*scale[i];
686 spawnpoint=DoRotation(spawnpoint,0,Random()%360,0);
687 spawnpoint+=position[i];
688 Sprite::MakeSprite(flamesprite, spawnpoint,spawnpoint*0, 1,1,1, (.6+(float)abs(Random()%100)/200-.25)*6, 1);
696 void Objects::DoShadows()
699 static XYZ testpoint,testpoint2, terrainpoint,lightloc,col;
700 lightloc=light.location;
701 if(!skyboxtexture)lightloc=0;
703 Normalise(&lightloc);
707 for(i=0;i<numobjects;i++){
708 if(type[i]!=treeleavestype&&type[i]!=treetrunktype&&type[i]!=bushtype&&type[i]!=firetype){
709 for(j=0;j<model[i].vertexNum;j++){
710 terrainpoint=position[i]+DoRotation(model[i].vertex[j]+model[i].normals[j]*.1,0,yaw[i],0);
711 //terrainpoint.y+=model[i].boundingsphereradius;
713 patchx=terrainpoint.x/(terrain.size/subdivision*terrain.scale);
714 patchz=terrainpoint.z/(terrain.size/subdivision*terrain.scale);
715 if(patchx>=0&&patchz>=0&&patchx<subdivision&&patchz<subdivision)
716 if(terrain.patchobjectnum[patchx][patchz])
717 for(k=0;k<terrain.patchobjectnum[patchx][patchz];k++){
718 l=terrain.patchobjects[patchx][patchz][k];
719 if(type[l]!=treetrunktype/*&&l!=i*/){
720 testpoint=terrainpoint;
721 testpoint2=terrainpoint+lightloc*50*(1-shadowed[i]);
722 if(model[l].LineCheck(&testpoint,&testpoint2,&col,&position[l],&yaw[l])!=-1){
723 shadowed[i]=1-(findDistance(&terrainpoint,&col)/50);
728 col=model[i].normals[j]-DoRotation(lightloc*shadowed[i],0,-yaw[i],0);
730 for(k=0;k<model[i].TriangleNum;k++){
731 if(model[i].Triangles[k].vertex[0]==j){
733 model[i].vArray[l+2]=col.x;
734 model[i].vArray[l+3]=col.y;
735 model[i].vArray[l+4]=col.z;
737 if(model[i].Triangles[k].vertex[1]==j){
739 model[i].vArray[l+10]=col.x;
740 model[i].vArray[l+11]=col.y;
741 model[i].vArray[l+12]=col.z;
743 if(model[i].Triangles[k].vertex[2]==j){
745 model[i].vArray[l+18]=col.x;
746 model[i].vArray[l+19]=col.y;
747 model[i].vArray[l+20]=col.z;
763 memset(position, 0, sizeof(position));
764 memset(type, 0, sizeof(type));
765 memset(yaw, 0, sizeof(yaw));
766 memset(pitch, 0, sizeof(pitch));
767 memset(rotx, 0, sizeof(rotx));
768 memset(rotxvel, 0, sizeof(rotxvel));
769 memset(roty, 0, sizeof(roty));
770 memset(rotyvel, 0, sizeof(rotyvel));
771 memset(possible, 0, sizeof(possible));
772 memset(model, 0, sizeof(model));
773 memset(displaymodel, 0, sizeof(displaymodel));
774 memset(friction, 0, sizeof(friction));
775 memset(scale, 0, sizeof(scale));
776 memset(messedwith, 0, sizeof(messedwith));
777 memset(checked, 0, sizeof(checked));
778 memset(shadowed, 0, sizeof(shadowed));
779 memset(occluded, 0, sizeof(occluded));
780 memset(onfire, 0, sizeof(onfire));
781 memset(flamedelay, 0, sizeof(flamedelay));
786 boxtextureptr.destroy();
787 treetextureptr.destroy();
788 bushtextureptr.destroy();
789 rocktextureptr.destroy();