[10081] | 1 | /* |
---|
| 2 | orxonox - the future of 3D-vertical-scrollers |
---|
| 3 | |
---|
| 4 | Copyright (C) 2006 orx |
---|
| 5 | |
---|
| 6 | This program is free software; you can redistribute it and/or modify |
---|
| 7 | it under the terms of the GNU General Public License as published by |
---|
| 8 | the Free Software Foundation; either version 2, or (at your option) |
---|
| 9 | any later version. |
---|
| 10 | |
---|
| 11 | ### File Specific: |
---|
| 12 | |
---|
| 13 | Trail system for engine output trails. |
---|
| 14 | uses a catmull rom spline to interpolate the curve which is subdivided |
---|
| 15 | into sections parts. |
---|
| 16 | main-programmer: Marc Schaerer |
---|
| 17 | */ |
---|
| 18 | |
---|
| 19 | #include "trail.h" |
---|
| 20 | |
---|
| 21 | #include "util/loading/load_param.h" |
---|
| 22 | #include "util/loading/factory.h" |
---|
| 23 | |
---|
| 24 | #include "quaternion.h" |
---|
| 25 | #include "vector.h" |
---|
| 26 | |
---|
| 27 | #include "graphics_engine.h" |
---|
| 28 | #include "material.h" |
---|
| 29 | #include "glincl.h" |
---|
| 30 | #include "state.h" |
---|
| 31 | #include "debug.h" |
---|
| 32 | |
---|
| 33 | #include "class_id_DEPRECATED.h" |
---|
| 34 | |
---|
| 35 | ObjectListDefinition(Trail); |
---|
| 36 | CREATE_FACTORY(Trail); |
---|
| 37 | |
---|
| 38 | /** |
---|
| 39 | * standart constructor |
---|
| 40 | * @param maxLength maximum length of the trail. You will later need to set the actual length used. |
---|
| 41 | * @param sections number of sections into which the trail polygon shall be splited. Higher number for more smooth curves |
---|
| 42 | * @param radius radius of the trail cross. |
---|
| 43 | * |
---|
| 44 | */ |
---|
| 45 | Trail::Trail (float maxLength, int sections, float radius) |
---|
| 46 | { |
---|
| 47 | this->maxLength = maxLength; |
---|
| 48 | this->length = 1.0; |
---|
| 49 | this->sections = sections; |
---|
| 50 | this->radius = radius; |
---|
| 51 | |
---|
| 52 | this->nodeList = new Vector[sections]; |
---|
| 53 | |
---|
| 54 | |
---|
| 55 | this->init(); |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | Trail::Trail (const TiXmlElement* root) |
---|
| 59 | { |
---|
| 60 | this->init(); |
---|
| 61 | |
---|
| 62 | if( root) |
---|
| 63 | this->loadParams(root); |
---|
| 64 | } |
---|
| 65 | |
---|
| 66 | /** |
---|
| 67 | * destroys a Trail |
---|
| 68 | */ |
---|
| 69 | Trail::~Trail () |
---|
| 70 | { |
---|
| 71 | if (this->material) |
---|
| 72 | delete this->material; |
---|
| 73 | delete this->nodeList; |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | |
---|
| 77 | /** |
---|
| 78 | * initializes the Trail |
---|
| 79 | */ |
---|
| 80 | void Trail::init() |
---|
| 81 | { |
---|
| 82 | this->registerObject(this, Trail::_objectList); |
---|
| 83 | this->setName("Trail"); |
---|
| 84 | |
---|
| 85 | this->material = new Material(); |
---|
| 86 | this->material->setIllum(3); |
---|
| 87 | this->material->setDiffuse(1.0,1.0,1.0); |
---|
| 88 | this->material->setSpecular(0.0,0.0,0.0); |
---|
| 89 | this->material->setAmbient(1.0, 1.0, 1.0); |
---|
| 90 | |
---|
| 91 | this->setAbsCoor(0, 0, 0); |
---|
| 92 | this->setVisibiliy(true); |
---|
| 93 | |
---|
| 94 | this->nodeList[0] = (this->getAbsCoor()); |
---|
| 95 | //PRINTF(0)("Trail data: N%i (%f,%f,%f)",0,this->getAbsCoor().x,this->getAbsCoor().y,this->getAbsCoor().z); |
---|
| 96 | for( int i = 1; i < sections; i++) |
---|
| 97 | { |
---|
| 98 | this->nodeList[i] = (this->getAbsCoor() - ((Vector(1,0,0) * (i * this->maxLength / sections)))); |
---|
| 99 | //PRINTF(0)(" N%i (%f,%f,%f)",i,this->nodeList[i].x,this->nodeList[i].y,this->nodeList[i].z); |
---|
| 100 | } |
---|
| 101 | //PRINTF(0)("\n"); |
---|
| 102 | } |
---|
| 103 | |
---|
| 104 | |
---|
| 105 | /** |
---|
| 106 | * load params |
---|
| 107 | * @param root TiXmlElement object |
---|
| 108 | */ |
---|
| 109 | void Trail::loadParams(const TiXmlElement* root) |
---|
| 110 | { |
---|
| 111 | WorldEntity::loadParams( root); |
---|
| 112 | } |
---|
| 113 | |
---|
| 114 | /** |
---|
| 115 | * sets the material to load |
---|
| 116 | * @param textureFile The texture-file to load |
---|
| 117 | */ |
---|
| 118 | void Trail::setTexture(const std::string& textureFile) |
---|
| 119 | { |
---|
| 120 | this->material->setDiffuseMap(textureFile); |
---|
| 121 | } |
---|
| 122 | |
---|
| 123 | |
---|
| 124 | /** |
---|
| 125 | * ticks the Trail |
---|
| 126 | * @param dt the time to ticks |
---|
| 127 | */ |
---|
| 128 | void Trail::tick(float dt) |
---|
| 129 | { |
---|
| 130 | // Update node positions |
---|
| 131 | float secLen = this->maxLength / this->sections; |
---|
| 132 | this->nodeList[0] = (this->getAbsCoor()); |
---|
| 133 | for(int i = 1; i < this->sections; i++) |
---|
| 134 | { |
---|
| 135 | this->nodeList[i] = this->nodeList[i-1] - (this->nodeList[i-1] - this->nodeList[i]).getNormalized()*secLen; |
---|
| 136 | } |
---|
| 137 | /* |
---|
| 138 | this->length = this->maxLength / (this->getAbsCoor() - this->nodeList[this->sections-1]).len(); |
---|
| 139 | if (!likely(this->length == 1.0)) |
---|
| 140 | for(int i = 1; i < this->sections; i++) |
---|
| 141 | this->nodeList[i] = this->getAbsCoor()- (this->getAbsCoor() - this->nodeList[i])*this->length; |
---|
| 142 | */ |
---|
| 143 | /*PRINTF(0)("TRAIL POS "); |
---|
| 144 | for( int i=0; i < this->sections; i++) |
---|
| 145 | { |
---|
| 146 | PRINTF(0)("N%i (%f,%f,%f)",i,this->nodeList[i].x,this->nodeList[i].y,this->nodeList[i].z); |
---|
| 147 | } |
---|
| 148 | PRINTF(0)("\n");*/ |
---|
| 149 | } |
---|
| 150 | |
---|
| 151 | |
---|
| 152 | /** |
---|
| 153 | * draws the trail |
---|
| 154 | * the trail has a cone shape |
---|
| 155 | */ |
---|
| 156 | void Trail::draw() const |
---|
| 157 | { |
---|
| 158 | if(!this->isVisible()) |
---|
| 159 | return; |
---|
| 160 | |
---|
| 161 | Vector* Q = new Vector[4]; |
---|
| 162 | Vector targ; |
---|
| 163 | Vector now, later; |
---|
| 164 | float fact = 1.0/this->sections; |
---|
| 165 | float rad0, rad1; |
---|
| 166 | |
---|
| 167 | //glPushAttrib(GL_ENABLE_BIT); |
---|
| 168 | |
---|
| 169 | glPushMatrix(); |
---|
| 170 | //glMatrixMode(GL_MODELVIEW); |
---|
| 171 | //glLoadIdentity(); |
---|
| 172 | glTranslatef(-this->getAbsCoor().x,-this->getAbsCoor().y,-this->getAbsCoor().z); |
---|
| 173 | glScalef(1,1,1); |
---|
| 174 | this->material->select(); |
---|
| 175 | /* |
---|
| 176 | glBegin(GL_TRIANGLESTRIP); |
---|
| 177 | for( int i = 0; i < this->sections-1; i++) |
---|
| 178 | { |
---|
| 179 | rad1 = this->radius * (1.0-i*fact); |
---|
| 180 | rad0 = this->radius * (1.0-(i+1)*fact); |
---|
| 181 | |
---|
| 182 | now = this->nodeList[i]; |
---|
| 183 | later = this->nodeList[i+1]; |
---|
| 184 | if( i == 0) |
---|
| 185 | targ = this->getAbsDir().apply(Vector(1,0,0)).getNormalized(); |
---|
| 186 | else |
---|
| 187 | targ = (this->getAbsCoor() - now).getNormalized(); |
---|
| 188 | |
---|
| 189 | // vertical polygon |
---|
| 190 | Q[0] = now + Vector(0,rad1,0) ; |
---|
| 191 | Q[1] = later + Vector(0,rad0,0) ; |
---|
| 192 | Q[2] = later + Vector(0,-rad0,0) ; |
---|
| 193 | Q[3] = now + Vector(0,-rad1,0) ; |
---|
| 194 | //PRINTF(0)("Debug output: Q0 (%f,%f,%f) :: Q1 (%f,%f,%f) :: Q2 (%f,%f,%f) :: Q3 (%f,%f,%f)\n",Q[0].x,Q[0].y,Q[0].z,Q[1].x,Q[1].y,Q[1].z,Q[2].x,Q[2].y,Q[2].z,Q[3].x,Q[3].y,Q[3].z); |
---|
| 195 | |
---|
| 196 | glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z); |
---|
| 197 | glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z); |
---|
| 198 | glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z); |
---|
| 199 | glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z); |
---|
| 200 | |
---|
| 201 | } |
---|
| 202 | glEnd(); |
---|
| 203 | glBegin(GL_TRIANGLESTRIP); |
---|
| 204 | for( int i = 0; i < this->sections-1; i++) |
---|
| 205 | { |
---|
| 206 | rad1 = this->radius * (1.0-i*fact); |
---|
| 207 | rad0 = this->radius * (1.0-(i+1)*fact); |
---|
| 208 | |
---|
| 209 | now = this->nodeList[i]; |
---|
| 210 | later = this->nodeList[i+1]; |
---|
| 211 | if( i == 0) |
---|
| 212 | targ = this->getAbsDir().apply(Vector(1,0,0)).getNormalized(); |
---|
| 213 | else |
---|
| 214 | targ = (this->getAbsCoor() - now).getNormalized(); |
---|
| 215 | |
---|
| 216 | // vertical polygon |
---|
| 217 | Q[0] = now + Vector(0,rad1,0) ; |
---|
| 218 | Q[1] = later + Vector(0,rad0,0) ; |
---|
| 219 | Q[2] = later + Vector(0,-rad0,0) ; |
---|
| 220 | Q[3] = now + Vector(0,-rad1,0) ; |
---|
| 221 | //PRINTF(0)("Debug output: Q0 (%f,%f,%f) :: Q1 (%f,%f,%f) :: Q2 (%f,%f,%f) :: Q3 (%f,%f,%f)\n",Q[0].x,Q[0].y,Q[0].z,Q[1].x,Q[1].y,Q[1].z,Q[2].x,Q[2].y,Q[2].z,Q[3].x,Q[3].y,Q[3].z); |
---|
| 222 | |
---|
| 223 | glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z); |
---|
| 224 | glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z); |
---|
| 225 | glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z); |
---|
| 226 | glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z); |
---|
| 227 | |
---|
| 228 | } |
---|
| 229 | glEnd();*/ |
---|
| 230 | glBegin(GL_TRIANGLE_STRIP); |
---|
| 231 | for( int i = 1; i < this->sections-1; i++) |
---|
| 232 | { |
---|
| 233 | rad1 = this->radius * (1.0-i*fact); |
---|
| 234 | rad0 = this->radius * (1.0-(i+1)*fact); |
---|
| 235 | |
---|
| 236 | now = this->nodeList[i]; |
---|
| 237 | later = this->nodeList[i+1]; |
---|
| 238 | if( i == 0) |
---|
| 239 | targ = this->getAbsDir().apply(Vector(1,0,0)).getNormalized(); |
---|
| 240 | else |
---|
| 241 | targ = (this->getAbsCoor() - now).getNormalized(); |
---|
| 242 | |
---|
| 243 | // horizontal polygon |
---|
| 244 | Q[0] = now + Vector(0,rad1,0) ; |
---|
| 245 | Q[3] = now + Vector(0,-rad1,0) ; |
---|
| 246 | |
---|
| 247 | glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z); |
---|
| 248 | glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z); |
---|
| 249 | |
---|
| 250 | if( i == this->sections - 1) |
---|
| 251 | { |
---|
| 252 | |
---|
| 253 | Q[1] = later + Vector(0,rad0,0) ; |
---|
| 254 | Q[2] = later + Vector(0,-rad0,0) ; |
---|
| 255 | glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z); |
---|
| 256 | glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z); |
---|
| 257 | } |
---|
| 258 | |
---|
| 259 | |
---|
| 260 | } |
---|
| 261 | glEnd(); |
---|
| 262 | glBegin(GL_TRIANGLE_STRIP); |
---|
| 263 | for( int i = this->sections-1; i > 0; i--) |
---|
| 264 | { |
---|
| 265 | rad1 = this->radius * (1.0-i*fact); |
---|
| 266 | rad0 = this->radius * (1.0-(i-1)*fact); |
---|
| 267 | |
---|
| 268 | now = this->nodeList[i]; |
---|
| 269 | later = this->nodeList[i-1]; |
---|
| 270 | if( i == 0) |
---|
| 271 | targ = this->getAbsDir().apply(Vector(1,0,0)).getNormalized(); |
---|
| 272 | else |
---|
| 273 | targ = (this->getAbsCoor() - now).getNormalized(); |
---|
| 274 | |
---|
| 275 | // horizontal polygon |
---|
| 276 | Q[0] = now + Vector(0,rad1,0) ; |
---|
| 277 | Q[3] = now + Vector(0,-rad1,0) ; |
---|
| 278 | |
---|
| 279 | glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z); |
---|
| 280 | glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z); |
---|
| 281 | |
---|
| 282 | if( i == 1) |
---|
| 283 | { |
---|
| 284 | Q[1] = later + Vector(0,rad0,0) ; |
---|
| 285 | Q[2] = later + Vector(0,-rad0,0) ; |
---|
| 286 | glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z); |
---|
| 287 | glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z); |
---|
| 288 | } |
---|
| 289 | |
---|
| 290 | } |
---|
| 291 | glEnd(); |
---|
| 292 | |
---|
| 293 | |
---|
| 294 | glBegin(GL_TRIANGLE_STRIP); |
---|
| 295 | for( int i = 1; i < this->sections-1; i++) |
---|
| 296 | { |
---|
| 297 | rad1 = this->radius * (1.0-i*fact); |
---|
| 298 | rad0 = this->radius * (1.0-(i+1)*fact); |
---|
| 299 | |
---|
| 300 | now = this->nodeList[i]; |
---|
| 301 | later = this->nodeList[i+1]; |
---|
| 302 | if( i == 0) |
---|
| 303 | targ = this->getAbsDir().apply(Vector(1,0,0)).getNormalized(); |
---|
| 304 | else |
---|
| 305 | targ = (this->getAbsCoor() - now).getNormalized(); |
---|
| 306 | |
---|
| 307 | // horizontal polygon |
---|
| 308 | Q[0] = now + targ.cross(Vector(0,rad1,0)) ; |
---|
| 309 | Q[3] = now + targ.cross(Vector(0,-rad1,0)) ; |
---|
| 310 | |
---|
| 311 | glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z); |
---|
| 312 | glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z); |
---|
| 313 | |
---|
| 314 | if( i == this->sections-1) |
---|
| 315 | { |
---|
| 316 | Q[1] = later + targ.cross(Vector(0,rad0,0)) ; |
---|
| 317 | Q[2] = later + targ.cross(Vector(0,-rad0,0)) ; |
---|
| 318 | glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z); |
---|
| 319 | glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z); |
---|
| 320 | } |
---|
| 321 | |
---|
| 322 | |
---|
| 323 | } |
---|
| 324 | glEnd(); |
---|
| 325 | glBegin(GL_TRIANGLE_STRIP); |
---|
| 326 | for( int i = this->sections-1; i > 0; i--) |
---|
| 327 | { |
---|
| 328 | rad1 = this->radius * (1.0-i*fact); |
---|
| 329 | rad0 = this->radius * (1.0-(i-1)*fact); |
---|
| 330 | |
---|
| 331 | now = this->nodeList[i]; |
---|
| 332 | later = this->nodeList[i-1]; |
---|
| 333 | if( i == 0) |
---|
| 334 | targ = this->getAbsDir().apply(Vector(1,0,0)).getNormalized(); |
---|
| 335 | else |
---|
| 336 | targ = (this->getAbsCoor() - now).getNormalized(); |
---|
| 337 | |
---|
| 338 | // horizontal polygon |
---|
| 339 | Q[0] = now + targ.cross(Vector(0,rad1,0)) ; |
---|
| 340 | Q[3] = now + targ.cross(Vector(0,-rad1,0)) ; |
---|
| 341 | |
---|
| 342 | glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z); |
---|
| 343 | glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z); |
---|
| 344 | |
---|
| 345 | if( i == 1) |
---|
| 346 | { |
---|
| 347 | Q[1] = later + targ.cross(Vector(0,rad0,0)) ; |
---|
| 348 | Q[2] = later + targ.cross(Vector(0,-rad0,0)) ; |
---|
| 349 | glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z); |
---|
| 350 | glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z); |
---|
| 351 | } |
---|
| 352 | |
---|
| 353 | } |
---|
| 354 | glEnd(); |
---|
| 355 | this->material->unselect(); |
---|
| 356 | |
---|
| 357 | glPopMatrix(); |
---|
| 358 | //glPopAttrib(); |
---|
| 359 | /* |
---|
| 360 | //glTranslatef(this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z); |
---|
| 361 | //glTranslatef(0,0,0); |
---|
| 362 | |
---|
| 363 | const PNode* camera = State::getCameraNode(); //!< @todo MUST be different |
---|
| 364 | Vector cameraPos = camera->getAbsCoor(); |
---|
| 365 | Vector cameraTargetPos = State::getCameraTargetNode()->getAbsCoor(); |
---|
| 366 | Vector view = cameraTargetPos - cameraPos; |
---|
| 367 | Vector up = Vector(0, 1, 0); |
---|
| 368 | up = camera->getAbsDir().apply(up); |
---|
| 369 | Vector h = up.cross(view); |
---|
| 370 | Vector v = h.cross(view); |
---|
| 371 | h.normalize(); |
---|
| 372 | v.normalize(); |
---|
| 373 | |
---|
| 374 | v *= sizeX; |
---|
| 375 | h *= sizeY; |
---|
| 376 | |
---|
| 377 | //v += this->getAbsCoor(); |
---|
| 378 | //PRINTF(0)("sizeX: %f sizeY: %f\n", sizeX, sizeY); |
---|
| 379 | glBegin(GL_QUADS); |
---|
| 380 | glTexCoord2f(0.0f, 0.0f); |
---|
| 381 | glVertex3f(this->getAbsCoor().x - h.x - v.x, |
---|
| 382 | this->getAbsCoor().y - h.y - v.y, |
---|
| 383 | this->getAbsCoor().z - h.z - v.z); |
---|
| 384 | glTexCoord2f(1.0f, 0.0f); |
---|
| 385 | glVertex3f( this->getAbsCoor().x + h.x - v.x, |
---|
| 386 | this->getAbsCoor().y + h.y - v.y, |
---|
| 387 | this->getAbsCoor().z + h.z - v.z); |
---|
| 388 | glTexCoord2f(1.0f, 1.0f); |
---|
| 389 | glVertex3f(this->getAbsCoor().x + h.x + v.x, |
---|
| 390 | this->getAbsCoor().y + h.y + v.y, |
---|
| 391 | this->getAbsCoor().z + h.z + v.z); |
---|
| 392 | glTexCoord2f(0.0f, 1.0f); |
---|
| 393 | glVertex3f(this->getAbsCoor().x - h.x + v.x, |
---|
| 394 | this->getAbsCoor().y - h.y + v.y, |
---|
| 395 | this->getAbsCoor().z - h.z + v.z); |
---|
| 396 | glEnd(); |
---|
| 397 | |
---|
| 398 | |
---|
| 399 | glPopMatrix(); |
---|
| 400 | |
---|
| 401 | glPopAttrib();*/ |
---|
| 402 | } |
---|