41 laStaticModel::laStaticModel(
void)
43 _bAddDirectoryPrefix = M_TRUE;
44 _bLightweightInstance = M_FALSE;
46 _arFlatVertex = _arFlatNormal = NULL;
55 laStaticModel::~laStaticModel(
void) {
59 void laStaticModel::discard() {
61 if(!_bLightweightInstance)
63 if(_arFlatVertex)
delete [] _arFlatVertex;
64 if(_arFlatNormal)
delete [] _arFlatNormal;
65 if(_arFlatTex)
delete [] _arFlatTex;
68 _arFlatVertex = _arFlatNormal = NULL;
74 void laStaticModel::create(
unsigned nFaceCnt)
77 _bLightweightInstance = M_FALSE;
79 _nFlatVertex = nFaceCnt * 3;
80 _arFlatVertex =
new laPoint3 [_nFlatVertex];
81 _arFlatNormal =
new laPoint3 [_nFlatVertex];
82 _arFlatTex =
new laPoint2 [_nFlatVertex];
84 _pCR = ::laSystemIntegrator::getRenderer();
89 bool laStaticModel::load(
char* strFile)
92 ASSERT(strnlen(strFile, 64) < 64,
"Invalid file name");
93 MLOG(
"Loading static model '%s'...", strFile);
96 static char junk[1024], ver[128], cr[128];
97 static int nverts,ntverts,nfaces;
99 M_BOOL bOpacityMap=M_FALSE;
100 _pCR = ::laSystemIntegrator::getRenderer();
104 if(!_bAddDirectoryPrefix) strFilePath[0]=
'\0';
105 strcat(strFilePath, strFile);
106 f.fileOpen(strFilePath);
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);
115 ASSERT(!strcmp(ver,
"JRM 1"),
"Unappropriate model format '%s' ( while parsing '%s' )", ver, f.getFileName());
119 f.readInt(&ntverts, M_FALSE);
120 f.readInt(&nfaces, M_FALSE);
123 ASSERT( nverts && nverts && nverts,
"Corrupted file '%s'", f.getFileName());
131 try{ f.readSectionSeparator(junk); }
132 catch(
laError& ){
throw laError(
"Section separator not found (while parsing '%s')", strFile); }
135 if(strcmp(junk,
"TEXTURE"))
throw laError(
"[TEXTURE] expected, [%s] found ('%s')", junk, strFile);
140 if( strstr(junk,
"load-opacity-map") ) {
141 f.readText(junk, M_FALSE);
145 bOpacityMap = M_TRUE;
147 else _nTex.load(_strTex);
149 f.readBool(&_bEmissive, M_FALSE);
152 _nShininess = (unsigned) (sh*100);
156 char strCacheFile[256];
157 sprintf(strCacheFile,
"%s.cache", strFilePath);
158 FILE* fCache_Read = fopen(strCacheFile,
"rb");
162 MLOG(
"loading %s from cache", strCacheFile);
164 _cache_load(fCache_Read);
169 MLOG(
"loading %s uncached", strCacheFile);
170 load(&f, nfaces, nverts, ntverts);
171 if(bOpacityMap) edSortZ();
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);
185 void laStaticModel::load(
class laFileParser *fp,
unsigned nf,
unsigned nv,
unsigned ntv)
191 laPoint3 *arVertex =
new laPoint3 [nv];
192 laPoint3 *arNormal =
new laPoint3 [nf*3];
198 _pCR = ::laSystemIntegrator::getRenderer();
202 try{ fp->readSectionSeparator(junk); }
catch(
laError& ){
throw laError(
"Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
204 if(strcmp(junk,
"VERTEX LIST"))
throw laError(
"Section [VERTEX LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
206 for(
unsigned i=0; i<nv; i++) fp->readObj(arVertex+i, M_FALSE);
210 try{ fp->readSectionSeparator(junk); }
catch(
laError& ){
throw laError(
"Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
212 if(strcmp(junk,
"TEXCOORD LIST"))
throw laError(
"Section [TEXCOORD LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
214 for(
unsigned i=0; i<ntv; i++)
217 fp->readObj( &tv3, M_FALSE );
218 arTVertex[i].x( tv3.x() );
219 arTVertex[i].y( tv3.y() );
224 try{ fp->readSectionSeparator(junk); }
catch(
laError& ){
throw laError(
"Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
226 if(strcmp(junk,
"NORMAL LIST"))
throw laError(
"Section [NORMAL LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
229 for(
unsigned i=0; i<nf*3; i++) fp->readObj(arNormal+i, M_FALSE);
233 try{ fp->readSectionSeparator(junk); }
catch(
laError& ){
throw laError(
"Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
235 if(strcmp(junk,
"FACE LIST"))
throw laError(
"Section [FACE LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
238 for(
unsigned i=0; i<nf; i++) fp->readObj(arFace+i, M_FALSE);
242 try{ fp->readSectionSeparator(junk); }
catch(
laError& ){
throw laError(
"Section separator expected but not found (while parsing '%s')", fp->getFileName()); }
244 if(strcmp(junk,
"TEXFACE LIST"))
throw laError(
"Section [TEXFACE LIST] expected, [%s] found ('%s')", junk, fp->getFileName());
246 for(
unsigned i=0; i<nf; i++) fp->readObj(arTFace+i, M_FALSE);
252 for(
unsigned i=0; i<nf; i++)
254 unsigned *index = arFace[i].pt;
255 unsigned *tindex = arTFace[i].pt;
257 _arFlatVertex[i*3 + 0] = arVertex[index[0]];
258 _arFlatVertex[i*3 + 1] = arVertex[index[1]];
259 _arFlatVertex[i*3 + 2] = arVertex[index[2]];
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];
265 _arFlatTex[i*3 + 0] = arTVertex[tindex[0]];
266 _arFlatTex[i*3 + 1] = arTVertex[tindex[1]];
267 _arFlatTex[i*3 + 2] = arTVertex[tindex[2]];
277 MLOG(
"Model has %d vertices", _nFlatVertex);
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);
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);
302 PROFILE_REN(laStaticModel_draw);
305 pr->styleShininess(_nShininess);
318 void laStaticModel::_draw_traingles(
laRenderer *pr)
320 if(_bBend || _bRotate || _bOffset)
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);
327 if(_bBend) _bend(arv, arn);
328 if(_bRotate) _rotate(arv, arn);
329 if(_bOffset) _offset(arv, arn);
331 pr->trianglesDraw(arv, _arFlatTex, arn, _nFlatVertex);
336 else pr->trianglesDraw(_arFlatVertex, _arFlatTex, _arFlatNormal, _nFlatVertex);
339 void laStaticModel::_bend(laPoint3 *arv, laPoint3 *arn)
342 double sinb = sin(_dBendAng), cosb = cos(_dBendAng);
344 for(
unsigned i=0; i<_nFlatVertex; i++)
350 arv[i][0] = arv[i].x()*_dBendScale;
353 tx = arv[i].x() * cosb - arv[i].z() * sinb;
354 tz = arv[i].x() * sinb + arv[i].z() * cosb;
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;
361 arn[i][0] = arn[i].x()*_dBendScale;
364 tx = arn[i].x() * cosb - arn[i].z() * sinb;
365 tz = arn[i].x() * sinb + arn[i].z() * cosb;
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;
372 void laStaticModel::_rotate(laPoint3 *arv, laPoint3 *arn)
375 double sinb = sin(_dRotAng), cosb = cos(_dRotAng);
377 for(
unsigned i=0; i<_nFlatVertex; i++)
382 tx = arv[i].x() * cosb - arv[i].z() * sinb;
383 tz = arv[i].x() * sinb + arv[i].z() * cosb;
386 arv[i][2] = tz +
M_UNIT/2.0;
391 tx = arn[i].x() * cosb - arn[i].z() * sinb;
392 tz = arn[i].x() * sinb + arn[i].z() * cosb;
395 arn[i][2] = tz +
M_UNIT/2.0;
399 void laStaticModel::_offset(laPoint3 *arv, laPoint3 *arn) {
400 for(
unsigned i=0; i<_nFlatVertex; i++) arv[i] += _ptOffset;
405 for(
unsigned i=0; i<_nFlatVertex; i+=3)
406 pDomain->addTriangle(_arFlatVertex[i+0], _arFlatVertex[i+1], _arFlatVertex[i+2], pTrap);
417 laPoint3 laStaticModel::boundaryMin()
419 laPoint3 min = _arFlatVertex[0];
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();
429 laPoint3 laStaticModel::boundaryMax()
431 laPoint3 max = _arFlatVertex[0];
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();
441 void laStaticModel::edScale(laPoint3 sz)
443 M_BOOL bFlip = M_FALSE;
448 for(i=0; i<_nFlatVertex; i++)
450 _arFlatVertex[i] *= sz;
505 void laStaticModel::edNormalize()
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();
515 edScale( laPoint3(1/max, 1/max, 1/max) );
518 void laStaticModel::edTranslate(laPoint3 pos) {
519 for(
unsigned i=0; i<_nFlatVertex; i++) _arFlatVertex[i] += pos;
522 void laStaticModel::edMinaxis()
524 laPoint3 min = _arFlatVertex[0];
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();
531 edTranslate( min * (-1) );
534 void laStaticModel::edMaxaxis()
536 laPoint3 max = _arFlatVertex[0];
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();
543 edTranslate( max * (-1) );
546 void laStaticModel::edCentralize()
548 laPoint3 avg = _arFlatVertex[0];
550 for(
unsigned i=1; i<_nFlatVertex; i++) avg += _arFlatVertex[i];
552 avg[0] /= _nFlatVertex;
553 avg[1] /= _nFlatVertex;
554 avg[2] /= _nFlatVertex;
556 edTranslate( avg * (-1) );
559 void laStaticModel::edSnap()
561 for(
unsigned i=0; i<_nFlatVertex; i++)
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;
568 _arFlatVertex[i][0] = ceil(_arFlatVertex[i].x()/M_SNAP_RANGE)*M_SNAP_RANGE;
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;
573 _arFlatVertex[i][1] = ceil(_arFlatVertex[i].y()/M_SNAP_RANGE)*M_SNAP_RANGE;
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;
578 _arFlatVertex[i][2] = ceil(_arFlatVertex[i].z()/M_SNAP_RANGE)*M_SNAP_RANGE;
582 void laStaticModel::edSortZ()
#define M_UNIT
Unit of 1 meter.
#define M_DIR_MODEL
3D models directory
#define M_ABS(a)
Return abs(a)
Virtual interface for the Engine graphics renderer.
#define M_SIGN(a)
Return sign (+1 or -1)
#define M_TEX_TMAP
Transparent texture with an alpha channel.