JNR
laStaticModel.cpp
1 /*
2 
3 Jump'n'Run Engine
4 http://www.atanaslaskov.com/jnr/
5 
6 BSD LICENSE
7 Copyright (c) 2007-2013, Atanas Laskov
8 All rights reserved.
9 
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are met:
12 1. Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14 2. Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ATANAS LASKOV BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 */
29 
30 //
31 // FILE: laStaticModel.cpp
32 //
33 // Copyright (C) 2007-2013 Atanas Laskov, <latanas@gmail.com>
34 //
35 #include "stdafx.h"
36 #include "Core.h"
37 #include "Core.h"
38 
39 // Constructor
40 //
41 laStaticModel::laStaticModel(void)
42 {
43  _bAddDirectoryPrefix = M_TRUE;
44  _bLightweightInstance = M_FALSE;
45 
46  _arFlatVertex = _arFlatNormal = NULL;
47  _arFlatTex = NULL;
48  _nFlatVertex = 0;
49 
50  _pCR = NULL;
51 }
52 
53 // Destructor
54 //
55 laStaticModel::~laStaticModel(void) {
56  discard();
57 }
58 
59 void laStaticModel::discard() {
60 
61  if(!_bLightweightInstance)
62  {
63  if(_arFlatVertex) delete [] _arFlatVertex;
64  if(_arFlatNormal) delete [] _arFlatNormal;
65  if(_arFlatTex) delete [] _arFlatTex;
66  }
67 
68  _arFlatVertex = _arFlatNormal = NULL;
69  _arFlatTex = NULL;
70  _nFlatVertex = 0;
71 }
72 
73 
74 void laStaticModel::create(unsigned nFaceCnt)
75 {
76  discard();
77  _bLightweightInstance = M_FALSE;
78 
79  _nFlatVertex = nFaceCnt * 3;
80  _arFlatVertex = new laPoint3 [_nFlatVertex];
81  _arFlatNormal = new laPoint3 [_nFlatVertex];
82  _arFlatTex = new laPoint2 [_nFlatVertex];
83 
84  _pCR = ::laSystemIntegrator::getRenderer();
85 }
86 
87 // Load static model from file
88 //
89 bool laStaticModel::load(char* strFile)
90 {
91  ERRORLEVEL_BEGIN;
92  ASSERT(strnlen(strFile, 64) < 64, "Invalid file name");
93  MLOG("Loading static model '%s'...", strFile);
94  laFileParser f;
95  char strFilePath[128]=M_DIR_MODEL;
96  static char junk[1024], ver[128], cr[128];
97  static int nverts,ntverts,nfaces;
98  double sh;
99  M_BOOL bOpacityMap=M_FALSE;
100  _pCR = ::laSystemIntegrator::getRenderer();
101 
102  //Open the model file
103  //
104  if(!_bAddDirectoryPrefix) strFilePath[0]='\0';
105  strcat(strFilePath, strFile);
106  f.fileOpen(strFilePath);
107 
108  //General Information
109  //
110  try{ f.readSectionSeparator(junk); }
111  catch( laError& ){ throw laError("Section separator expected but not found (while parsing '%s')", strFile); }
112  ASSERT(!strcmp(_strupr(junk), "GENERAL INFORMATION"), "Section [GENERAL INFORMATION] expected, [%s] found ('%s')", junk, strFile);
113 
114  f.readText(ver);
115  ASSERT(!strcmp(ver, "JRM 1"), "Unappropriate model format '%s' ( while parsing '%s' )", ver, f.getFileName());
116 
117  f.readText(cr);
118  f.readInt(&nverts);
119  f.readInt(&ntverts, M_FALSE);
120  f.readInt(&nfaces, M_FALSE);
121  //MLOG("%d %d %d", nverts, ntverts, nfaces*3);
122  //ASSERT( nverts == ntverts == nfaces*3, "Corrupted file");
123  ASSERT( nverts && nverts && nverts, "Corrupted file '%s'", f.getFileName());
124 
125  // Allocate memory
126  //
127  //create(nverts, ntverts, nfaces);
128 
129  // Texture
130  //
131  try{ f.readSectionSeparator(junk); }
132  catch(laError& ){ throw laError("Section separator not found (while parsing '%s')", strFile); }
133 
134  _strupr(junk);
135  if(strcmp(junk, "TEXTURE")) throw laError("[TEXTURE] expected, [%s] found ('%s')", junk, strFile);
136 
137  f.readText(_strTex);
138  f.readLabel(junk);
139 
140  if( strstr(junk, "load-opacity-map") ) {
141  f.readText(junk, M_FALSE);
142  _nTex.load(_strTex, M_TEX_TMAP);
143  f.readLabel(junk);
144 
145  bOpacityMap = M_TRUE;
146  }
147  else _nTex.load(_strTex);
148 
149  f.readBool(&_bEmissive, M_FALSE);
150  f.readDouble(&sh);
151 
152  _nShininess = (unsigned) (sh*100);
153 
154  // Load geometry
155  //
156  char strCacheFile[256];
157  sprintf(strCacheFile, "%s.cache", strFilePath);
158  FILE* fCache_Read = fopen(strCacheFile, "rb");
159 
160  if(fCache_Read)
161  {
162  MLOG("loading %s from cache", strCacheFile);
163  create(nfaces);
164  _cache_load(fCache_Read);
165  fclose(fCache_Read);
166  }
167  else
168  {
169  MLOG("loading %s uncached", strCacheFile);
170  load(&f, nfaces, nverts, ntverts);
171  if(bOpacityMap) edSortZ();
172 
173  FILE* fCache_Write = fopen(strCacheFile, "wb");
174  ASSERT(fCache_Write, "Cannot open cache for writing (%s)", strCacheFile);
175  _cache_save(fCache_Write);
176  fclose(fCache_Write);
177  }
178 
179  return true;
180  ERRORLEVEL_END;
181 }
182 
183 // Load geometry, in case where there is no cache file
184 //
185 void laStaticModel::load(class laFileParser *fp, unsigned nf, unsigned nv, unsigned ntv)
186 {
187  char junk[1024];
188 
189  // Create temporary arrays
190  //
191  laPoint3 *arVertex = new laPoint3 [nv];
192  laPoint3 *arNormal = new laPoint3 [nf*3];
193  laPoint2 *arTVertex = new laPoint2 [ntv];
194 
195  laFace *arFace = new laFace [nf];
196  laFace *arTFace = new laFace [nf];
197 
198  _pCR = ::laSystemIntegrator::getRenderer();
199 
200  //Vertex List
201  //
202  try{ fp->readSectionSeparator(junk); }catch(laError& ){ throw laError("Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
203  _strupr(junk);
204  if(strcmp(junk, "VERTEX LIST")) throw laError("Section [VERTEX LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
205 
206  for(unsigned i=0; i<nv; i++) fp->readObj(arVertex+i, M_FALSE);
207 
208  //Texcoord List
209  //
210  try{ fp->readSectionSeparator(junk); }catch(laError& ){ throw laError("Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
211  _strupr(junk);
212  if(strcmp(junk, "TEXCOORD LIST")) throw laError("Section [TEXCOORD LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
213 
214  for(unsigned i=0; i<ntv; i++)
215  {
216  laPoint3 tv3;
217  fp->readObj( &tv3, M_FALSE ); // TODO: 3 coords in file, only 2 used; fix this
218  arTVertex[i].x( tv3.x() );
219  arTVertex[i].y( tv3.y() );
220  }
221 
222  //Normal List
223  //
224  try{ fp->readSectionSeparator(junk); }catch(laError& ){ throw laError("Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
225  _strupr(junk);
226  if(strcmp(junk, "NORMAL LIST")) throw laError("Section [NORMAL LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
227 
228 
229  for(unsigned i=0; i<nf*3; i++) fp->readObj(arNormal+i, M_FALSE);
230 
231  //Face List
232  //
233  try{ fp->readSectionSeparator(junk); }catch(laError& ){ throw laError("Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
234  _strupr(junk);
235  if(strcmp(junk, "FACE LIST")) throw laError("Section [FACE LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
236 
237 
238  for(unsigned i=0; i<nf; i++) fp->readObj(arFace+i, M_FALSE);
239 
240  //Texface List
241  //
242  try{ fp->readSectionSeparator(junk); }catch(laError& ){ throw laError("Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
243  _strupr(junk);
244  if(strcmp(junk, "TEXFACE LIST")) throw laError("Section [TEXFACE LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
245 
246  for(unsigned i=0; i<nf; i++) fp->readObj(arTFace+i, M_FALSE);
247 
248  // Expand faces
249  //
250  create(nf);
251 
252  for(unsigned i=0; i<nf; i++)
253  {
254  unsigned *index = arFace[i].pt;
255  unsigned *tindex = arTFace[i].pt;
256 
257  _arFlatVertex[i*3 + 0] = arVertex[index[0]];
258  _arFlatVertex[i*3 + 1] = arVertex[index[1]];
259  _arFlatVertex[i*3 + 2] = arVertex[index[2]];
260 
261  _arFlatNormal[i*3 + 0] = arNormal[i*3+0];
262  _arFlatNormal[i*3 + 1] = arNormal[i*3+1];
263  _arFlatNormal[i*3 + 2] = arNormal[i*3+2];
264 
265  _arFlatTex[i*3 + 0] = arTVertex[tindex[0]];
266  _arFlatTex[i*3 + 1] = arTVertex[tindex[1]];
267  _arFlatTex[i*3 + 2] = arTVertex[tindex[2]];
268  }
269 
270  delete [] arVertex;
271  delete [] arNormal;
272  delete [] arTVertex;
273 
274  delete [] arFace;
275  delete [] arTFace;
276 
277  MLOG("Model has %d vertices", _nFlatVertex);
278 
279  //Scale to the game scale factor
280  edScale(laPoint3(M_UNIT, M_UNIT, M_UNIT));
281 }
282 
283 // Load/save cache
284 //
285 void laStaticModel::_cache_save(FILE* f) {
286  fwrite(_arFlatVertex, sizeof(laPoint3), _nFlatVertex, f);
287  fwrite(_arFlatNormal, sizeof(laPoint3), _nFlatVertex, f);
288  fwrite(_arFlatTex, sizeof(laPoint2), _nFlatVertex, f);
289 }
290 
291 void laStaticModel::_cache_load(FILE* f) {
292  fread(_arFlatVertex, sizeof(laPoint3), _nFlatVertex, f);
293  fread(_arFlatNormal, sizeof(laPoint3), _nFlatVertex, f);
294  fread(_arFlatTex, sizeof(laPoint2), _nFlatVertex, f);
295 }
296 
297 
298 // Draw static model
299 //
300 void laStaticModel::draw( laRenderer *pr )
301 {
302  PROFILE_REN(laStaticModel_draw);
303  static M_BOOL bFog;
304 
305  pr->styleShininess(_nShininess);
306 
307  /*if(_bEmissive) {
308  bFog = pr->getFogMode();
309  pr->modeFog(M_FALSE);
310  }*/
311 
312  _nTex.use();
313  _draw_traingles(pr);
314 
315  //if(_bEmissive) pr->modeFog(bFog);
316 }
317 
318 void laStaticModel::_draw_traingles(laRenderer *pr)
319 {
320  if(_bBend || _bRotate || _bOffset)
321  {
322  laPoint3 *arv = new laPoint3 [_nFlatVertex];
323  laPoint3 *arn = new laPoint3 [_nFlatVertex];
324  memcpy(arv, _arFlatVertex, sizeof(laPoint3)*_nFlatVertex);
325  memcpy(arn, _arFlatNormal, sizeof(laPoint3)*_nFlatVertex);
326 
327  if(_bBend) _bend(arv, arn);
328  if(_bRotate) _rotate(arv, arn);
329  if(_bOffset) _offset(arv, arn);
330 
331  pr->trianglesDraw(arv, _arFlatTex, arn, _nFlatVertex);
332 
333  delete [] arv;
334  delete [] arn;
335  }
336  else pr->trianglesDraw(_arFlatVertex, _arFlatTex, _arFlatNormal, _nFlatVertex);
337 }
338 
339 void laStaticModel::_bend(laPoint3 *arv, laPoint3 *arn)
340 {
341  double w, tx, tz;
342  double sinb = sin(_dBendAng), cosb = cos(_dBendAng);
343 
344  for(unsigned i=0; i<_nFlatVertex; i++)
345  {
346  w = M_CLAMP(0,1, (M_UNIT-arv[i].x())/M_UNIT);
347 
348  // Vertex
349  //
350  arv[i][0] = arv[i].x()*_dBendScale;
351  arv[i][2] -= M_UNIT/2.0;
352 
353  tx = arv[i].x() * cosb - arv[i].z() * sinb;
354  tz = arv[i].x() * sinb + arv[i].z() * cosb;
355 
356  arv[i][0] = tx*w + arv[i].x()*(1-w);
357  arv[i][2] = tz*w + arv[i].z()*(1-w) + M_UNIT/2.0;
358 
359  // Normal
360  //
361  arn[i][0] = arn[i].x()*_dBendScale;
362  arn[i][2] -= M_UNIT/2.0;
363 
364  tx = arn[i].x() * cosb - arn[i].z() * sinb;
365  tz = arn[i].x() * sinb + arn[i].z() * cosb;
366 
367  arn[i][0] = tx*w + arn[i].x()*(1-w);
368  arn[i][2] = tz*w + arn[i].z()*(1-w) + M_UNIT/2.0;
369  }
370 }
371 
372 void laStaticModel::_rotate(laPoint3 *arv, laPoint3 *arn)
373 {
374  double tx, tz;
375  double sinb = sin(_dRotAng), cosb = cos(_dRotAng);
376 
377  for(unsigned i=0; i<_nFlatVertex; i++)
378  {
379  // Vertex
380  //
381  arv[i][2] -= M_UNIT/2.0;
382  tx = arv[i].x() * cosb - arv[i].z() * sinb;
383  tz = arv[i].x() * sinb + arv[i].z() * cosb;
384 
385  arv[i][0] = tx;
386  arv[i][2] = tz + M_UNIT/2.0;
387 
388  // Normal
389  //
390  arn[i][2] -= M_UNIT/2.0;
391  tx = arn[i].x() * cosb - arn[i].z() * sinb;
392  tz = arn[i].x() * sinb + arn[i].z() * cosb;
393 
394  arn[i][0] = tx;
395  arn[i][2] = tz + M_UNIT/2.0;
396  }
397 }
398 
399 void laStaticModel::_offset(laPoint3 *arv, laPoint3 *arn) {
400  for(unsigned i=0; i<_nFlatVertex; i++) arv[i] += _ptOffset;
401 }
402 
403 void laStaticModel::buildCollisionData(laCollisionDomain* pDomain, rpgTrap* pTrap)
404 {
405  for(unsigned i=0; i<_nFlatVertex; i+=3)
406  pDomain->addTriangle(_arFlatVertex[i+0], _arFlatVertex[i+1], _arFlatVertex[i+2], pTrap);
407 
408  /*for(unsigned i=0; i<_nFaceCnt; i++)
409  {
410  unsigned *index;
411  index = _arFace[i].pt;
412 
413  pDomain->addTriangle(_arFlatVertex[index[0]], _arFlatVertex[index[1]], _arFlatVertex[index[2]], pTrap);
414  }*/
415 }
416 
417 laPoint3 laStaticModel::boundaryMin()
418 {
419  laPoint3 min = _arFlatVertex[0];
420 
421  for(unsigned i=1; i<_nFlatVertex; i++) {
422  if(_arFlatVertex[i].x() < min.x()) min[0] = _arFlatVertex[i].x();
423  if(_arFlatVertex[i].y() < min.y()) min[1] = _arFlatVertex[i].y();
424  }
425 
426  return min;
427 }
428 
429 laPoint3 laStaticModel::boundaryMax()
430 {
431  laPoint3 max = _arFlatVertex[0];
432 
433  for(unsigned i=1; i<_nFlatVertex; i++) {
434  if(_arFlatVertex[i].x() > max.x()) max[0] = _arFlatVertex[i].x();
435  if(_arFlatVertex[i].y() > max.y()) max[1] = _arFlatVertex[i].y();
436  }
437 
438  return max;
439 }
440 
441 void laStaticModel::edScale(laPoint3 sz)
442 {
443  M_BOOL bFlip = M_FALSE;
444  unsigned long i;
445 
446  if( (M_SIGN(sz.x())+M_SIGN(sz.y())+M_SIGN(sz.z()))==1) bFlip = M_TRUE;
447 
448  for(i=0; i<_nFlatVertex; i++)
449  {
450  _arFlatVertex[i] *= sz;
451 
452  /*if(sz.x()<0) _arFlatNormal[i] *= -1;
453  if(sz.y()<0) _arFlatNormal[i] *= -1;
454  if(sz.z()<0) _arFlatNormal[i] *= -1;*/
455  }
456 
457  /*for(i=0; i<_nFaceCnt; i++)
458  {
459  if(bFlip)
460  {
461  unsigned *face = _arFace[i].pt;
462  unsigned *tface = _arTFace[i].pt;
463  unsigned temp;
464  laPoint3 ntemp;
465 
466  //Reverse the triangle order in the face
467  temp = face[0];
468  face[0] = face[2];
469  face[2] = temp;
470 
471  //Reverse triangle order in the texture face
472  temp = tface[0];
473  tface[0] = tface[2];
474  tface[2] = temp;
475 
476  //Reverse the normas
477  ntemp = _arNormal[i*3+0];
478  _arNormal[i*3+0] = _arNormal[i*3+2];
479  _arNormal[i*3+2] = ntemp;
480  }
481 
482  if(sz.x()<0)
483  {
484  _arNormal[i*3+0][0] *= -1;
485  _arNormal[i*3+1][0] *= -1;
486  _arNormal[i*3+2][0] *= -1;
487  }
488 
489  if(sz.y()<0)
490  {
491  _arNormal[i*3+0][1] *= -1;
492  _arNormal[i*3+1][1] *= -1;
493  _arNormal[i*3+2][1] *= -1;
494  }
495 
496  if(sz.z()<0)
497  {
498  _arNormal[i*3+0][2] *= -1;
499  _arNormal[i*3+1][2] *= -1;
500  _arNormal[i*3+2][2] *= -1;
501  }
502  }*/
503 }
504 
505 void laStaticModel::edNormalize()
506 {
507  double max=0;
508 
509  for(unsigned i=0; i<_nFlatVertex; i++){
510  if(_arFlatVertex[i].x()>max) max = _arFlatVertex[i].x();
511  if(_arFlatVertex[i].y()>max) max = _arFlatVertex[i].y();
512  if(_arFlatVertex[i].z()>max) max = _arFlatVertex[i].z();
513  }
514 
515  edScale( laPoint3(1/max, 1/max, 1/max) );
516 }
517 
518 void laStaticModel::edTranslate(laPoint3 pos) {
519  for(unsigned i=0; i<_nFlatVertex; i++) _arFlatVertex[i] += pos;
520 }
521 
522 void laStaticModel::edMinaxis()
523 {
524  laPoint3 min = _arFlatVertex[0];
525 
526  for(unsigned i=1; i<_nFlatVertex; i++) {
527  if(_arFlatVertex[i].x()<min.x()) min[0] = _arFlatVertex[i].x();
528  if(_arFlatVertex[i].y()<min.y()) min[1] = _arFlatVertex[i].y();
529  if(_arFlatVertex[i].z()<min.z()) min[2] = _arFlatVertex[i].z();
530  }
531  edTranslate( min * (-1) );
532 }
533 
534 void laStaticModel::edMaxaxis()
535 {
536  laPoint3 max = _arFlatVertex[0];
537 
538  for(unsigned i=1; i<_nFlatVertex; i++) {
539  if(_arFlatVertex[i].x()>max.x()) max[0] = _arFlatVertex[i].x();
540  if(_arFlatVertex[i].y()>max.y()) max[1] = _arFlatVertex[i].y();
541  if(_arFlatVertex[i].z()>max.z()) max[2] = _arFlatVertex[i].z();
542  }
543  edTranslate( max * (-1) );
544 }
545 
546 void laStaticModel::edCentralize()
547 {
548  laPoint3 avg = _arFlatVertex[0];
549 
550  for(unsigned i=1; i<_nFlatVertex; i++) avg += _arFlatVertex[i];
551 
552  avg[0] /= _nFlatVertex;
553  avg[1] /= _nFlatVertex;
554  avg[2] /= _nFlatVertex;
555 
556  edTranslate( avg * (-1) );
557 }
558 
559 void laStaticModel::edSnap()
560 {
561  for(unsigned i=0; i<_nFlatVertex; i++)
562  {
563  //Snap
564 
565  if( M_ABS( ceil(_arFlatVertex[i].x()/M_SNAP_RANGE)-(_arFlatVertex[i].x()/M_SNAP_RANGE))>0.5 )
566  _arFlatVertex[i][0] = floor(_arFlatVertex[i].x()/M_SNAP_RANGE)*M_SNAP_RANGE;
567  else
568  _arFlatVertex[i][0] = ceil(_arFlatVertex[i].x()/M_SNAP_RANGE)*M_SNAP_RANGE;
569 
570  if( M_ABS( ceil(_arFlatVertex[i].y()/M_SNAP_RANGE)-(_arFlatVertex[i].y()/M_SNAP_RANGE))>0.5 )
571  _arFlatVertex[i][1] = floor(_arFlatVertex[i].y()/M_SNAP_RANGE)*M_SNAP_RANGE;
572  else
573  _arFlatVertex[i][1] = ceil(_arFlatVertex[i].y()/M_SNAP_RANGE)*M_SNAP_RANGE;
574 
575  if( M_ABS( ceil(_arFlatVertex[i].z()/M_SNAP_RANGE)-(_arFlatVertex[i].z()/M_SNAP_RANGE))>0.5 )
576  _arFlatVertex[i][2] = floor(_arFlatVertex[i].z()/M_SNAP_RANGE)*M_SNAP_RANGE;
577  else
578  _arFlatVertex[i][2] = ceil(_arFlatVertex[i].z()/M_SNAP_RANGE)*M_SNAP_RANGE;
579  }
580 }
581 
582 void laStaticModel::edSortZ()
583 {
584  /*
585  unsigned i, j;
586  double *z = new double[_nFaceCnt];
587  double z_min, tmp_z;
588  laFace tmp;
589  laPoint3 ntmp[3];
590 
591  for(i=0; i<_nFaceCnt; i++)
592  {
593  double z1 = _arFlatVertex[_arFace[i].pt[0]].z();
594  double z2 = _arFlatVertex[_arFace[i].pt[1]].z();
595  double z3 = _arFlatVertex[_arFace[i].pt[2]].z();
596  z[i] = (z1 + z2 + z3 ) / 3;
597  }
598 
599  for(i=0; i<_nFaceCnt; i++)
600  {
601  z_min = z[i];
602 
603  for(j=i+1; j<_nFaceCnt; j++)
604  {
605  if( z[j] < z_min )
606  {
607  //Update min z
608  //
609  z_min = z[j];
610 
611  //Swap stuff
612  //
613  tmp = _arFace[i];
614  _arFace[i] = _arFace[j];
615  _arFace[j] = tmp;
616 
617  tmp = _arTFace[i];
618  _arTFace[i] = _arTFace[j];
619  _arTFace[j] = tmp;
620 
621  memcpy(ntmp, _arNormal+i*3, sizeof(laPoint3)*3);
622  memcpy(_arNormal+i*3, _arNormal+j*3, sizeof(laPoint3)*3);
623  memcpy(_arNormal+j*3, ntmp, sizeof(laPoint3)*3);
624 
625  tmp_z = z[i];
626  z[i] = z[j];
627  z[j] = tmp_z;
628  }
629  }
630  }
631  delete [] z;*/
632 }
3D Geometry Face
Definition: laFace.h:41
#define M_UNIT
Unit of 1 meter.
2D Point
Definition: laPoint_novec.h:41
#define M_DIR_MODEL
3D models directory
Trap Properties.
Definition: rpgTrap.h:42
#define M_ABS(a)
Return abs(a)
Collision Domain.
Virtual interface for the Engine graphics renderer.
Definition: laRenderer.h:98
#define M_SIGN(a)
Return sign (+1 or -1)
#define M_TEX_TMAP
Transparent texture with an alpha channel.
Error handling class.
Definition: laError.h:46
File Parser.
Definition: laFileParser.h:41