Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6257 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
RevLine 
[4744]1/*
[1853]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.
[1855]10
11   ### File Specific:
[4838]12   main-programmer: Benjamin Grauer
[1855]13   co-programmer: ...
[1853]14*/
15
[3955]16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
[1853]17
[4839]18#include "element_2d.h"
[4840]19#include "render_2d.h"
[1853]20
[6142]21#include <algorithm>
22
[5775]23#include "p_node.h"
24
[4843]25#include "graphics_engine.h"
[4858]26#include "load_param.h"
[5944]27#include "parser/tinyxml/tinyxml.h"
[4858]28#include "class_list.h"
[5775]29
[5285]30#include "color.h"
[4843]31
[1856]32using namespace std;
[1853]33
[5285]34/**
35 * standard constructor
36 */
[5089]37Element2D::Element2D()
38{
39  this->init();
40  this->setParent2D(NullElement2D::getInstance());
41}
[1856]42
[3245]43/**
[4838]44 * standard constructor
[5285]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 */
[5402]50Element2D::Element2D (Element2D* parent, E2D_LAYER layer)
[3365]51{
[5089]52  this->init();
[5402]53  this->layer = layer;
[5286]54  // check Parenting, and if ok parent the stuff
[5089]55  if (this->parent != NULL)
56    this->setParent2D(parent);
[5285]57  else if (NullElement2D::isInstanciated())
58    this->setParent2D(NullElement2D::getInstance());
[3365]59}
[1853]60
[3245]61/**
[4838]62 * standard deconstructor
[5285]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:
[5401]72 *    moves its children to the NullElement2D
[5285]73 *    then deletes the Element.
74 */
[4838]75Element2D::~Element2D ()
[3543]76{
[5285]77  // remove the Node, delete it's children.
[5778]78  while (this->children.size() > 0)
79  {
80    Element2D* child = this->children.front();
81    this->children.pop_front();
82    delete child;
83  }
[5285]84  if (this->parent != NULL)
85  {
[6142]86    this->parent->eraseChild(this);
[5285]87    this->parent = NULL;
88  }
[5089]89
[5285]90  // remove all other allocated memory.
[5088]91  if (this->toCoordinate != NULL)
92    delete this->toCoordinate;
93  if (this->toDirection != NULL)
94    delete this->toDirection;
[3543]95}
[4843]96
97
[4858]98/**
99 * initializes a Element2D
100 */
[5089]101void Element2D::init()
[4847]102{
103  this->setClassID(CL_ELEMENT_2D, "Element2D");
104
[4861]105  this->setVisibility(true);
[5068]106  this->setActiveness(true);
[4861]107  this->setAlignment(E2D_ALIGN_NONE);
[5398]108  this->layer = E2D_DEFAULT_LAYER;
[5089]109  this->bindNode = NULL;
[5084]110
[5252]111  this->setParentMode2D(E2D_PARENT_ALL);
112  this->parent = NULL;
[5211]113  this->absDirection = 0.0;
[5089]114  this->relDirection = 0.0;
[5082]115  this->bRelCoorChanged = true;
116  this->bRelDirChanged = true;
[5088]117  this->toCoordinate = NULL;
118  this->toDirection = NULL;
[5378]119  this->setSize2D(1,1);
[4847]120}
121
[4843]122/**
[4858]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{
[5402]128  // ELEMENT2D-native settings.
[5671]129  LoadParam(root, "alignment", this, Element2D, setAlignment)
[4858]130      .describe("loads the alignment: (either: center, left, right or screen-center)");
131
[5671]132  LoadParam(root, "layer", this, Element2D, setLayer)
[4858]133      .describe("loads the layer onto which to project: (either: top, medium, bottom, below-all)");
134
[5671]135  LoadParam(root, "bind-node", this, Element2D, setBindNode)
[4858]136      .describe("sets a node, this 2D-Element should be shown upon (name of the node)");
137
[5671]138  LoadParam(root, "visibility", this, Element2D, setVisibility)
[4860]139      .describe("if the Element is visible or not");
[5089]140
141
[5402]142// PNode-style:
[5671]143  LoadParam(root, "rel-coor", this, Element2D, setRelCoor2D)
[5091]144      .describe("Sets The relative position of the Node to its parent.");
145
[5671]146  LoadParam(root, "abs-coor", this, Element2D, setAbsCoor2D)
[5091]147      .describe("Sets The absolute Position of the Node.");
148
[5671]149  LoadParam(root, "rel-dir", this, Element2D, setRelDir2D)
[5091]150      .describe("Sets The relative rotation of the Node to its parent.");
151
[5671]152  LoadParam(root, "abs-dir", this, Element2D, setAbsDir2D)
[5091]153      .describe("Sets The absolute rotation of the Node.");
154
[5671]155  LoadParam(root, "parent", this, Element2D, setParent2D)
[5091]156      .describe("the Name of the Parent of this Element2D");
157
[5671]158  LoadParam(root, "parent-mode", this, Element2D, setParentMode2D)
[5091]159      .describe("the mode to connect this node to its parent ()");
160
161  // cycling properties
162  if (root != NULL)
163  {
[5654]164    LOAD_PARAM_START_CYCLE(root, element);
[5091]165    {
[5654]166      LoadParam_CYCLE(element, "parent", this, Element2D, addChild2D)
[5091]167          .describe("adds a new Child to the current Node.");
168    }
[5654]169    LOAD_PARAM_END_CYCLE(element);
[5091]170  }
[4858]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
[4862]189
[4858]190/**
[4862]191 * moves a Element to another layer
192 * @param layer the Layer this is drawn on
193 */
194void Element2D::setLayer(E2D_LAYER layer)
195{
[5402]196  if (this->parent != NULL && this->parent->getLayer() > layer)
197  {
[5403]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()));
[5402]203    layer = this->parent->getLayer();
204  }
[4862]205  this->layer = layer;
206}
207
208/**
[4858]209 * sets the layer onto which this 2D-element is projected to.
[5401]210 * @param layer the layer @see loadParams @see Element2D::charToLayer2D(const char* layer)
[4858]211 */
212void Element2D::setLayer(const char* layer)
213{
[5401]214  this->setLayer(Element2D::charToLayer2D(layer));
[4858]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
[5091]229/**
230 * sets the relative coordinate of the Element2D to its parent
231 * @param relCoord the relative coordinate to the parent
232 */
[5081]233void Element2D::setRelCoor2D (const Vector& relCoord)
234{
[5113]235  if (this->toCoordinate!= NULL)
236  {
237    delete this->toCoordinate;
238    this->toCoordinate = NULL;
239  }
[5082]240  this->relCoordinate = relCoord;
241  this->bRelCoorChanged = true;
[5081]242}
243
244
[5091]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 */
[5081]251void Element2D::setRelCoor2D (float x, float y, float z)
252{
[5113]253  this->setRelCoor2D(Vector(x,y,z));
[5081]254}
255
[5091]256/**
257 * sets the Relative coordinate to the parent in Pixels
258 * @param x the relCoord X
259 * @param y the relCoord Y
260 */
[5089]261void Element2D::setRelCoor2Dpx (int x, int y)
262{
[5090]263  this->setRelCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
264                     (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
[5089]265                     0
266                           ));
267}
268
[5091]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 */
[5081]274void Element2D::setRelCoorSoft2D(const Vector& relCoordSoft, float bias)
275{
[5082]276  if (likely(this->toCoordinate == NULL))
277    this->toCoordinate = new Vector();
278
279  *this->toCoordinate = relCoordSoft;
280  this->bias = bias;
[5081]281}
282
[5091]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 */
[5089]289void Element2D::setRelCoorSoft2Dpx (int x, int y, float bias)
290{
[5090]291  this->setRelCoorSoft2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
292                         (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
[5089]293                         0),
294                         bias);
295}
296
[5091]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 */
[5082]304void Element2D::setRelCoorSoft2D(float x, float y, float depth, float bias)
[5081]305{
[5082]306  this->setRelCoorSoft2D(Vector(x, y, depth), bias);
[5081]307}
308
[5091]309/**
310 * @param absCoord set absolute coordinate
311 */
[5081]312void Element2D::setAbsCoor2D (const Vector& absCoord)
313{
[5113]314  if (this->toCoordinate!= NULL)
315  {
316    delete this->toCoordinate;
317    this->toCoordinate = NULL;
318  }
319
[5082]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;
[5081]337}
338
[5091]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 */
[5081]345void Element2D::setAbsCoor2D (float x, float y, float depth)
346{
[5082]347  this->setAbsCoor2D(Vector(x, y, depth));
[5081]348}
349
[5091]350/**
351 * @param x x-coordinate in Pixels
352 * @param y y-coordinate in Pixels
353 * @see void PNode::setAbsCoor (const Vector& absCoord)
354 */
[5089]355void Element2D::setAbsCoor2Dpx (int x, int y)
356{
[5090]357  this->setAbsCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
358                     (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
[5089]359                     0
360                           ));
361}
362
[5091]363/**
[5414]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/**
[5091]403 *  shift coordinate ralative
404 * @param shift shift vector
405 *
406 * This simply adds the shift-Vector to the relative Coordinate
407 */
[5083]408void Element2D::shiftCoor2D (const Vector& shift)
[5081]409{
[5082]410  this->relCoordinate += shift;
411  this->bRelCoorChanged = true;
412
[5081]413}
414
[5091]415/**
416 * shifts in PixelSpace
417 * @param x the pixels to shift in X
418 * @param y the pixels to shift in Y
419 */
[5089]420void Element2D::shiftCoor2Dpx (int x, int y)
421{
[5090]422  this->shiftCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
423                    (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
[5089]424                     0));
425}
426
[5091]427/**
428 *  set relative direction
429 * @param relDir to its parent
430 */
[5081]431void Element2D::setRelDir2D (float relDir)
432{
[5113]433  if (this->toDirection!= NULL)
434  {
435    delete this->toDirection;
436    this->toDirection = NULL;
437  }
438
[5082]439  this->relDirection = relDir;
440  this->bRelDirChanged = true;
[5081]441}
442
[5091]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 */
[5081]448void Element2D::setRelDirSoft2D(float relDirSoft, float bias)
449{
[5082]450  if (likely(this->toDirection == NULL))
451    this->toDirection = new float;
452
453  *this->toDirection = relDirSoft;
454  this->bias = bias;
[5081]455}
456
[5091]457/**
458 *  sets the absolute direction
459 * @param absDir absolute coordinates
460 */
[5081]461void Element2D::setAbsDir2D (float absDir)
462{
[5113]463  if (this->toDirection!= NULL)
464  {
465    delete this->toDirection;
466    this->toDirection = NULL;
467  }
468
[5082]469  if (likely(this->parent != NULL))
470    this->relDirection = absDir - this->parent->getAbsDir2D();
471  else
472    this->relDirection = absDir;
473
474  this->bRelDirChanged = true;
[5081]475}
476
[5091]477/**
[5414]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/**
[5091]495 * shift Direction
496 * @param shift the direction around which to shift.
497 */
[5083]498void Element2D::shiftDir2D (float shiftDir)
[5081]499{
[5082]500  this->relDirection = this->relDirection + shiftDir;
501  this->bRelDirChanged = true;
[5081]502}
503
[5091]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 */
[5403]511void Element2D::addChild2D (Element2D* child)
[5081]512{
[5082]513  if( likely(child->parent != NULL))
514  {
[5254]515    PRINTF(5)("Element2D::addChild() - reparenting node: removing it and adding it again\n");
[6142]516    child->parent->eraseChild(child);
[5082]517  }
518  child->parent = this;
[5397]519  if (likely(this != NULL))
[5402]520  {
[5403]521    // ELEMENT SORTING TO LAYERS  //
[5775]522    unsigned int childCount = this->children.size();
523
524    list<Element2D*>::iterator elem;
525    for (elem = this->children.begin(); elem != this->children.end(); elem++)
[5403]526    {
[5775]527      if ((*elem)->layer < child->layer)
[5403]528      {
[5775]529        this->children.insert(elem, child);
[5403]530        break;
531      }
532    }
[5775]533
534    if (childCount == this->children.size())
535      this->children.push_back(child);
[5403]536    ////////////////////////////////
[5402]537    if (unlikely(this->layer > child->getLayer()))
538    {
[5403]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));
[5402]541      child->setLayer(this->layer);
542    }
543  }
[5082]544  child->parentCoorChanged();
[5081]545}
546
[5091]547/**
548 * @see Element2D::addChild(Element2D* child);
549 * @param childName the name of the child to add to this PNode
550 */
[5081]551void Element2D::addChild2D (const char* childName)
552{
[5082]553  Element2D* childNode = dynamic_cast<Element2D*>(ClassList::getObject(childName, CL_ELEMENT_2D));
554  if (childNode != NULL)
555    this->addChild2D(childNode);
[5081]556}
557
[5091]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 */
[5081]564void Element2D::removeChild2D (Element2D* child)
565{
[5212]566  if (child != NULL)
567    child->remove2D();
[5081]568}
569
[5091]570/**
[5285]571 * remove this Element from the tree and adds all children to NullElement2D
[5091]572 *
[5285]573 * afterwards this Node is free, and can be reattached, or deleted freely.
[5091]574 */
[5081]575void Element2D::remove2D()
576{
[5775]577  list<Element2D*>::iterator child;
578  for (child = this->children.begin(); child != this->children.end(); child++)
579    NullElement2D::getInstance()->addChild2D(*child);
[5082]580
[5783]581  this->children.clear();
[5285]582
[5214]583  if (this->parent != NULL)
[5285]584  {
[6142]585    this->parent->eraseChild(this);
[5285]586    this->parent = NULL;
587  }
[5081]588}
589
[5091]590/**
591 * sets the parent of this Element2D
592 * @param parent the Parent to set
593 */
[5081]594void Element2D::setParent2D (Element2D* parent)
595{
[5252]596  parent->addChild2D(this);
[5081]597}
598
[5091]599/**
600 * @see Element2D::setParent(Element2D* parent);
601 * @param parentName the name of the Parent to set to this Element2D
602 */
[5081]603void Element2D::setParent2D (const char* parentName)
604{
[5082]605  Element2D* parentNode = dynamic_cast<Element2D*>(ClassList::getObject(parentName, CL_ELEMENT_2D));
606  if (parentNode != NULL)
607    parentNode->addChild2D(this);
[5252]608
[5081]609}
610
[5091]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 */
[5382]616void Element2D::setParentSoft2D(Element2D* parentNode, float bias)
[5081]617{
[5082]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
[5382]639  if (this->parentMode & PNODE_ROTATE_MOVEMENT) //! @todo implement this.
[5082]640    ;//this->setRelCoor(this->parent->getAbsDir().inverse().apply(tmpV - this->parent->getAbsCoor()));
641  else
[5382]642    this->relCoordinate = (tmpV - parentNode->getAbsCoor2D());
643  this->bRelCoorChanged = true;
[5082]644
[5382]645  this->relDirection = (tmpQ - parentNode->getAbsDir2D());
646  this->bRelDirChanged = true;
[5081]647}
648
[5091]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 */
[5382]654void Element2D::setParentSoft2D(const char* parentName, float bias)
[5081]655{
[5082]656  Element2D* parentNode = dynamic_cast<Element2D*>(ClassList::getObject(parentName, CL_ELEMENT_2D));
657  if (parentNode != NULL)
[5382]658    this->setParentSoft2D(parentNode, bias);
[5081]659}
660
[6142]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
[5091]668/**
669 *  sets the mode of this parent manually
670 * @param parentMode a String representing this parentingMode
671 */
[5081]672void Element2D::setParentMode2D (const char* parentingMode)
673{
[5082]674  this->setParentMode2D(Element2D::charToParentingMode2D(parentingMode));
[5081]675}
676
[5091]677/**
678 *  updates the absCoordinate/absDirection
679 * @param dt The time passed since the last update
[5081]680
[5091]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 */
[5081]685void Element2D::update2D (float dt)
686{
[5089]687  // setting the Position of this 2D-Element.
[5083]688  if( likely(this->parent != NULL))
689  {
690      // movement for nodes with smoothMove enabled
691    if (unlikely(this->toCoordinate != NULL))
692    {
[5376]693      Vector moveVect = (*this->toCoordinate - this->relCoordinate) *fabsf(dt)*bias;
[5082]694
[5083]695      if (likely(moveVect.len() >= .001))//PNODE_ITERATION_DELTA))
696      {
697        this->shiftCoor2D(moveVect);
698      }
699      else
700      {
[5377]701        Vector tmp = *this->toCoordinate;
702        this->setRelCoor2D(tmp);
[5083]703        PRINTF(5)("SmoothMove of %s finished\n", this->getName());
704      }
705    }
706    if (unlikely(this->toDirection != NULL))
707    {
[5376]708      float rotFlot = (*this->toDirection - this->relDirection) *fabsf(dt)*bias;
709      if (likely(fabsf(rotFlot) >= .001))//PNODE_ITERATION_DELTA))
[5083]710      {
711        this->shiftDir2D(rotFlot);
712      }
713      else
714      {
[5377]715        float tmp = *this->toDirection;
716        this->setRelDir2D(tmp);
[5083]717        PRINTF(5)("SmoothRotate of %s finished\n", this->getName());
718      }
719    }
720
721    // MAIN UPDATE /////////////////////////////////////
722    this->lastAbsCoordinate = this->absCoordinate;
723
[5084]724    PRINTF(5)("Element2D::update - %s - (%f, %f, %f)\n", this->getName(), this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
[5083]725
726
[5118]727    if( this->parentMode & E2D_PARENT_LOCAL_ROTATE && this->bRelDirChanged)
[5083]728    {
729      /* update the current absDirection - remember * means rotation around sth.*/
[5090]730      this->prevRelDirection = this->relDirection;
[5083]731      this->absDirection = this->relDirection + parent->getAbsDir2D();;
732    }
733
[5089]734
[5397]735    if (unlikely(this->alignment & E2D_ALIGN_SCREEN_CENTER && this->bRelCoorChanged))
[5083]736    {
737      this->prevRelCoordinate = this->relCoordinate;
[5089]738      this->absCoordinate.x = .5 + this->relCoordinate.x;
739      this->absCoordinate.y = .5 + this->relCoordinate.y;
740      this->absCoordinate.z = 0.0;
[5083]741    }
[5397]742    else if (unlikely(this->bindNode != NULL))
[5083]743    {
[6142]744      GLdouble projectPos[3] = {0, 0, 0};
[5089]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);
[5396]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;
[5089]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;
[5090]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
[5089]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()));
[5083]778
[5089]779      }
[5083]780    }
781    /////////////////////////////////////////////////
782  }
783  else
784  {
[5084]785    PRINTF(5)("Element2D::update - (%f, %f, %f)\n", this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
[5083]786    if (this->bRelCoorChanged)
[5118]787    {
788      this->prevRelCoordinate = this->relCoordinate;
[5083]789      this->absCoordinate = this->relCoordinate;
[5118]790    }
[5083]791    if (this->bRelDirChanged)
[5118]792    {
793      this->prevRelDirection = this->relDirection;
[5376]794      this->absDirection = this->getAbsDir2D() + this->relDirection;
[5118]795    }
[5083]796  }
797
[5089]798
799  // UPDATE CHILDREN
[5775]800  if(this->children.size() > 0)
[5083]801  {
[5775]802    list<Element2D*>::iterator child;
803    for (child = this->children.begin(); child != this->children.end(); child++)
[5083]804    {
805      /* if this node has changed, make sure, that all children are updated also */
806      if( likely(this->bRelCoorChanged))
[5775]807        (*child)->parentCoorChanged ();
[5083]808      if( likely(this->bRelDirChanged))
[5775]809        (*child)->parentDirChanged ();
[5083]810
[5775]811      (*child)->update2D(dt);
[5083]812    }
813  }
[5089]814
815  // FINISHING PROCESS
[5083]816  this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
817  this->bRelCoorChanged = false;
818  this->bRelDirChanged = false;
[5081]819}
820
[5091]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 */
[5081]827void Element2D::debug (unsigned int depth, unsigned int level) const
828{
[5082]829  for (unsigned int i = 0; i < level; i++)
830    PRINT(0)(" |");
[5775]831  if (this->children.size() > 0)
[5082]832    PRINT(0)(" +");
833  else
834    PRINT(0)(" -");
[5401]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));
[5402]845
[5082]846  if (depth >= 2 || depth == 0)
847  {
[5775]848    list<Element2D*>::const_iterator child;
849    for (child = this->children.begin(); child != this->children.end(); child++)
[5082]850    {
851      if (depth == 0)
[5775]852        (*child)->debug(0, level + 1);
[5082]853      else
[5775]854        (*child)->debug(depth - 1, level +1);
[5082]855    }
856  }
[5081]857}
858
[5285]859/**
860 * ticks the 2d-Element
861 * @param dt the time elapsed since the last tick
[5401]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.
[5285]866 */
[5401]867void Element2D::tick2D(float dt)
[5285]868{
[5401]869  if (this->active)
870    this->tick(dt);
[5775]871  if (this->children.size() > 0)
[5401]872  {
[5775]873    list<Element2D*>::iterator child;
874    for (child = this->children.begin(); child != this->children.end(); child++)
875      (*child)->tick2D(dt);
[5401]876  }
877}
[5082]878
[5401]879/**
880 * draws all the Elements from this element2D downwards
[5404]881 * @param layer the maximal Layer to draw. @see E2D_LAYER
[5401]882 */
[5404]883void Element2D::draw2D(short layer) const
[5401]884{
885  if (this->visible)
886    this->draw();
[5775]887  if (this->children.size() > 0)
[5401]888  {
[5775]889    list<Element2D*>::const_iterator child;
890    for (child = this->children.begin(); child != this->children.end(); child++)
[5401]891      if (likely(layer >= this->layer))
[5775]892        (*child)->draw2D(layer);
[5401]893  }
[5285]894}
895
[5091]896/**
897 * displays the Element2D at its position with its rotation as a Plane.
898 */
[5417]899void Element2D::debugDraw2D(unsigned int depth, float size, Vector color, unsigned int level) const
[5081]900{
[5417]901  if (level == 0)
902  {
903    glPushAttrib(GL_ENABLE_BIT);
904    glMatrixMode(GL_MODELVIEW);
[5082]905
[5417]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);
[5418]919  glVertex2f(0, 0);
920  glVertex2f(0, +this->getSizeY2D());
[5417]921  glVertex2f(+this->getSizeX2D(), +this->getSizeY2D());
[5418]922  glVertex2f(+this->getSizeX2D(), 0);
[5417]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));
[5775]930    list<Element2D*>::const_iterator child;
931    for (child = this->children.begin(); child != this->children.end(); child++)
[5417]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);
[5775]942        glVertex3f((*child)->getAbsCoor2D ().x,
943                   (*child)->getAbsCoor2D ().y,
[5417]944                   0);
945        glEnd();
946      }
947      if (depth == 0)
[5775]948        (*child)->debugDraw2D(0, size, childColor, level+1);
[5417]949      else
[5775]950        (*child)->debugDraw2D(depth - 1, size, childColor, level +1);
[5417]951    }
952  }
953  if (level == 0)
954    glPopAttrib();
955
[5081]956}
957
958
959// helper functions //
[5091]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 */
[5082]965const char* Element2D::parentingModeToChar2D(int parentingMode)
[5081]966{
[5082]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";
[5081]977}
978
[5091]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 */
[5082]984E2D_PARENT_MODE Element2D::charToParentingMode2D(const char* parentingMode)
[5081]985{
[5082]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);
[5081]996}
997
[5401]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}
[5081]1024
[5401]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}
[5081]1043
1044
[5401]1045
1046
[5285]1047///////////////////
1048// NullElement2D //
1049///////////////////
[5082]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 */
[5403]1056NullElement2D::NullElement2D () : Element2D(NULL, E2D_LAYER_BELOW_ALL)
[5082]1057{
[5117]1058  this->setClassID(CL_NULL_ELEMENT_2D, "NullElement2D");
[5082]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.