Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/render2D/element_2d.cc @ 5090

Last change on this file since 5090 was 5090, checked in by bensch, 19 years ago

orxonox/trunk: math should be easy…

File size: 17.7 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 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   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "element_2d.h"
19#include "render_2d.h"
20
21#include "graphics_engine.h"
22#include "p_node.h"
23#include "load_param.h"
24#include "tinyxml.h"
25#include "class_list.h"
26#include "list.h"
27
28using namespace std;
29
30Element2D::Element2D()
31{
32  this->init();
33  this->setParent2D(NullElement2D::getInstance());
34}
35
36/**
37 * standard constructor
38 * @todo this constructor is not jet implemented - do it
39*/
40Element2D::Element2D (Element2D* parent)
41{
42  this->init();
43
44  if (this->parent != NULL)
45    this->setParent2D(parent);
46}
47
48/**
49 * standard deconstructor
50*/
51Element2D::~Element2D ()
52{
53  // delete what has to be deleted here
54  Render2D::getInstance()->unregisterElement2D(this);
55
56  tIterator<Element2D>* iterator = this->children->getIterator();
57  Element2D* pn = iterator->nextElement();
58  while( pn != NULL)
59  {
60    delete pn;
61    pn = iterator->nextElement();
62  }
63  delete iterator;
64  /* this deletes all children in the list */
65  delete this->children;
66  if (this->parent)
67    this->parent->removeChild2D(this);
68
69  if (this->toCoordinate != NULL)
70    delete this->toCoordinate;
71  if (this->toDirection != NULL)
72    delete this->toDirection;
73}
74
75
76/**
77 * initializes a Element2D
78 */
79void Element2D::init()
80{
81  this->setClassID(CL_ELEMENT_2D, "Element2D");
82
83  this->setVisibility(true);
84  this->setActiveness(true);
85  this->setAlignment(E2D_ALIGN_NONE);
86  this->layer = E2D_TOP;
87  this->bindNode = NULL;
88
89  this->setParentMode2D(E2D_PARENT_ALL);
90  this->parent = NULL;
91  this->children = new tList<Element2D>;
92  this->relDirection = 0.0;
93  this->bRelCoorChanged = true;
94  this->bRelDirChanged = true;
95  this->toCoordinate = NULL;
96  this->toDirection = NULL;
97//  else
98  //  this->setParent2D(parent);
99
100  Render2D::getInstance()->registerElement2D(this);
101}
102
103/**
104 * Loads the Parameters of an Element2D from...
105 * @param root The XML-element to load from
106 */
107void Element2D::loadParams(const TiXmlElement* root)
108{
109  LoadParam<Element2D>(root, "alignment", this, &Element2D::setAlignment)
110      .describe("loads the alignment: (either: center, left, right or screen-center)");
111
112  LoadParam<Element2D>(root, "layer", this, &Element2D::setLayer)
113      .describe("loads the layer onto which to project: (either: top, medium, bottom, below-all)");
114
115  LoadParam<Element2D>(root, "bind-node", this, &Element2D::setBindNode)
116      .describe("sets a node, this 2D-Element should be shown upon (name of the node)");
117
118  LoadParam<Element2D>(root, "visibility", this, &Element2D::setVisibility)
119      .describe("if the Element is visible or not");
120
121//   LoadParam<Element2D>(root, "2d-position", this, &Element2D::setPosition2D)
122//       .describe("the _relative_ position (away from alignment) this 2d-element shows");
123
124}
125
126/**
127 * sets the alignment of the 2D-element in form of a String
128 * @param alignment the alignment @see loadParams
129*/
130void Element2D::setAlignment(const char* alignment)
131{
132  if (!strcmp(alignment, "center"))
133    this->setAlignment(E2D_ALIGN_CENTER);
134  else if (!strcmp(alignment, "left"))
135    this->setAlignment(E2D_ALIGN_LEFT);
136  else if (!strcmp(alignment, "right"))
137    this->setAlignment(E2D_ALIGN_RIGHT);
138  else if (!strcmp(alignment, "screen-center"))
139    this->setAlignment(E2D_ALIGN_SCREEN_CENTER);
140}
141
142
143/**
144 * moves a Element to another layer
145 * @param layer the Layer this is drawn on
146 */
147void Element2D::setLayer(E2D_LAYER layer)
148{
149  Render2D::getInstance()->moveToLayer(this, layer);
150  this->layer = layer;
151}
152
153/**
154 * sets the layer onto which this 2D-element is projected to.
155 * @param layer the layer @see loadParams
156 */
157void Element2D::setLayer(const char* layer)
158{
159  if (!strcmp(layer, "top"))
160    this->setLayer(E2D_TOP);
161  else if (!strcmp(layer, "medium"))
162    this->setLayer(E2D_MEDIUM);
163  else if (!strcmp(layer, "bottom"))
164    this->setLayer(E2D_BOTTOM);
165  else if (!strcmp(layer, "below-all"))
166    this->setLayer(E2D_BELOW_ALL);
167}
168
169
170/**
171 * sets a node, this 2D-Element should be shown upon
172 * @param bindNode the name of the Node (should be existing)
173 */
174void Element2D::setBindNode(const char* bindNode)
175{
176  const PNode* tmpBindNode = dynamic_cast<const PNode*>(ClassList::getObject(bindNode, CL_PARENT_NODE));
177  if (tmpBindNode != NULL)
178    this->bindNode = tmpBindNode;
179}
180
181
182void Element2D::setRelCoor2D (const Vector& relCoord)
183{
184  this->relCoordinate = relCoord;
185  this->bRelCoorChanged = true;
186}
187
188
189void Element2D::setRelCoor2D (float x, float y, float z)
190{
191  this->setAbsCoor2D(Vector(x,y,z));
192}
193
194void Element2D::setRelCoor2Dpx (int x, int y)
195{
196  this->setRelCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
197                     (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
198                     0
199                           ));
200}
201
202
203void Element2D::setRelCoorSoft2D(const Vector& relCoordSoft, float bias)
204{
205  if (likely(this->toCoordinate == NULL))
206    this->toCoordinate = new Vector();
207
208  *this->toCoordinate = relCoordSoft;
209  this->bias = bias;
210}
211
212void Element2D::setRelCoorSoft2Dpx (int x, int y, float bias)
213{
214  this->setRelCoorSoft2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
215                         (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
216                         0),
217                         bias);
218}
219
220
221void Element2D::setRelCoorSoft2D(float x, float y, float depth, float bias)
222{
223  this->setRelCoorSoft2D(Vector(x, y, depth), bias);
224}
225
226void Element2D::setAbsCoor2D (const Vector& absCoord)
227{
228  if( likely(this->parentMode & E2D_PARENT_MOVEMENT))
229  {
230    /* if you have set the absolute coordinates this overrides all other changes */
231    if (likely(this->parent != NULL))
232      this->relCoordinate = absCoord - parent->getAbsCoor2D ();
233    else
234      this->relCoordinate = absCoord;
235  }
236  if( this->parentMode & E2D_PARENT_ROTATE_MOVEMENT)
237  {
238    if (likely(this->parent != NULL))
239      this->relCoordinate = absCoord - parent->getAbsCoor2D ();
240    else
241      this->relCoordinate = absCoord;
242  }
243
244  this->bRelCoorChanged = true;
245}
246
247void Element2D::setAbsCoor2D (float x, float y, float depth)
248{
249  this->setAbsCoor2D(Vector(x, y, depth));
250}
251
252
253void Element2D::setAbsCoor2Dpx (int x, int y)
254{
255  this->setAbsCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
256                     (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
257                     0
258                           ));
259}
260
261void Element2D::shiftCoor2D (const Vector& shift)
262{
263  this->relCoordinate += shift;
264  this->bRelCoorChanged = true;
265
266}
267
268
269void Element2D::shiftCoor2Dpx (int x, int y)
270{
271  this->shiftCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
272                    (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
273                     0));
274}
275
276
277void Element2D::setRelDir2D (float relDir)
278{
279  this->relDirection = relDir;
280  this->bRelDirChanged = true;
281}
282
283void Element2D::setRelDirSoft2D(float relDirSoft, float bias)
284{
285  if (likely(this->toDirection == NULL))
286    this->toDirection = new float;
287
288  *this->toDirection = relDirSoft;
289  this->bias = bias;
290}
291
292void Element2D::setAbsDir2D (float absDir)
293{
294  if (likely(this->parent != NULL))
295    this->relDirection = absDir - this->parent->getAbsDir2D();
296  else
297    this->relDirection = absDir;
298
299  this->bRelDirChanged = true;
300}
301
302void Element2D::shiftDir2D (float shiftDir)
303{
304  this->relDirection = this->relDirection + shiftDir;
305  this->bRelDirChanged = true;
306}
307
308
309void Element2D::addChild2D (Element2D* child, int parentingMod)
310{
311  if( likely(child->parent != NULL))
312  {
313    PRINTF(4)("Element2D::addChild() - reparenting node: removing it and adding it again\n");
314    child->parent->children->remove(child);
315  }
316  child->parentMode = parentMode;
317  child->parent = this;
318  this->children->add(child);
319  child->parentCoorChanged();
320}
321
322void Element2D::addChild2D (const char* childName)
323{
324  Element2D* childNode = dynamic_cast<Element2D*>(ClassList::getObject(childName, CL_ELEMENT_2D));
325  if (childNode != NULL)
326    this->addChild2D(childNode);
327}
328
329void Element2D::removeChild2D (Element2D* child)
330{
331  child->remove2D();
332  this->children->remove(child);
333  child->parent = NULL;
334}
335
336void Element2D::remove2D()
337{
338  tIterator<Element2D>* iterator = this->children->getIterator();
339  Element2D* pn = iterator->nextElement();
340
341  while( pn != NULL)
342  {
343    NullElement2D::getInstance()->addChild2D(pn, pn->getParentMode2D());
344    pn = iterator->nextElement();
345  }
346  delete iterator;
347  this->parent->children->remove(this);
348}
349
350
351void Element2D::setParent2D (Element2D* parent)
352{
353  parent->addChild2D(this);
354}
355
356void Element2D::setParent2D (const char* parentName)
357{
358  Element2D* parentNode = dynamic_cast<Element2D*>(ClassList::getObject(parentName, CL_ELEMENT_2D));
359  if (parentNode != NULL)
360    parentNode->addChild2D(this);
361
362}
363
364
365void Element2D::softReparent2D(Element2D* parentNode, float bias)
366{
367  if (this->parent == parentNode)
368    return;
369
370  if (likely(this->toCoordinate == NULL))
371  {
372    this->toCoordinate = new Vector();
373    *this->toCoordinate = this->getRelCoor2D();
374  }
375  if (likely(this->toDirection == NULL))
376  {
377    this->toDirection = new float;
378    *this->toDirection = this->getRelDir2D();
379  }
380  this->bias = bias;
381
382
383  Vector tmpV = this->getAbsCoor2D();
384  float tmpQ = this->getAbsDir2D();
385
386  parentNode->addChild2D(this);
387
388  if (this->parentMode & PNODE_ROTATE_MOVEMENT)
389    ;//this->setRelCoor(this->parent->getAbsDir().inverse().apply(tmpV - this->parent->getAbsCoor()));
390  else
391    this->setRelCoor2D(tmpV - parentNode->getAbsCoor2D());
392
393  this->setRelDir2D(tmpQ - parentNode->getAbsDir2D());
394}
395
396void Element2D::softReparent2D(const char* parentName, float bias)
397{
398  Element2D* parentNode = dynamic_cast<Element2D*>(ClassList::getObject(parentName, CL_ELEMENT_2D));
399  if (parentNode != NULL)
400    this->softReparent2D(parentNode, bias);
401}
402
403
404void Element2D::setParentMode2D (const char* parentingMode)
405{
406  this->setParentMode2D(Element2D::charToParentingMode2D(parentingMode));
407}
408
409
410void Element2D::update2D (float dt)
411{
412  // setting the Position of this 2D-Element.
413  if( likely(this->parent != NULL))
414  {
415      // movement for nodes with smoothMove enabled
416    if (unlikely(this->toCoordinate != NULL))
417    {
418      Vector moveVect = (*this->toCoordinate - this->getRelCoor2D()) *dt*bias;
419
420      if (likely(moveVect.len() >= .001))//PNODE_ITERATION_DELTA))
421      {
422        this->shiftCoor2D(moveVect);
423      }
424      else
425      {
426        delete this->toCoordinate;
427        this->toCoordinate = NULL;
428        PRINTF(5)("SmoothMove of %s finished\n", this->getName());
429      }
430    }
431    if (unlikely(this->toDirection != NULL))
432    {
433      float rotFlot = (*this->toDirection - this->getRelDir2D()) *dt*bias;
434      if (likely(rotFlot >= .001))//PNODE_ITERATION_DELTA))
435      {
436        this->shiftDir2D(rotFlot);
437      }
438      else
439      {
440        delete this->toDirection;
441        this->toDirection = NULL;
442        PRINTF(5)("SmoothRotate of %s finished\n", this->getName());
443      }
444    }
445
446    // MAIN UPDATE /////////////////////////////////////
447    this->lastAbsCoordinate = this->absCoordinate;
448
449    PRINTF(5)("Element2D::update - %s - (%f, %f, %f)\n", this->getName(), this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
450
451
452    if( this->parentMode & PNODE_LOCAL_ROTATE && this->bRelDirChanged)
453    {
454      /* update the current absDirection - remember * means rotation around sth.*/
455      this->prevRelDirection = this->relDirection;
456      this->absDirection = this->relDirection + parent->getAbsDir2D();;
457    }
458
459
460    if (this->alignment == E2D_ALIGN_SCREEN_CENTER && this->bRelCoorChanged)
461    {
462      this->prevRelCoordinate = this->relCoordinate;
463      this->absCoordinate.x = .5 + this->relCoordinate.x;
464      this->absCoordinate.y = .5 + this->relCoordinate.y;
465      this->absCoordinate.z = 0.0;
466    }
467    else if (this->bindNode)
468    {
469      GLdouble projectPos[3];
470      gluProject(this->bindNode->getAbsCoor().x,
471                 this->bindNode->getAbsCoor().y,
472                 this->bindNode->getAbsCoor().z,
473                 GraphicsEngine::modMat,
474                 GraphicsEngine::projMat,
475                 GraphicsEngine::viewPort,
476                 projectPos,
477                 projectPos+1,
478                 projectPos+2);
479      this->absCoordinate.x = projectPos[0]/(float)GraphicsEngine::getInstance()->getResolutionX() + this->relCoordinate.x;
480      this->absCoordinate.y = projectPos[1]/(float)GraphicsEngine::getInstance()->getResolutionY() + this->relCoordinate.y;
481      this->absCoordinate.z = projectPos[2] + this->relCoordinate.z;
482    }
483    else
484    {
485      if(likely(this->parentMode & PNODE_MOVEMENT && this->bRelCoorChanged))
486      {
487        /* update the current absCoordinate */
488        this->prevRelCoordinate = this->relCoordinate;
489        this->absCoordinate = this->parent->getAbsCoor2D() + this->relCoordinate;
490      }
491      else if( this->parentMode & PNODE_ROTATE_MOVEMENT && this->bRelCoorChanged)
492      {
493        /* update the current absCoordinate */
494        this->prevRelCoordinate = this->relCoordinate;
495        float sine = sin(this->parent->getAbsDir2D());
496        float cose = cos(this->parent->getAbsDir2D());
497//        this->absCoordinate.x = this->relCoordinate.x*cose - this->relCoordinate.y*sine + this->parent->getRelCoor2D().x*(1-cose) +this->parent->getRelCoor2D().y*sine;
498//        this->absCoordinate.y = this->relCoordinate.x*sine + this->relCoordinate.y*cose + this->parent->getRelCoor2D().y*(1-cose) +this->parent->getRelCoor2D().x*sine;
499
500        this->absCoordinate.x = this->parent->getAbsCoor2D().x + (this->relCoordinate.x*cos(this->parent->getAbsDir2D()) - this->relCoordinate.y * sin(this->parent->getAbsDir2D()));
501        this->absCoordinate.y = this->parent->getAbsCoor2D().y + (this->relCoordinate.x*sin(this->parent->getAbsDir2D()) + this->relCoordinate.y * cos(this->parent->getAbsDir2D()));
502
503      }
504    }
505    /////////////////////////////////////////////////
506  }
507  else
508  {
509    PRINTF(5)("Element2D::update - (%f, %f, %f)\n", this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
510    if (this->bRelCoorChanged)
511      this->absCoordinate = this->relCoordinate;
512    if (this->bRelDirChanged)
513      this->absDirection = this->getAbsDir2D() * this->relDirection;
514  }
515
516
517  // UPDATE CHILDREN
518  if(this->children->getSize() > 0)
519  {
520    tIterator<Element2D>* iterator = this->children->getIterator();
521    Element2D* pn = iterator->nextElement();
522    while( pn != NULL)
523    {
524      /* if this node has changed, make sure, that all children are updated also */
525      if( likely(this->bRelCoorChanged))
526        pn->parentCoorChanged ();
527      if( likely(this->bRelDirChanged))
528        pn->parentDirChanged ();
529
530      pn->update2D(dt);
531          //pn = this->children->nextElement();
532      pn = iterator->nextElement();
533    }
534    delete iterator;
535  }
536
537  // FINISHING PROCESS
538  this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
539  this->bRelCoorChanged = false;
540  this->bRelDirChanged = false;
541}
542
543
544void Element2D::debug (unsigned int depth, unsigned int level) const
545{
546  for (unsigned int i = 0; i < level; i++)
547    PRINT(0)(" |");
548  if (this->children->getSize() > 0)
549    PRINT(0)(" +");
550  else
551    PRINT(0)(" -");
552  PRINT(0)("Element2D(%s::%s) - absCoord: (%0.2f, %0.2f), relCoord(%0.2f, %0.2f), direction(%0.2f) - %s\n",
553  this->getClassName(),
554  this->getName(),
555  this->absCoordinate.x,
556  this->absCoordinate.y,
557  this->relCoordinate.x,
558  this->relCoordinate.y,
559  this->getAbsDir2D(),
560  Element2D::parentingModeToChar2D(parentMode));
561  if (depth >= 2 || depth == 0)
562  {
563    tIterator<Element2D>* iterator = this->children->getIterator();
564      //PNode* pn = this->children->enumerate ();
565    Element2D* pn = iterator->nextElement();
566    while( pn != NULL)
567    {
568      if (depth == 0)
569        pn->debug(0, level + 1);
570      else
571        pn->debug(depth - 1, level +1);
572      pn = iterator->nextElement();
573    }
574    delete iterator;
575  }
576}
577
578#include "color.h"
579
580void Element2D::debugDraw2D(unsigned int depth, float size, Vector color) const
581{
582
583}
584
585
586// helper functions //
587const char* Element2D::parentingModeToChar2D(int parentingMode)
588{
589  if (parentingMode == E2D_PARENT_LOCAL_ROTATE)
590    return "local-rotate";
591  else if (parentingMode == E2D_PARENT_ROTATE_MOVEMENT)
592    return "rotate-movement";
593  else if (parentingMode == E2D_PARENT_MOVEMENT)
594    return "movement";
595  else if (parentingMode == E2D_PARENT_ALL)
596    return "all";
597  else if (parentingMode == E2D_PARENT_ROTATE_AND_MOVE)
598    return "rotate-and-move";
599}
600
601E2D_PARENT_MODE Element2D::charToParentingMode2D(const char* parentingMode)
602{
603  if (!strcmp(parentingMode, "local-rotate"))
604    return (E2D_PARENT_LOCAL_ROTATE);
605  else  if (!strcmp(parentingMode, "rotate-movement"))
606    return (E2D_PARENT_ROTATE_MOVEMENT);
607  else  if (!strcmp(parentingMode, "movement"))
608    return (E2D_PARENT_MOVEMENT);
609  else  if (!strcmp(parentingMode, "all"))
610    return (E2D_PARENT_ALL);
611  else  if (!strcmp(parentingMode, "rotate-and-move"))
612    return (E2D_PARENT_ROTATE_AND_MOVE);
613}
614
615
616
617
618
619
620/**
621 * ticks the 2d-Element
622 * @param dt the time elapsed since the last tick
623 */
624void Element2D::tick(float dt)
625{
626
627}
628
629
630
631
632
633
634
635NullElement2D* NullElement2D::singletonRef = 0;
636
637/**
638 *  creates the one and only NullElement2D
639 * @param absCoordinate the cordinate of the Parent (normally Vector(0,0,0))
640 */
641NullElement2D::NullElement2D () : Element2D(NULL)
642{
643  this->setClassID(CL_NULL_PARENT, "NullElement2D");
644  this->setName("NullElement2D");
645
646  this->setParentMode2D(E2D_PARENT_ALL);
647  NullElement2D::singletonRef = this;
648}
649
650
651/**
652 *  standard deconstructor
653 */
654NullElement2D::~NullElement2D ()
655{
656  //delete singletonRef;
657  NullElement2D::singletonRef = NULL;
658}
Note: See TracBrowser for help on using the repository browser.