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)
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) {
54 colviewer = startpoint;
56 if (model[i].LineCheck(&colviewer, &coltarget, &colpoint, &position[i], &yaw[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], &yaw[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, yaw[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 = distsq(&viewer, &position[i]);
96 hidden = !(distsqflat(&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,yaw[i],0)*scale[i]+position[i],i)){
108 else occluded[i]=0;*/
109 if (occluded[i] < 6) {
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;
191 messedwith[i] -= multiplier;
192 if (rotxvel[i] || rotx[i]) {
193 if (rotx[i] > 0)rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
194 if (rotx[i] < 0)rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
195 if (rotx[i] > 0)rotxvel[i] -= multiplier * 4;
196 if (rotx[i] < 0)rotxvel[i] += multiplier * 4;
197 if (rotxvel[i] > 0)rotxvel[i] -= multiplier * 4;
198 if (rotxvel[i] < 0)rotxvel[i] += multiplier * 4;
199 if (fabs(rotx[i]) < multiplier * 4)rotx[i] = 0;
200 if (fabs(rotxvel[i]) < multiplier * 4)rotxvel[i] = 0;
202 rotx[i] += rotxvel[i] * multiplier * 4;
204 if (rotyvel[i] || roty[i]) {
205 if (roty[i] > 0)rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
206 if (roty[i] < 0)rotyvel[i] += multiplier * 8 * fabs(roty[i]);
207 if (roty[i] > 0)rotyvel[i] -= multiplier * 4;
208 if (roty[i] < 0)rotyvel[i] += multiplier * 4;
209 if (rotyvel[i] > 0)rotyvel[i] -= multiplier * 4;
210 if (rotyvel[i] < 0)rotyvel[i] += multiplier * 4;
211 if (fabs(roty[i]) < multiplier * 4)roty[i] = 0;
212 if (fabs(rotyvel[i]) < multiplier * 4)rotyvel[i] = 0;
214 roty[i] += rotyvel[i] * multiplier * 4;
217 glRotatef(roty[i] / 4, 1, 0, 0);
220 glRotatef(-rotx[i] / 4, 0, 0, 1);
222 if (rotx[i] > 10)rotx[i] = 10;
223 if (rotx[i] < -10)rotx[i] = -10;
224 if (roty[i] > 10)roty[i] = 10;
225 if (roty[i] < -10)roty[i] = -10;
229 if (/*detail==2&&*/environment == snowyenvironment) {
230 if (type[i] == treeleavestype) {
231 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
233 if (type[i] == treetrunktype) {
234 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
236 if (type[i] == bushtype) {
237 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
240 if (/*detail==2&&*/environment == grassyenvironment) {
241 if (type[i] == treeleavestype) {
242 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
244 if (type[i] == treetrunktype) {
245 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
247 if (type[i] == bushtype) {
248 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
251 if (/*detail==2&&*/environment == desertenvironment) {
252 if (type[i] == bushtype) {
253 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
256 glRotatef(yaw[i], 0, 1, 0);
257 if (distance > 1)distance = 1;
258 glColor4f((1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, distance);
261 glAlphaFunc(GL_GREATER, 0.5);
265 glAlphaFunc(GL_GREATER, 0.1);
267 if (type[i] != treetrunktype && type[i] != treeleavestype && type[i] != bushtype && type[i] != rocktype) {
268 glEnable(GL_CULL_FACE);
269 glAlphaFunc(GL_GREATER, 0.0001);
270 model[i].drawdifftex(boxtextureptr);
271 model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
273 if (type[i] == rocktype) {
274 glEnable(GL_CULL_FACE);
275 glAlphaFunc(GL_GREATER, 0.0001);
276 glColor4f((1 - shadowed[i]) / 2 + light.ambient[0], (1 - shadowed[i]) / 2 + light.ambient[1], (1 - shadowed[i]) / 2 + light.ambient[2], distance);
277 model[i].drawdifftex(rocktextureptr);
278 model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
280 if (type[i] == treeleavestype) {
281 glDisable(GL_CULL_FACE);
282 glDisable(GL_LIGHTING);
283 terrainlight = terrain.getLighting(position[i].x, position[i].z);
285 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
286 if (distance < 1)glAlphaFunc(GL_GREATER, 0.2);
291 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
292 glAlphaFunc(GL_GREATER, 0);
294 model[i].drawdifftex(treetextureptr);
296 if (type[i] == bushtype) {
297 glDisable(GL_CULL_FACE);
298 glDisable(GL_LIGHTING);
299 terrainlight = terrain.getLighting(position[i].x, position[i].z);
301 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
302 if (distance < 1)glAlphaFunc(GL_GREATER, 0.2);
307 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
308 glAlphaFunc(GL_GREATER, 0);
310 model[i].drawdifftex(bushtextureptr);
312 if (type[i] == treetrunktype) {
313 glEnable(GL_CULL_FACE);
314 terrainlight = terrain.getLighting(position[i].x, position[i].z);
315 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
316 model[i].drawdifftex(treetextureptr);
326 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
327 for (i = 0; i < numobjects; i++) {
328 if (type[i] == treeleavestype || type[i] == bushtype) {
329 moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
330 if (frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
331 hidden = distsqflat(&viewer, &position[i]) <= playerdist + 3;
335 if (1 == 1 || occluded[i] < 6) {
336 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
338 glEnable(GL_LIGHTING);
340 glTranslatef(position[i].x, position[i].y, position[i].z);
341 if (type[i] == bushtype) {
342 messedwith[i] -= multiplier;
343 if (rotxvel[i] || rotx[i]) {
344 if (rotx[i] > 0)rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
345 if (rotx[i] < 0)rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
346 if (rotx[i] > 0)rotxvel[i] -= multiplier * 4;
347 if (rotx[i] < 0)rotxvel[i] += multiplier * 4;
348 if (rotxvel[i] > 0)rotxvel[i] -= multiplier * 4;
349 if (rotxvel[i] < 0)rotxvel[i] += multiplier * 4;
350 if (fabs(rotx[i]) < multiplier * 4)rotx[i] = 0;
351 if (fabs(rotxvel[i]) < multiplier * 4)rotxvel[i] = 0;
353 rotx[i] += rotxvel[i] * multiplier * 4;
355 if (rotyvel[i] || roty[i]) {
356 if (roty[i] > 0)rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
357 if (roty[i] < 0)rotyvel[i] += multiplier * 8 * fabs(roty[i]);
358 if (roty[i] > 0)rotyvel[i] -= multiplier * 4;
359 if (roty[i] < 0)rotyvel[i] += multiplier * 4;
360 if (rotyvel[i] > 0)rotyvel[i] -= multiplier * 4;
361 if (rotyvel[i] < 0)rotyvel[i] += multiplier * 4;
362 if (fabs(roty[i]) < multiplier * 4)roty[i] = 0;
363 if (fabs(rotyvel[i]) < multiplier * 4)rotyvel[i] = 0;
365 roty[i] += rotyvel[i] * multiplier * 4;
368 glRotatef(roty[i], 1, 0, 0);
371 glRotatef(-rotx[i], 0, 0, 1);
373 if (rotx[i] > 10)rotx[i] = 10;
374 if (rotx[i] < -10)rotx[i] = -10;
375 if (roty[i] > 10)roty[i] = 10;
376 if (roty[i] < -10)roty[i] = -10;
378 if (type[i] == treetrunktype || type[i] == treeleavestype) {
379 messedwith[i] -= multiplier;
380 if (rotxvel[i] || rotx[i]) {
381 if (rotx[i] > 0)rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
382 if (rotx[i] < 0)rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
383 if (rotx[i] > 0)rotxvel[i] -= multiplier * 4;
384 if (rotx[i] < 0)rotxvel[i] += multiplier * 4;
385 if (rotxvel[i] > 0)rotxvel[i] -= multiplier * 4;
386 if (rotxvel[i] < 0)rotxvel[i] += multiplier * 4;
387 if (fabs(rotx[i]) < multiplier * 4)rotx[i] = 0;
388 if (fabs(rotxvel[i]) < multiplier * 4)rotxvel[i] = 0;
390 rotx[i] += rotxvel[i] * multiplier * 4;
392 if (rotyvel[i] || roty[i]) {
393 if (roty[i] > 0)rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
394 if (roty[i] < 0)rotyvel[i] += multiplier * 8 * fabs(roty[i]);
395 if (roty[i] > 0)rotyvel[i] -= multiplier * 4;
396 if (roty[i] < 0)rotyvel[i] += multiplier * 4;
397 if (rotyvel[i] > 0)rotyvel[i] -= multiplier * 4;
398 if (rotyvel[i] < 0)rotyvel[i] += multiplier * 4;
399 if (fabs(roty[i]) < multiplier * 4)roty[i] = 0;
400 if (fabs(rotyvel[i]) < multiplier * 4)rotyvel[i] = 0;
402 roty[i] += rotyvel[i] * multiplier * 4;
405 glRotatef(roty[i] / 2, 1, 0, 0);
408 glRotatef(-rotx[i] / 2, 0, 0, 1);
410 if (rotx[i] > 10)rotx[i] = 10;
411 if (rotx[i] < -10)rotx[i] = -10;
412 if (roty[i] > 10)roty[i] = 10;
413 if (roty[i] < -10)roty[i] = -10;
415 if (environment == snowyenvironment) {
416 if (type[i] == treeleavestype) {
417 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
419 if (type[i] == treetrunktype) {
420 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
422 if (type[i] == bushtype) {
423 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
426 if (environment == grassyenvironment) {
427 if (type[i] == treeleavestype) {
428 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
430 if (type[i] == treetrunktype) {
431 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
433 if (type[i] == bushtype) {
434 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
437 glRotatef(yaw[i], 0, 1, 0);
438 glColor4f(1, 1, 1, distance);
439 if (type[i] == treeleavestype) {
440 glDisable(GL_CULL_FACE);
441 glDisable(GL_LIGHTING);
442 terrainlight = terrain.getLighting(position[i].x, position[i].z);
445 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
446 glAlphaFunc(GL_GREATER, 0);
447 glDisable(GL_ALPHA_TEST);
448 model[i].drawdifftex(treetextureptr);
450 if (type[i] == bushtype) {
451 glDisable(GL_CULL_FACE);
452 glDisable(GL_LIGHTING);
453 terrainlight = terrain.getLighting(position[i].x, position[i].z);
456 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
457 glAlphaFunc(GL_GREATER, 0);
458 glDisable(GL_ALPHA_TEST);
459 model[i].drawdifftex(bushtextureptr);
468 if (environment == desertenvironment)glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
469 glEnable(GL_ALPHA_TEST);
470 SetUpLight(&light, 0);
473 void Objects::DeleteObject(int which)
475 type[numobjects - 1] = 0;
476 yaw[numobjects - 1] = 0;
477 position[numobjects - 1] = 0;
478 scale[numobjects - 1] = 0;
479 friction[numobjects - 1] = 0;
484 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;
502 rotx[numobjects] = 0;
503 roty[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)
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 yaw[numobjects] = ayaw;
587 pitch[numobjects] = apitch;
589 rotxvel[numobjects] = 0;
590 rotyvel[numobjects] = 0;
591 rotx[numobjects] = 0;
592 roty[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(apitch) > 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(apitch, 0, 0);
639 if (type[numobjects] == rocktype) {
640 model[numobjects].Rotate(ayaw * 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, ayaw, 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]) {
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];
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()
700 static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
701 lightloc = light.location;
702 if (!skyboxtexture)lightloc = 0;
704 Normalise(&lightloc);
708 for (i = 0; i < numobjects; i++) {
709 if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype) {
710 for (j = 0; j < model[i].vertexNum; j++) {
711 terrainpoint = position[i] + DoRotation(model[i].vertex[j] + model[i].normals[j] * .1, 0, yaw[i], 0);
712 //terrainpoint.y+=model[i].boundingsphereradius;
714 patchx = terrainpoint.x / (terrain.size / subdivision * terrain.scale);
715 patchz = terrainpoint.z / (terrain.size / subdivision * terrain.scale);
716 if (patchx >= 0 && patchz >= 0 && patchx < subdivision && patchz < subdivision)
717 if (terrain.patchobjectnum[patchx][patchz])
718 for (k = 0; k < terrain.patchobjectnum[patchx][patchz]; k++) {
719 l = terrain.patchobjects[patchx][patchz][k];
720 if (type[l] != treetrunktype/*&&l!=i*/) {
721 testpoint = terrainpoint;
722 testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed[i]);
723 if (model[l].LineCheck(&testpoint, &testpoint2, &col, &position[l], &yaw[l]) != -1) {
724 shadowed[i] = 1 - (findDistance(&terrainpoint, &col) / 50);
728 if (shadowed[i] > 0) {
729 col = model[i].normals[j] - DoRotation(lightloc * shadowed[i], 0, -yaw[i], 0);
731 for (k = 0; k < model[i].TriangleNum; k++) {
732 if (model[i].Triangles[k].vertex[0] == j) {
734 model[i].vArray[l + 2] = col.x;
735 model[i].vArray[l + 3] = col.y;
736 model[i].vArray[l + 4] = col.z;
738 if (model[i].Triangles[k].vertex[1] == j) {
740 model[i].vArray[l + 10] = col.x;
741 model[i].vArray[l + 11] = col.y;
742 model[i].vArray[l + 12] = col.z;
744 if (model[i].Triangles[k].vertex[2] == j) {
746 model[i].vArray[l + 18] = col.x;
747 model[i].vArray[l + 19] = col.y;
748 model[i].vArray[l + 20] = col.z;
764 memset(position, 0, sizeof(position));
765 memset(type, 0, sizeof(type));
766 memset(yaw, 0, sizeof(yaw));
767 memset(pitch, 0, sizeof(pitch));
768 memset(rotx, 0, sizeof(rotx));
769 memset(rotxvel, 0, sizeof(rotxvel));
770 memset(roty, 0, sizeof(roty));
771 memset(rotyvel, 0, sizeof(rotyvel));
772 memset(possible, 0, sizeof(possible));
773 memset(model, 0, sizeof(model));
774 memset(displaymodel, 0, sizeof(displaymodel));
775 memset(friction, 0, sizeof(friction));
776 memset(scale, 0, sizeof(scale));
777 memset(messedwith, 0, sizeof(messedwith));
778 memset(checked, 0, sizeof(checked));
779 memset(shadowed, 0, sizeof(shadowed));
780 memset(occluded, 0, sizeof(occluded));
781 memset(onfire, 0, sizeof(onfire));
782 memset(flamedelay, 0, sizeof(flamedelay));
787 boxtextureptr.destroy();
788 treetextureptr.destroy();
789 bushtextureptr.destroy();
790 rocktextureptr.destroy();