JNR
laTile.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: laTile.cpp
32 //
33 // Copyright (C) 2007-2013 Atanas Laskov, <latanas@gmail.com>
34 //
35 #include "stdafx.h"
36 #include "Core-Level-JR.h"
37 
38 // Constructor
39 //
40 laTile::laTile(void)
41 {
42  _pSegment = NULL;
43  _nSegX = _nSegY = 0;
44 
45  _pTileset = NULL;
46 
47  _nTileIndex = 0;
48  _pTile = NULL;
49  _nVaration = 0;
50 
51  _pTrap = NULL;
52 }
53 
54 laTile::~laTile(void){
55 
56  if(_pTrap)
57  {
58  delete _pTrap;
59  delete _pfxTrap;
60  }
61 }
62 
63 // Read the tile form file
64 //
65 void laTile::load(class laFileParser *fp)
66 {
67  fp->readUnsigned(&_nTileIndex, M_FALSE);
68 
69  ASSERT(_pTileset, "Nil tileset");
70  ASSERT( _pTileset->getElementCnt() >_nTileIndex,
71  "Tile index %u exceeds tileset size %u", _nTileIndex, _pTileset->getElementCnt());
72 
73  _pTile = _pTileset->getElement(_nTileIndex);
74 
75  // Try to load a trap
76  //
77  try{
78  // Locate the specified trap elment (if any)
79  //
80  unsigned nTrap = _pTileset->getElementIndex( _pTile->getText("trap-name") );
81  laPropertyList* pTrapElem = _pTileset->getElement( nTrap );//_pTile->getChild("trap");
82 
83  // Extract properties
84  //
85  _pTrap = new rpgTrap();
86  _pTrap->load( pTrapElem );
87 
88  _rgbTrap = pTrapElem->getColor("color");
89  _texTrap.load( pTrapElem->getText("texture") );
90 
91  // NOTE: it is also necessary to create a copy of the particle Fx,
92  // because the angle of the emitter changes dynamically for each trap;
93  // Fixing the emitter for the same trap won't work because all particles must follow
94  //
95  _pfxTrap = new fxParticleSystem();
96  _pfxTrap->create(pTrapElem->getFx("fx")->parameters);
97 
98  _pfxTrap->parameters.gen_linearEmitter = M_TRUE;
99  _pfxTrap->lnEmitter.origin = laPoint3(0, - M_UNIT*1.5, M_UNIT*0.4);
100  }
101  catch(laError_PropertyNotDefined&){ _pTrap = NULL; _pfxTrap = NULL; };
102 }
103 
104 // Draw the 3D geometry associated with a tile
105 //
106 void laTile::drawGeometry(laRenderer *r) {
107  ASSERT(_pTile, "Nil tile");
108  _pTile->drawGeometry(r);
109  //_domain.draw(r, laPoint3());
110 }
111 
112 // Draw animated geometry that can't be cached
113 //
114 void laTile::drawDynamicGeometry(laRenderer *r)
115 {
116  PROFILE_REN(laTile_drawDynamicGeometry);
117  ASSERT(_pTile, "Nil tile TS object");
118 
119  // Draw animated lava surface
120  //
121  double dOffsetDelta = _pSegment->terrainZOffset(_nSegX) - _pSegment->terrainZOffset(_nSegX+1);
122  double dLenght = sqrt( M_UNIT*M_UNIT + dOffsetDelta*dOffsetDelta );
123 
124  double y0 = _pSegment->getWave(_nSegX)*WAVE_AMPLITUDE - M_LAVASURFACE_OFFSET;
125  double y1 = _pSegment->getWave(_nSegX+1)*WAVE_AMPLITUDE - M_LAVASURFACE_OFFSET;
126 
127  double an0 = _pSegment->terrainAngle(_nSegX-1);
128  double an1 = _pSegment->terrainAngle(_nSegX);
129  double an2 = _pSegment->terrainAngle(_nSegX+1);
130  double sin1=sin(0.5*(an0-an1)), cos1=cos(0.5*(an0-an1));
131  double sin2=sin(0.5*(an2-an1)), cos2=cos(0.5*(an2-an1));
132 
133  double v = _pTileset->getAnimatedOffset()*0.1;
134 
135  laPoint3 *pquad = r->vquadsData(0);
136  laPoint2 *puv = r->vquadsTexCoord(0);
137 
138  laPoint3 ptStart(0, y0, M_UNIT/2.0);
139  laPoint3 ptEnd(dLenght, y1, M_UNIT/2.0);
140 
141  *(pquad++) = ptStart + 0.5*M_UNIT*laPoint3(sin1, 0, cos1);
142  *(pquad++) = ptStart - 0.5*M_UNIT*laPoint3(sin1, 0, cos1);
143  *(pquad++) = ptEnd - 0.5*M_UNIT*laPoint3(sin2, 0, cos2);
144  *(pquad++) = ptEnd + 0.5*M_UNIT*laPoint3(sin2, 0, cos2);
145 
146  *(puv++) = laPoint2(0.7, v);
147  *(puv++) = laPoint2(1, v);
148  *(puv++) = laPoint2(1, v+1);
149  *(puv++) = laPoint2(0.7, v+1);
150 
151  r->styleSet( _rgbTrap );
152  _texTrap.use();
153  r->vquadsDrawSingle();
154 
155  /*r->drawRect(
156  laPoint3(0, y0, 0),
157  laPoint3(dScale + 0.01, dy, M_UNIT*0.9 ),
158  laPoint2(0.7, v), laPoint2(0.3, 1),
159  an1, an2, M_FALSE);*/
160 }
161 
162 // Draw the effects associated with a tile
163 //
164 void laTile::drawFx(laRenderer *r)
165 {
166  ASSERT(_pTile, "Nil tile TS object");
167 
168  // Attach particle fx to lava surface
169  //
170  if( _pTrap )
171  {
172  double dCurrentOffset = _pSegment->terrainZOffset( _nSegX );
173  double dNextOffset = _pSegment->terrainZOffset( _nSegX+1 );
174  double _y0 = _pSegment->getWave( _nSegX )*WAVE_AMPLITUDE;
175  double _y1 = _pSegment->getWave( _nSegX+1 )*WAVE_AMPLITUDE;
176 
177  _pfxTrap->lnEmitter.vector[0] = M_UNIT;
178  _pfxTrap->lnEmitter.vector[2] = dNextOffset - dCurrentOffset;
179  _pfxTrap->lnEmitter.vector[1] = _y1 - _y0;
180 
181  r->transPush();
182  r->transTranslate( laPoint3(0, _y0, 0) );
183  _pfxTrap->draw(r);
184  r->transPop();
185  }
186 
187  _pTile->drawFx(r);
188 }
189 
190 // Animate the tile
191 //
192 void laTile::animate(laTimer &t){
193  if( _pTrap ) _pfxTrap->animate( t );
194 }
195 
196 // Build collision domain
197 //
198 // This information is extracted from the correspodning 3D models in the tileset
199 // and positioned at the appropriate location
200 //
201 unsigned laTile::bulidDomain(laPoint3 pos)
202 {
203  ASSERT(_pTile, "Nil tile TS element");
204 
205  _domain.offset(pos);
206  _pTile->buildCollisionData(&_domain, _pTrap);
207  _domain.updateBounds();
208 
209  return _domain.countLines();
210 }
211 
212 // Terrain curviture
213 //
214 
215 double laTile::getOffset() {
216  return _pSegment->terrainZOffset(_nSegX);
217 }
218 
219 double laTile::getAngle() {
220  return _pSegment->terrainAngle(_nSegX);
221 }
laPoint2 * vquadsTexCoord(unsigned nQuad, unsigned nCount=1)
Get a pointer to VQ texture coordinates.
Definition: laRenderer.h:284
#define M_UNIT
Unit of 1 meter.
virtual void vquadsDrawSingle(laPoint2 *ar_uv=NULL)=0
Draw a single VQ (Note this is slower than drawing an array of VQ and should be avoided) ...
2D Point
Definition: laPoint_novec.h:41
Trap Properties.
Definition: rpgTrap.h:42
Virtual interface for the Engine graphics renderer.
Definition: laRenderer.h:98
laPoint3 * vquadsData(unsigned nQuad, unsigned nCount=1)
Get a pointer to VQ vertex data.
Definition: laRenderer.h:278
File Parser.
Definition: laFileParser.h:41