38 #include "Core-Level-JR.h"
42 laSegment::laSegment(
unsigned nIndex)
46 _nSegmentIndex = nIndex;
49 _pPrev = _pNext = NULL;
51 _nBackgroundElement = 0;
55 _bObjectListReset = M_FALSE;
61 for(
int y=0; y<M_SEGH; y++)
for(
int x=0; x<M_SEGW; x++)
65 if(y>=(M_SEGH-1)) pNext = NULL;
66 else pNext = _arTiles[0][y+1].getDomain();
68 else pNext = _arTiles[x+1][y].getDomain();
70 _arTiles[x][y].getDomain()->setNextDomain(pNext);
71 _arTiles[x][y]._pSegment =
this;
72 _arTiles[x][y]._nSegX = x;
73 _arTiles[x][y]._nSegY = y;
76 srand(::GetTickCount());
80 laSegment::~laSegment(
void){
86 void laSegment::_update_curviture_parameters()
88 laPropertyList *pl = getTS()->getElement(
"terrain-curviture");
90 _arTerrainCurvitureParams[0] = pl->getDouble(
"big") + pl->getDouble(
"big-variation")*(rand()%100)/100.0;
91 _arTerrainCurvitureParams[1] = pl->getDouble(
"strange") + pl->getDouble(
"strange-variation")*(rand()%100)/100.0;
92 _arTerrainCurvitureParams[2] = pl->getDouble(
"small") + pl->getDouble(
"small-variation")*(rand()%100)/100.0;
93 _arTerrainCurvitureParams[3] = 0;
105 fp->readUnsigned(&_nLitterBoxCount);
107 if(_nLitterBoxCount>=M_MAXLITTER_BOX)
108 throw laError(
"laSegment::load() failed: Too many litter boxes (%d requested, %d allowed)",
109 _nLitterBoxCount, M_MAXLITTER_BOX);
111 for(
unsigned i=0; i<_nLitterBoxCount; i++)
113 fp->readObj(_arLitterBox+i, M_FALSE);
114 _arLitterBox[i].litter(_pTileset);
119 for(
int y=0; y<M_SEGH; y++)
121 for(
int x=0; x<M_SEGW; x++)
124 _arTiles[x][y].setTS(_pTileset);
125 fp->readObj( &(_arTiles[x][y]), M_FALSE );
134 PROFILE_REN(laSegment_drawTerrain);
135 ASSERT(_pTileset,
"Invalid tileset object");
136 ASSERT(_pLevel,
"Invalid level object");
142 r->transTranslate( laPoint3(0,
M_UNIT*M_SEGH) );
143 _pTileset->getElement(_nBackgroundElement)->drawGeometry(r);
145 for(
unsigned i=0; i<_nLitterBoxCount; i++)
146 _arLitterBox[i].drawGeometry(r, laPoint3());
156 r->compiledDraw( _nCompilationID );
163 _nCompilationID = r->compiledActivate(M_TRUE);
165 r->compiledActivate(M_FALSE);
171 PROFILE_REN(laSegment__draw_static);
173 double dCurrentOffset, dCurrentAngle, dPreviousAngle, dScale;
175 for(
int x=0; x<M_SEGW; x++)
180 dCurrentOffset = terrainZOffset(x);
181 dCurrentAngle = terrainAngle(x);
182 dPreviousAngle = terrainAngle(x-1);
183 dScale = terrainScale(x);
185 for(
unsigned y=0; y<M_SEGH; y++)
187 if( _arTiles[x][y].isEmpty() )
continue;
190 laModel::edRotate(M_TRUE, -dCurrentAngle);
191 laModel::edBend(M_TRUE, -dPreviousAngle + dCurrentAngle, dScale);
192 laModel::edOffset(M_TRUE, laPoint3(
M_UNIT*x,
M_UNIT*y, dCurrentOffset) );
194 _arTiles[x][y].drawGeometry(r);
196 laModel::edRotate(M_FALSE);
197 laModel::edBend(M_FALSE);
198 laModel::edOffset(M_FALSE);
207 PROFILE_REN(laSegment__draw_dynamic);
211 double dCurrentOffset, dCurrentAngle;
213 for(
int x=0; x<M_SEGW; x++)
215 dCurrentOffset = terrainZOffset(x);
216 dCurrentAngle =
M_R2D(terrainAngle(x));
218 for(
unsigned y=0; y<M_SEGH; y++)
220 if( _arTiles[x][y].isEmpty() || _arTiles[x][y].isStatic() )
continue;
224 r->transRotate( dCurrentAngle, laPoint3(0,1,0)) ;
225 r->transTranslate( laPoint3(0, 0, -
M_UNIT/2.0) );
228 _arTiles[x][y].drawDynamicGeometry( r );
236 PROFILE_REN(laSegment__draw_objects);
237 std::list<class laObject*>::iterator i;
239 for(i=_listObjects.begin(); i!= _listObjects.end(); i++) (*i)->drawGeometry(r, laPoint3());
244 void laSegment::drawFx(
laRenderer *r,
const laPoint3 &pos)
246 PROFILE_REN(laSegment_drawFx);
247 ASSERT(_pTileset,
"Invalid tileset object");
248 ASSERT(_pLevel,
"Invalid level object");
252 double dCurrentOffset, dCurrentAngle;
254 for(
unsigned x=0; x<M_SEGW; x++)
256 dCurrentOffset = terrainZOffset(x);
257 dCurrentAngle =
M_R2D(terrainAngle(x));
259 for(
unsigned i=0; i<M_SEGH; i++)
261 if( _arTiles[x][i].isEmpty() || _arTiles[x][i].isWithoutFx() )
continue;
267 r->transTranslate( pos + laPoint3(
M_UNIT*x,
M_UNIT*i, dCurrentOffset) );
268 _arTiles[x][i].drawFx(r);
275 std::list<class laObject*>::iterator i;
277 for(i=_listObjects.begin(); i!= _listObjects.end(); i++) (*i)->drawFx(r, laPoint3());
281 for(
unsigned i=0; i<_nLitterBoxCount; i++) _arLitterBox[i].drawFx(r, laPoint3(0,
M_UNIT*M_SEGH));
286 void laSegment::animate(laTimer &t)
289 PROFILE_ANIM(laSegment_animate);
290 ASSERT(_pTileset,
"Invalid tileset object");
291 ASSERT(_pLevel,
"Invalid level object");
292 std::list<class laObject*>::iterator i = _listObjects.begin();
297 while( i != _listObjects.end() )
305 if(_bObjectListReset) {
306 _bObjectListReset = M_FALSE;
310 if( _pNext && ((*i)->getPosition().x() >= (_nSegmentIndex + 1) *
M_UNIT * M_SEGW) )
312 _pNext->_migrate_object( *i );
313 i = _listObjects.erase( i );
315 else if( _pPrev && ((*i)->getPosition().x() < _nSegmentIndex *
M_UNIT * M_SEGW) )
317 _pPrev->_migrate_object( *i );
318 i = _listObjects.erase( i );
322 ERRORLEVEL_ARG(ERRORLEVEL_ARGVAL + 1);
326 for(
unsigned i=0; i<M_SEGH; i++)
for(
unsigned j=0; j<M_SEGW; j++)
327 _arTiles[j][i].animate(t);
337 void laSegment::_init_object_list (
class laObject** par,
unsigned n )
339 _bObjectListReset = M_TRUE;
340 _listObjects.clear();
342 for(
unsigned i=0; i<n; i++)
344 if( par[i]->getPosition().x() >= (_nSegmentIndex + 1) *
M_UNIT * M_SEGW )
continue;
345 if( par[i]->getPosition().x() < _nSegmentIndex *
M_UNIT * M_SEGW )
continue;
347 _migrate_object( par[i] );
355 void laSegment::_update_wave()
357 PROFILE_ANIM(laSegment__update_wave);
359 double dWaveOffset = (_pTileset) ? _pTileset->getAnimatedWaveOffset() : 0;
362 for(
unsigned x=0; x<=M_SEGW; x++)
364 dx = (_nSegmentIndex*(M_SEGW) + x)*
M_UNIT*WAVE_FREQUENCY + dWaveOffset;
365 _arWave[x] = sin( dx );
371 void laSegment::bulidDomains(laPoint3 pos)
373 laPoint3 ptTilePosition;
375 _nCollisionDomainSize = 0;
376 _nCollisionDomains = 0;
378 for(
unsigned i=0; i<M_SEGH; i++)
for(
unsigned j=0; j<M_SEGW; j++)
380 ptTilePosition = pos + laPoint3(j, i)*
M_UNIT;
382 unsigned n = _arTiles[j][i].bulidDomain( ptTilePosition );
384 _nCollisionDomainSize += n;
385 if(n) _nCollisionDomains++;
388 MLOG(
"This segment contains %d collision lines in %d domains", _nCollisionDomainSize, _nCollisionDomains);
392 double laSegment::terrainZOffset(
int nX) {
393 return _pLevel->terrainZOffset(nX + _nSegmentIndex*M_SEGW);
396 double laSegment::terrainAngle(
int nX) {
397 return _pLevel->terrainAngle(nX + _nSegmentIndex*M_SEGW);
400 double laSegment::terrainScale(
int nX) {
401 return _pLevel->terrainScale(nX + _nSegmentIndex*M_SEGW);
#define M_R2D(r)
Convert radians to degrees.
#define M_UNIT
Unit of 1 meter.
Virtual interface for the Engine graphics renderer.
Base Class for Level Objects.