Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merge the ObjectManager to the trunk
merged with command:
svn merge -r6082:HEAD objectmanager/ ../trunk/

conflicts resolution was easy this time :)
but specially merged the world to network_world

File size: 30.1 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 <algorithm>
22
23#include "p_node.h"
24
25#include "graphics_engine.h"
26#include "load_param.h"
27#include "parser/tinyxml/tinyxml.h"
28#include "class_list.h"
29
30#include "color.h"
31
32using namespace std;
33
34/**
35 * standard constructor
36 */
37Element2D::Element2D()
38{
39  this->init();
40  this->setParent2D(NullElement2D::getInstance());
41}
42
43/**
44 * standard constructor
45 * @param parent the parent to set for this Element2D
46 *
47 * NullElement2D needs this constructor with parameter NULL to initialize
48 * itself. Otherwise it would result in an endless Loop.
49 */
50Element2D::Element2D (Element2D* parent, E2D_LAYER layer)
51{
52  this->init();
53  this->layer = layer;
54  // check Parenting, and if ok parent the stuff
55  if (this->parent != NULL)
56    this->setParent2D(parent);
57  else if (NullElement2D::isInstanciated())
58    this->setParent2D(NullElement2D::getInstance());
59}
60
61/**
62 * standard deconstructor
63 *
64 * There are two general ways to delete an Element2D
65 * 1. delete instance;
66 *   -> result
67 *    delete this Node and all its children and children's children...
68 *    (danger if you still want the instance!!)
69 *
70 * 2. instance->remove2D(); delete instance;
71 *   -> result:
72 *    moves its children to the NullElement2D
73 *    then deletes the Element.
74 */
75Element2D::~Element2D ()
76{
77  // remove the Node, delete it's children.
78  while (this->children.size() > 0)
79  {
80    Element2D* child = this->children.front();
81    this->children.pop_front();
82    delete child;
83  }
84  if (this->parent != NULL)
85  {
86    this->parent->eraseChild(this);
87    this->parent = NULL;
88  }
89
90  // remove all other allocated memory.
91  if (this->toCoordinate != NULL)
92    delete this->toCoordinate;
93  if (this->toDirection != NULL)
94    delete this->toDirection;
95}
96
97
98/**
99 * initializes a Element2D
100 */
101void Element2D::init()
102{
103  this->setClassID(CL_ELEMENT_2D, "Element2D");
104
105  this->setVisibility(true);
106  this->setActiveness(true);
107  this->setAlignment(E2D_ALIGN_NONE);
108  this->layer = E2D_DEFAULT_LAYER;
109  this->bindNode = NULL;
110
111  this->setParentMode2D(E2D_PARENT_ALL);
112  this->parent = NULL;
113  this->absDirection = 0.0;
114  this->relDirection = 0.0;
115  this->bRelCoorChanged = true;
116  this->bRelDirChanged = true;
117  this->toCoordinate = NULL;
118  this->toDirection = NULL;
119  this->setSize2D(1,1);
120}
121
122/**
123 * Loads the Parameters of an Element2D from...
124 * @param root The XML-element to load from
125 */
126void Element2D::loadParams(const TiXmlElement* root)
127{
128  // ELEMENT2D-native settings.
129  LoadParam(root, "alignment", this, Element2D, setAlignment)
130      .describe("loads the alignment: (either: center, left, right or screen-center)");
131
132  LoadParam(root, "layer", this, Element2D, setLayer)
133      .describe("loads the layer onto which to project: (either: top, medium, bottom, below-all)");
134
135  LoadParam(root, "bind-node", this, Element2D, setBindNode)
136      .describe("sets a node, this 2D-Element should be shown upon (name of the node)");
137
138  LoadParam(root, "visibility", this, Element2D, setVisibility)
139      .describe("if the Element is visible or not");
140
141
142// PNode-style:
143  LoadParam(root, "rel-coor", this, Element2D, setRelCoor2D)
144      .describe("Sets The relative position of the Node to its parent.");
145
146  LoadParam(root, "abs-coor", this, Element2D, setAbsCoor2D)
147      .describe("Sets The absolute Position of the Node.");
148
149  LoadParam(root, "rel-dir", this, Element2D, setRelDir2D)
150      .describe("Sets The relative rotation of the Node to its parent.");
151
152  LoadParam(root, "abs-dir", this, Element2D, setAbsDir2D)
153      .describe("Sets The absolute rotation of the Node.");
154
155  LoadParam(root, "parent", this, Element2D, setParent2D)
156      .describe("the Name of the Parent of this Element2D");
157
158  LoadParam(root, "parent-mode", this, Element2D, setParentMode2D)
159      .describe("the mode to connect this node to its parent ()");
160
161  // cycling properties
162  if (root != NULL)
163  {
164    LOAD_PARAM_START_CYCLE(root, element);
165    {
166      LoadParam_CYCLE(element, "parent", this, Element2D, addChild2D)
167          .describe("adds a new Child to the current Node.");
168    }
169    LOAD_PARAM_END_CYCLE(element);
170  }
171}
172
173/**
174 * sets the alignment of the 2D-element in form of a String
175 * @param alignment the alignment @see loadParams
176*/
177void Element2D::setAlignment(const char* alignment)
178{
179  if (!strcmp(alignment, "center"))
180    this->setAlignment(E2D_ALIGN_CENTER);
181  else if (!strcmp(alignment, "left"))
182    this->setAlignment(E2D_ALIGN_LEFT);
183  else if (!strcmp(alignment, "right"))
184    this->setAlignment(E2D_ALIGN_RIGHT);
185  else if (!strcmp(alignment, "screen-center"))
186    this->setAlignment(E2D_ALIGN_SCREEN_CENTER);
187}
188
189
190/**
191 * moves a Element to another layer
192 * @param layer the Layer this is drawn on
193 */
194void Element2D::setLayer(E2D_LAYER layer)
195{
196  if (this->parent != NULL && this->parent->getLayer() > layer)
197  {
198    PRINTF(2)("Unable to set %s to layer %s, because it's parent(%s) is of higher layer %s\n",
199              this->getName(),
200              Element2D::layer2DToChar(layer),
201              this->parent->getName(),
202              Element2D::layer2DToChar(this->parent->getLayer()));
203    layer = this->parent->getLayer();
204  }
205  this->layer = layer;
206}
207
208/**
209 * sets the layer onto which this 2D-element is projected to.
210 * @param layer the layer @see loadParams @see Element2D::charToLayer2D(const char* layer)
211 */
212void Element2D::setLayer(const char* layer)
213{
214  this->setLayer(Element2D::charToLayer2D(layer));
215}
216
217
218/**
219 * sets a node, this 2D-Element should be shown upon
220 * @param bindNode the name of the Node (should be existing)
221 */
222void Element2D::setBindNode(const char* bindNode)
223{
224  const PNode* tmpBindNode = dynamic_cast<const PNode*>(ClassList::getObject(bindNode, CL_PARENT_NODE));
225  if (tmpBindNode != NULL)
226    this->bindNode = tmpBindNode;
227}
228
229/**
230 * sets the relative coordinate of the Element2D to its parent
231 * @param relCoord the relative coordinate to the parent
232 */
233void Element2D::setRelCoor2D (const Vector& relCoord)
234{
235  if (this->toCoordinate!= NULL)
236  {
237    delete this->toCoordinate;
238    this->toCoordinate = NULL;
239  }
240  this->relCoordinate = relCoord;
241  this->bRelCoorChanged = true;
242}
243
244
245/**
246 * sets the relative coordinate of the Element2D to its Parent
247 * @param x the x coordinate
248 * @param y the y coordinate
249 * @param z the z coordinate
250 */
251void Element2D::setRelCoor2D (float x, float y, float z)
252{
253  this->setRelCoor2D(Vector(x,y,z));
254}
255
256/**
257 * sets the Relative coordinate to the parent in Pixels
258 * @param x the relCoord X
259 * @param y the relCoord Y
260 */
261void Element2D::setRelCoor2Dpx (int x, int y)
262{
263  this->setRelCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
264                     (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
265                     0
266                           ));
267}
268
269/**
270 * sets a new relative position smoothely
271 * @param relCoordSoft the new Position to iterate to
272 * @param bias how fast to iterate to this position
273 */
274void Element2D::setRelCoorSoft2D(const Vector& relCoordSoft, float bias)
275{
276  if (likely(this->toCoordinate == NULL))
277    this->toCoordinate = new Vector();
278
279  *this->toCoordinate = relCoordSoft;
280  this->bias = bias;
281}
282
283/**
284 * sets a new relative position smoothely
285 * @param x the new x-coordinate in Pixels of the Position to iterate to
286 * @param y the new y-coordinate in Pixels of the Position to iterate to
287 * @param bias how fast to iterate to this position
288 */
289void Element2D::setRelCoorSoft2Dpx (int x, int y, float bias)
290{
291  this->setRelCoorSoft2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
292                         (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
293                         0),
294                         bias);
295}
296
297/**
298 * set relative coordinates smoothely
299 * @param x x-relative coordinates to its parent
300 * @param y y-relative coordinates to its parent
301 * @param z z-relative coordinates to its parent
302 * @see  void PNode::setRelCoorSoft (const Vector&, float)
303 */
304void Element2D::setRelCoorSoft2D(float x, float y, float depth, float bias)
305{
306  this->setRelCoorSoft2D(Vector(x, y, depth), bias);
307}
308
309/**
310 * @param absCoord set absolute coordinate
311 */
312void Element2D::setAbsCoor2D (const Vector& absCoord)
313{
314  if (this->toCoordinate!= NULL)
315  {
316    delete this->toCoordinate;
317    this->toCoordinate = NULL;
318  }
319
320  if( likely(this->parentMode & E2D_PARENT_MOVEMENT))
321  {
322    /* if you have set the absolute coordinates this overrides all other changes */
323    if (likely(this->parent != NULL))
324      this->relCoordinate = absCoord - parent->getAbsCoor2D ();
325    else
326      this->relCoordinate = absCoord;
327  }
328  if( this->parentMode & E2D_PARENT_ROTATE_MOVEMENT)
329  {
330    if (likely(this->parent != NULL))
331      this->relCoordinate = absCoord - parent->getAbsCoor2D ();
332    else
333      this->relCoordinate = absCoord;
334  }
335
336  this->bRelCoorChanged = true;
337}
338
339/**
340 * @param x x-coordinate.
341 * @param y y-coordinate.
342 * @param z z-coordinate.
343 * @see void PNode::setAbsCoor (const Vector& absCoord)
344 */
345void Element2D::setAbsCoor2D (float x, float y, float depth)
346{
347  this->setAbsCoor2D(Vector(x, y, depth));
348}
349
350/**
351 * @param x x-coordinate in Pixels
352 * @param y y-coordinate in Pixels
353 * @see void PNode::setAbsCoor (const Vector& absCoord)
354 */
355void Element2D::setAbsCoor2Dpx (int x, int y)
356{
357  this->setAbsCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
358                     (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
359                     0
360                           ));
361}
362
363/**
364 * @param absCoordSoft set absolute coordinate
365 * @param bias how fast to iterato to the new Coordinate
366 */
367void Element2D::setAbsCoorSoft2D (const Vector& absCoordSoft, float bias)
368{
369  if (this->toCoordinate == NULL)
370    this->toCoordinate = new Vector();
371
372  if( likely(this->parentMode & E2D_PARENT_MOVEMENT))
373  {
374    /* if you have set the absolute coordinates this overrides all other changes */
375    if (likely(this->parent != NULL))
376      *this->toCoordinate = absCoordSoft - parent->getAbsCoor2D ();
377    else
378      *this->toCoordinate = absCoordSoft;
379  }
380  if( this->parentMode & E2D_PARENT_ROTATE_MOVEMENT)
381  {
382    if (likely(this->parent != NULL))
383      *this->toCoordinate = absCoordSoft - parent->getAbsCoor2D ();
384    else
385      *this->toCoordinate = absCoordSoft;
386  }
387
388  this->bias = bias;
389}
390
391/**
392 * @param x x-coordinate.
393 * @param y y-coordinate.
394 * @param z z-coordinate.
395 * @see void PNode::setAbsCoor (const Vector& absCoord)
396 */
397void Element2D::setAbsCoorSoft2D (float x, float y, float depth, float bias)
398{
399  this->setAbsCoorSoft2D(Vector(x, y, depth), bias);
400}
401
402/**
403 *  shift coordinate ralative
404 * @param shift shift vector
405 *
406 * This simply adds the shift-Vector to the relative Coordinate
407 */
408void Element2D::shiftCoor2D (const Vector& shift)
409{
410  this->relCoordinate += shift;
411  this->bRelCoorChanged = true;
412
413}
414
415/**
416 * shifts in PixelSpace
417 * @param x the pixels to shift in X
418 * @param y the pixels to shift in Y
419 */
420void Element2D::shiftCoor2Dpx (int x, int y)
421{
422  this->shiftCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
423                    (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
424                     0));
425}
426
427/**
428 *  set relative direction
429 * @param relDir to its parent
430 */
431void Element2D::setRelDir2D (float relDir)
432{
433  if (this->toDirection!= NULL)
434  {
435    delete this->toDirection;
436    this->toDirection = NULL;
437  }
438
439  this->relDirection = relDir;
440  this->bRelDirChanged = true;
441}
442
443/**
444 * sets the Relative Direction of this node to its parent in a Smoothed way
445 * @param relDirSoft the direction to iterate to smoothely.
446 * @param bias how fast to iterate to the new Direction
447 */
448void Element2D::setRelDirSoft2D(float relDirSoft, float bias)
449{
450  if (likely(this->toDirection == NULL))
451    this->toDirection = new float;
452
453  *this->toDirection = relDirSoft;
454  this->bias = bias;
455}
456
457/**
458 *  sets the absolute direction
459 * @param absDir absolute coordinates
460 */
461void Element2D::setAbsDir2D (float absDir)
462{
463  if (this->toDirection!= NULL)
464  {
465    delete this->toDirection;
466    this->toDirection = NULL;
467  }
468
469  if (likely(this->parent != NULL))
470    this->relDirection = absDir - this->parent->getAbsDir2D();
471  else
472    this->relDirection = absDir;
473
474  this->bRelDirChanged = true;
475}
476
477/**
478 *  sets the absolute direction softly
479 * @param absDir absolute coordinates
480 */
481void Element2D::setAbsDirSoft2D (float absDirSoft, float bias)
482{
483  if (this->toDirection == NULL)
484    this->toDirection = new float;
485
486  if (likely(this->parent != NULL))
487    *this->toDirection = absDirSoft - this->parent->getAbsDir2D();
488  else
489    *this->toDirection = absDirSoft;
490
491  this->bias = bias;
492}
493
494/**
495 * shift Direction
496 * @param shift the direction around which to shift.
497 */
498void Element2D::shiftDir2D (float shiftDir)
499{
500  this->relDirection = this->relDirection + shiftDir;
501  this->bRelDirChanged = true;
502}
503
504/**
505 *  adds a child and makes this node to a parent
506 * @param child child reference
507 * @param parentMode on which changes the child should also change ist state
508 *
509 * use this to add a child to this node.
510 */
511void Element2D::addChild2D (Element2D* child)
512{
513  if( likely(child->parent != NULL))
514  {
515    PRINTF(5)("Element2D::addChild() - reparenting node: removing it and adding it again\n");
516    child->parent->eraseChild(child);
517  }
518  child->parent = this;
519  if (likely(this != NULL))
520  {
521    // ELEMENT SORTING TO LAYERS  //
522    unsigned int childCount = this->children.size();
523
524    list<Element2D*>::iterator elem;
525    for (elem = this->children.begin(); elem != this->children.end(); elem++)
526    {
527      if ((*elem)->layer < child->layer)
528      {
529        this->children.insert(elem, child);
530        break;
531      }
532    }
533
534    if (childCount == this->children.size())
535      this->children.push_back(child);
536    ////////////////////////////////
537    if (unlikely(this->layer > child->getLayer()))
538    {
539      PRINTF(2)("Layer '%s' of Child(%s) lower than parents(%s) layer '%s'. updating...\n",
540      Element2D::layer2DToChar(child->getLayer()),child->getName(), this->getName(), Element2D::layer2DToChar(this->layer));
541      child->setLayer(this->layer);
542    }
543  }
544  child->parentCoorChanged();
545}
546
547/**
548 * @see Element2D::addChild(Element2D* child);
549 * @param childName the name of the child to add to this PNode
550 */
551void Element2D::addChild2D (const char* childName)
552{
553  Element2D* childNode = dynamic_cast<Element2D*>(ClassList::getObject(childName, CL_ELEMENT_2D));
554  if (childNode != NULL)
555    this->addChild2D(childNode);
556}
557
558/**
559 * removes a child from the node
560 * @param child the child to remove from this Node..
561 *
562 * Children from nodes will not be lost, they are referenced to NullPointer
563 */
564void Element2D::removeChild2D (Element2D* child)
565{
566  if (child != NULL)
567    child->remove2D();
568}
569
570/**
571 * remove this Element from the tree and adds all children to NullElement2D
572 *
573 * afterwards this Node is free, and can be reattached, or deleted freely.
574 */
575void Element2D::remove2D()
576{
577  list<Element2D*>::iterator child;
578  for (child = this->children.begin(); child != this->children.end(); child++)
579    NullElement2D::getInstance()->addChild2D(*child);
580
581  this->children.clear();
582
583  if (this->parent != NULL)
584  {
585    this->parent->eraseChild(this);
586    this->parent = NULL;
587  }
588}
589
590/**
591 * sets the parent of this Element2D
592 * @param parent the Parent to set
593 */
594void Element2D::setParent2D (Element2D* parent)
595{
596  parent->addChild2D(this);
597}
598
599/**
600 * @see Element2D::setParent(Element2D* parent);
601 * @param parentName the name of the Parent to set to this Element2D
602 */
603void Element2D::setParent2D (const char* parentName)
604{
605  Element2D* parentNode = dynamic_cast<Element2D*>(ClassList::getObject(parentName, CL_ELEMENT_2D));
606  if (parentNode != NULL)
607    parentNode->addChild2D(this);
608
609}
610
611/**
612 * does the reparenting in a very smooth way
613 * @param parentNode the new Node to connect this node to.
614 * @param bias the speed to iterate to this new Positions
615 */
616void Element2D::setParentSoft2D(Element2D* parentNode, float bias)
617{
618  if (this->parent == parentNode)
619    return;
620
621  if (likely(this->toCoordinate == NULL))
622  {
623    this->toCoordinate = new Vector();
624    *this->toCoordinate = this->getRelCoor2D();
625  }
626  if (likely(this->toDirection == NULL))
627  {
628    this->toDirection = new float;
629    *this->toDirection = this->getRelDir2D();
630  }
631  this->bias = bias;
632
633
634  Vector tmpV = this->getAbsCoor2D();
635  float tmpQ = this->getAbsDir2D();
636
637  parentNode->addChild2D(this);
638
639  if (this->parentMode & PNODE_ROTATE_MOVEMENT) //! @todo implement this.
640    ;//this->setRelCoor(this->parent->getAbsDir().inverse().apply(tmpV - this->parent->getAbsCoor()));
641  else
642    this->relCoordinate = (tmpV - parentNode->getAbsCoor2D());
643  this->bRelCoorChanged = true;
644
645  this->relDirection = (tmpQ - parentNode->getAbsDir2D());
646  this->bRelDirChanged = true;
647}
648
649/**
650 * does the reparenting in a very smooth way
651 * @param parentName the name of the Parent to reconnect to
652 * @param bias the speed to iterate to this new Positions
653 */
654void Element2D::setParentSoft2D(const char* parentName, float bias)
655{
656  Element2D* parentNode = dynamic_cast<Element2D*>(ClassList::getObject(parentName, CL_ELEMENT_2D));
657  if (parentNode != NULL)
658    this->setParentSoft2D(parentNode, bias);
659}
660
661/** @param child the child to be erased from this Nodes List */
662void Element2D::eraseChild(Element2D* child)
663{
664  std::list<Element2D*>::iterator childIT = std::find(this->children.begin(), this->children.end(), child);
665  this->children.erase(childIT);
666}
667
668/**
669 *  sets the mode of this parent manually
670 * @param parentMode a String representing this parentingMode
671 */
672void Element2D::setParentMode2D (const char* parentingMode)
673{
674  this->setParentMode2D(Element2D::charToParentingMode2D(parentingMode));
675}
676
677/**
678 *  updates the absCoordinate/absDirection
679 * @param dt The time passed since the last update
680
681   this is used to go through the parent-tree to update all the absolute coordinates
682   and directions. this update should be done by the engine, so you don't have to
683   worry, normaly...
684 */
685void Element2D::update2D (float dt)
686{
687  // setting the Position of this 2D-Element.
688  if( likely(this->parent != NULL))
689  {
690      // movement for nodes with smoothMove enabled
691    if (unlikely(this->toCoordinate != NULL))
692    {
693      Vector moveVect = (*this->toCoordinate - this->relCoordinate) *fabsf(dt)*bias;
694
695      if (likely(moveVect.len() >= .001))//PNODE_ITERATION_DELTA))
696      {
697        this->shiftCoor2D(moveVect);
698      }
699      else
700      {
701        Vector tmp = *this->toCoordinate;
702        this->setRelCoor2D(tmp);
703        PRINTF(5)("SmoothMove of %s finished\n", this->getName());
704      }
705    }
706    if (unlikely(this->toDirection != NULL))
707    {
708      float rotFlot = (*this->toDirection - this->relDirection) *fabsf(dt)*bias;
709      if (likely(fabsf(rotFlot) >= .001))//PNODE_ITERATION_DELTA))
710      {
711        this->shiftDir2D(rotFlot);
712      }
713      else
714      {
715        float tmp = *this->toDirection;
716        this->setRelDir2D(tmp);
717        PRINTF(5)("SmoothRotate of %s finished\n", this->getName());
718      }
719    }
720
721    // MAIN UPDATE /////////////////////////////////////
722    this->lastAbsCoordinate = this->absCoordinate;
723
724    PRINTF(5)("Element2D::update - %s - (%f, %f, %f)\n", this->getName(), this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
725
726
727    if( this->parentMode & E2D_PARENT_LOCAL_ROTATE && this->bRelDirChanged)
728    {
729      /* update the current absDirection - remember * means rotation around sth.*/
730      this->prevRelDirection = this->relDirection;
731      this->absDirection = this->relDirection + parent->getAbsDir2D();;
732    }
733
734
735    if (unlikely(this->alignment & E2D_ALIGN_SCREEN_CENTER && this->bRelCoorChanged))
736    {
737      this->prevRelCoordinate = this->relCoordinate;
738      this->absCoordinate.x = .5 + this->relCoordinate.x;
739      this->absCoordinate.y = .5 + this->relCoordinate.y;
740      this->absCoordinate.z = 0.0;
741    }
742    else if (unlikely(this->bindNode != NULL))
743    {
744      GLdouble projectPos[3] = {0, 0, 0};
745      gluProject(this->bindNode->getAbsCoor().x,
746                 this->bindNode->getAbsCoor().y,
747                 this->bindNode->getAbsCoor().z,
748                 GraphicsEngine::modMat,
749                 GraphicsEngine::projMat,
750                 GraphicsEngine::viewPort,
751                 projectPos,
752                 projectPos+1,
753                 projectPos+2);
754      this->prevRelCoordinate.x = this->absCoordinate.x = projectPos[0] /* /(float)GraphicsEngine::getInstance()->getResolutionX() */ + this->relCoordinate.x;
755      this->prevRelCoordinate.y = this->absCoordinate.y = (float)GraphicsEngine::getInstance()->getResolutionY() -  projectPos[1] + this->relCoordinate.y;
756      this->prevRelCoordinate.z = this->absCoordinate.z = projectPos[2] + this->relCoordinate.z;
757      this->bRelCoorChanged = true;
758    }
759    else
760    {
761      if(likely(this->parentMode & PNODE_MOVEMENT && this->bRelCoorChanged))
762      {
763        /* update the current absCoordinate */
764        this->prevRelCoordinate = this->relCoordinate;
765        this->absCoordinate = this->parent->getAbsCoor2D() + this->relCoordinate;
766      }
767      else if( this->parentMode & PNODE_ROTATE_MOVEMENT && this->bRelCoorChanged)
768      {
769        /* update the current absCoordinate */
770        this->prevRelCoordinate = this->relCoordinate;
771        float sine = sin(this->parent->getAbsDir2D());
772        float cose = cos(this->parent->getAbsDir2D());
773//        this->absCoordinate.x = this->relCoordinate.x*cose - this->relCoordinate.y*sine + this->parent->getRelCoor2D().x*(1-cose) +this->parent->getRelCoor2D().y*sine;
774//        this->absCoordinate.y = this->relCoordinate.x*sine + this->relCoordinate.y*cose + this->parent->getRelCoor2D().y*(1-cose) +this->parent->getRelCoor2D().x*sine;
775
776        this->absCoordinate.x = this->parent->getAbsCoor2D().x + (this->relCoordinate.x*cos(this->parent->getAbsDir2D()) - this->relCoordinate.y * sin(this->parent->getAbsDir2D()));
777        this->absCoordinate.y = this->parent->getAbsCoor2D().y + (this->relCoordinate.x*sin(this->parent->getAbsDir2D()) + this->relCoordinate.y * cos(this->parent->getAbsDir2D()));
778
779      }
780    }
781    /////////////////////////////////////////////////
782  }
783  else
784  {
785    PRINTF(5)("Element2D::update - (%f, %f, %f)\n", this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
786    if (this->bRelCoorChanged)
787    {
788      this->prevRelCoordinate = this->relCoordinate;
789      this->absCoordinate = this->relCoordinate;
790    }
791    if (this->bRelDirChanged)
792    {
793      this->prevRelDirection = this->relDirection;
794      this->absDirection = this->getAbsDir2D() + this->relDirection;
795    }
796  }
797
798
799  // UPDATE CHILDREN
800  if(this->children.size() > 0)
801  {
802    list<Element2D*>::iterator child;
803    for (child = this->children.begin(); child != this->children.end(); child++)
804    {
805      /* if this node has changed, make sure, that all children are updated also */
806      if( likely(this->bRelCoorChanged))
807        (*child)->parentCoorChanged ();
808      if( likely(this->bRelDirChanged))
809        (*child)->parentDirChanged ();
810
811      (*child)->update2D(dt);
812    }
813  }
814
815  // FINISHING PROCESS
816  this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
817  this->bRelCoorChanged = false;
818  this->bRelDirChanged = false;
819}
820
821/**
822 *  displays some information about this pNode
823 * @param depth The deph into which to debug the children of this Element2D to.
824 * (0: all children will be debugged, 1: only this Element2D, 2: this and direct children...)
825 * @param level The n-th level of the Node we draw (this is internal and only for nice output)
826 */
827void Element2D::debug (unsigned int depth, unsigned int level) const
828{
829  for (unsigned int i = 0; i < level; i++)
830    PRINT(0)(" |");
831  if (this->children.size() > 0)
832    PRINT(0)(" +");
833  else
834    PRINT(0)(" -");
835  PRINT(0)("Element2D(%s::%s) - absCoord: (%0.2f, %0.2f), relCoord(%0.2f, %0.2f), direction(%0.2f) - %s, layer:%s\n",
836            this->getClassName(),
837            this->getName(),
838            this->absCoordinate.x,
839            this->absCoordinate.y,
840            this->relCoordinate.x,
841            this->relCoordinate.y,
842            this->getAbsDir2D(),
843            Element2D::parentingModeToChar2D(parentMode),
844            Element2D::layer2DToChar(this->layer));
845
846  if (depth >= 2 || depth == 0)
847  {
848    list<Element2D*>::const_iterator child;
849    for (child = this->children.begin(); child != this->children.end(); child++)
850    {
851      if (depth == 0)
852        (*child)->debug(0, level + 1);
853      else
854        (*child)->debug(depth - 1, level +1);
855    }
856  }
857}
858
859/**
860 * ticks the 2d-Element
861 * @param dt the time elapsed since the last tick
862 *
863 * the element only gets tickt, if it is active.
864 * Be aware, that this walks through the entire Element2D-tree,
865 * searching for Elements to be ticked.
866 */
867void Element2D::tick2D(float dt)
868{
869  if (this->active)
870    this->tick(dt);
871  if (this->children.size() > 0)
872  {
873    list<Element2D*>::iterator child;
874    for (child = this->children.begin(); child != this->children.end(); child++)
875      (*child)->tick2D(dt);
876  }
877}
878
879/**
880 * draws all the Elements from this element2D downwards
881 * @param layer the maximal Layer to draw. @see E2D_LAYER
882 */
883void Element2D::draw2D(short layer) const
884{
885  if (this->visible)
886    this->draw();
887  if (this->children.size() > 0)
888  {
889    list<Element2D*>::const_iterator child;
890    for (child = this->children.begin(); child != this->children.end(); child++)
891      if (likely(layer >= this->layer))
892        (*child)->draw2D(layer);
893  }
894}
895
896/**
897 * displays the Element2D at its position with its rotation as a Plane.
898 */
899void Element2D::debugDraw2D(unsigned int depth, float size, Vector color, unsigned int level) const
900{
901  if (level == 0)
902  {
903    glPushAttrib(GL_ENABLE_BIT);
904    glMatrixMode(GL_MODELVIEW);
905
906    glDisable(GL_LIGHTING);
907    glDisable(GL_BLEND);
908    glDisable(GL_TEXTURE_2D);
909  }
910
911  glPushMatrix();
912  /* translate */
913  /* rotate */
914  glColor3f(color.x, color.y, color.z);
915
916  glTranslatef (this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
917  glRotatef(this->getAbsDir2D(), 0,0,1);
918  glBegin(GL_LINE_LOOP);
919  glVertex2f(0, 0);
920  glVertex2f(0, +this->getSizeY2D());
921  glVertex2f(+this->getSizeX2D(), +this->getSizeY2D());
922  glVertex2f(+this->getSizeX2D(), 0);
923  glEnd();
924
925
926  glPopMatrix();
927  if (depth >= 2 || depth == 0)
928  {
929    Vector childColor =  Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(20,0,.0));
930    list<Element2D*>::const_iterator child;
931    for (child = this->children.begin(); child != this->children.end(); child++)
932    {
933      // drawing the Dependency graph
934      if (this != NullElement2D::getInstance())
935      {
936        glBegin(GL_LINES);
937        glColor3f(color.x, color.y, color.z);
938        glVertex3f(this->getAbsCoor2D ().x,
939                   this->getAbsCoor2D ().y,
940                   0);
941        glColor3f(childColor.x, childColor.y, childColor.z);
942        glVertex3f((*child)->getAbsCoor2D ().x,
943                   (*child)->getAbsCoor2D ().y,
944                   0);
945        glEnd();
946      }
947      if (depth == 0)
948        (*child)->debugDraw2D(0, size, childColor, level+1);
949      else
950        (*child)->debugDraw2D(depth - 1, size, childColor, level +1);
951    }
952  }
953  if (level == 0)
954    glPopAttrib();
955
956}
957
958
959// helper functions //
960/**
961 * converts a parentingMode into a string that is the name of it
962 * @param parentingMode the ParentingMode to convert
963 * @return the converted string
964 */
965const char* Element2D::parentingModeToChar2D(int parentingMode)
966{
967  if (parentingMode == E2D_PARENT_LOCAL_ROTATE)
968    return "local-rotate";
969  else if (parentingMode == E2D_PARENT_ROTATE_MOVEMENT)
970    return "rotate-movement";
971  else if (parentingMode == E2D_PARENT_MOVEMENT)
972    return "movement";
973  else if (parentingMode == E2D_PARENT_ALL)
974    return "all";
975  else if (parentingMode == E2D_PARENT_ROTATE_AND_MOVE)
976    return "rotate-and-move";
977}
978
979/**
980 * converts a parenting-mode-string into a int
981 * @param parentingMode the string naming the parentingMode
982 * @return the int corresponding to the named parentingMode
983 */
984E2D_PARENT_MODE Element2D::charToParentingMode2D(const char* parentingMode)
985{
986  if (!strcmp(parentingMode, "local-rotate"))
987    return (E2D_PARENT_LOCAL_ROTATE);
988  else  if (!strcmp(parentingMode, "rotate-movement"))
989    return (E2D_PARENT_ROTATE_MOVEMENT);
990  else  if (!strcmp(parentingMode, "movement"))
991    return (E2D_PARENT_MOVEMENT);
992  else  if (!strcmp(parentingMode, "all"))
993    return (E2D_PARENT_ALL);
994  else  if (!strcmp(parentingMode, "rotate-and-move"))
995    return (E2D_PARENT_ROTATE_AND_MOVE);
996}
997
998/**
999 * converts a layer into its corresponding string
1000 * @param layer the layer to get the name-String of.
1001 * @returns the Name of the Layer (on error the default-layer-string is returned)
1002 */
1003const char* Element2D::layer2DToChar(E2D_LAYER layer)
1004{
1005  switch(layer)
1006  {
1007    case E2D_LAYER_TOP:
1008      return "top";
1009      break;
1010    case E2D_LAYER_MEDIUM:
1011      return "medium";
1012      break;
1013    case E2D_LAYER_BOTTOM:
1014      return "bottom";
1015      break;
1016    case E2D_LAYER_BELOW_ALL:
1017      return "below-all";
1018      break;
1019    default:
1020      return layer2DToChar(E2D_DEFAULT_LAYER);
1021      break;
1022  }
1023}
1024
1025/**
1026 * converts a String holding a actual Layer
1027 * @param layer the String to convert into a Layer2D
1028 * @returns the E2D_LAYER on success, E2D_DEFAULT_LAYER on error.
1029 */
1030E2D_LAYER Element2D::charToLayer2D(const char* layer)
1031{
1032  if (!strcmp(layer, "top"))
1033    return (E2D_LAYER_TOP);
1034  else  if (!strcmp(layer, "medium"))
1035    return (E2D_LAYER_MEDIUM);
1036  else  if (!strcmp(layer, "bottom"))
1037    return (E2D_LAYER_BOTTOM);
1038  else  if (!strcmp(layer, "below-all"))
1039    return (E2D_LAYER_BELOW_ALL);
1040  else
1041    return (E2D_DEFAULT_LAYER);
1042}
1043
1044
1045
1046
1047///////////////////
1048// NullElement2D //
1049///////////////////
1050NullElement2D* NullElement2D::singletonRef = 0;
1051
1052/**
1053 *  creates the one and only NullElement2D
1054 * @param absCoordinate the cordinate of the Parent (normally Vector(0,0,0))
1055 */
1056NullElement2D::NullElement2D () : Element2D(NULL, E2D_LAYER_BELOW_ALL)
1057{
1058  this->setClassID(CL_NULL_ELEMENT_2D, "NullElement2D");
1059  this->setName("NullElement2D");
1060
1061  this->setParentMode2D(E2D_PARENT_ALL);
1062  NullElement2D::singletonRef = this;
1063}
1064
1065
1066/**
1067 *  standard deconstructor
1068 */
1069NullElement2D::~NullElement2D ()
1070{
1071  NullElement2D::singletonRef = NULL;
1072}
Note: See TracBrowser for help on using the repository browser.