home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5164 / miletos.7z / poseableitem.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2011-04-02  |  4.7 KB  |  243 lines

  1. #define __MILETOS_POSEABLEITEM_CPP__
  2.  
  3. //
  4. // Libmiletos
  5. //
  6. // Copyright (C) Lauris Kaplinski 2009
  7. //
  8.  
  9. #include <malloc.h>
  10.  
  11. #include <sehle/renderable.h>
  12.  
  13. #include "skeleton.h"
  14. #include "bone.h"
  15.  
  16. #include "poseableitem.h"
  17.  
  18. namespace Miletos {
  19.  
  20. PoseableItem::PoseableItem (void)
  21. : Item(HAS_CHILDREN), anchor(NULL), skeletonanchoridx(-1)
  22. {
  23. }
  24.  
  25. PoseableItem::~PoseableItem (void)
  26. {
  27. }
  28.  
  29. static Object *
  30. poseableitem_factory (void)
  31. {
  32.     return new PoseableItem();
  33. }
  34.  
  35. const Object::Type *
  36. PoseableItem::objectType (void)
  37. {
  38.     return type ();
  39. }
  40.  
  41. const Object::Type *
  42. PoseableItem::type (void)
  43. {
  44.     static Type *mytype = NULL;
  45.     static const Attribute attrs[] = {
  46.         { "anchor", NULL, 0 }
  47.     };
  48.     if (!mytype) mytype = new Type(Item::type (), "PoseableItem", "poseableItem", poseableitem_factory, sizeof (attrs) / sizeof (attrs[0]), attrs);
  49.     return mytype;
  50. }
  51.  
  52. void
  53. PoseableItem::build (Thera::Node *pnode, Document *doc, BuildCtx *ctx)
  54. {
  55.     Item::build (pnode, doc, ctx);
  56.  
  57.     buildAllAttributes (type (), ctx);
  58.  
  59. }
  60.  
  61. void
  62. PoseableItem::release (void)
  63. {
  64.     if (anchor) {
  65.         free (anchor);
  66.         anchor = NULL;
  67.     }
  68.  
  69.     Item::release ();
  70. }
  71.  
  72. Object *
  73. PoseableItem::childAdded (Thera::Node *cnode, Thera::Node *rnode)
  74. {
  75.     Object *child = Item::childAdded (cnode, rnode);
  76.  
  77.     if (renderable && child->isType (Item::type ())) {
  78.         Item *ichild = (Item *) child;
  79.         Sehle::Renderable *rchild = ichild->invokeShow (renderable->graph, 0xffffffff);
  80.         Sehle::RenderableGroup *rgroup = (Sehle::RenderableGroup *) renderable;
  81.         if (rchild) rgroup->prependChild (rchild);
  82.     }
  83.  
  84.     return child;
  85. }
  86.  
  87. void
  88. PoseableItem::childRemoved (Thera::Node *cnode, Thera::Node *rnode)
  89. {
  90.     if (renderable) {
  91.         for (Object *child = children; child; child = child->next) {
  92.             if (child->node == cnode) {
  93.                 if (child->isType (Item::type ())) {
  94.                     ((Item *) child)->invokeHide ((Sehle::RenderableGroup *) renderable);
  95.                 }
  96.                 break;
  97.             }
  98.         }
  99.     }
  100.  
  101.     Item::removeChild (cnode, rnode);
  102. }
  103.  
  104. void
  105. PoseableItem::set (const char *attrid, const char *val)
  106. {
  107.     if (!strcmp (attrid, "anchor")) {
  108.         if (anchor) {
  109.             free (anchor);
  110.             anchor = NULL;
  111.         }
  112.         if (val) {
  113.             anchor = strdup (val);
  114.         }
  115.         requestUpdate (MODIFIED | MESH_DEFINITION_MODIFIED);
  116.     } else {
  117.         Item::set (attrid, val);
  118.     }
  119. }
  120.  
  121. void
  122. PoseableItem::write (const char *attrid)
  123. {
  124.     if (!strcmp (attrid, "anchor")) {
  125.         node->setAttribute (attrid, anchor);
  126.     } else {
  127.         Item::write (attrid);
  128.     }
  129. }
  130.  
  131. void
  132. PoseableItem::update (UpdateCtx *ctx, unsigned int flags)
  133. {
  134.     // Rewrite flags
  135.     if (flags & MODIFIED) flags |= PARENT_MODIFIED;
  136.     flags &= MODIFIED_CASCADE;
  137.  
  138.     // Update children
  139.     for (Object *child = children; child; child = child->next) {
  140.         if (flags || child->updateFlagIsSet (MODIFIED_STATE)) {
  141.             if (child->isType (Item::type ())) {
  142.                 Item *ichild = (Item *) child;
  143.                 UpdateCtx cctx;
  144.                 cctx.i2w = ctx->i2w * c2o * ichild->getI2P ();
  145.                 child->invokeUpdate (&cctx, flags);
  146.             } else {
  147.                 child->invokeUpdate (ctx, flags);
  148.             }
  149.         }
  150.     }
  151.  
  152.     bbox.setEmpty ();
  153.     for (Object *child = children; child; child = child->next) {
  154.         if (child->isType (Item::type ())) {
  155.             Item *ichild = (Item *) child;
  156.             bbox.grow (ichild->bbox);
  157.         }
  158.     }
  159.  
  160.     Item::update (ctx, flags);
  161. }
  162.  
  163. Sehle::Renderable *
  164. PoseableItem::show (Sehle::Graph *graph, Sehle::u32 contextmask)
  165. {
  166.     Sehle::RenderableGroup *rgroup = new Sehle::RenderableGroup(graph, contextmask);
  167.  
  168.     for (Object *child = children; child; child = child->next) {
  169.         if (child->isType (Item::type ())) {
  170.             Item *ichild = (Item *) child;
  171.             Sehle::Renderable *rchild = ichild->invokeShow (graph, contextmask);
  172.             if (rchild) rgroup->prependChild (rchild);
  173.         }
  174.     }
  175.  
  176.     return rgroup;
  177. }
  178.  
  179. void
  180. PoseableItem::hide (Sehle::RenderableGroup *pgroup)
  181. {
  182.     for (Object *child = children; child; child = child->next) {
  183.         if (child->isType (Item::type ())) {
  184.             Item *ichild = (Item *) child;
  185.             ichild->invokeHide ((Sehle::RenderableGroup *) renderable);
  186.         }
  187.     }
  188. }
  189.  
  190. Item *
  191. PoseableItem::trace (const Elea::Line3f *wray, unsigned int mask, float *distance)
  192. {
  193.     Item *tchild = NULL;
  194.     float bestd = Elea::OMEGA_F;
  195.  
  196.     for (Object *child = children; child; child = child->next) {
  197.         if (child->isType (Item::type ())) {
  198.             Item *ichild = (Item *) child;
  199.             float d;
  200.             Item *tch = ichild->invokeTrace (wray, mask, &d);
  201.             if ((d > 0) && (d < bestd)) {
  202.                 bestd = d;
  203.                 tchild = tch;
  204.             }
  205.         }
  206.     }
  207.  
  208.     if (tchild) *distance = bestd;
  209.  
  210.     return tchild;
  211. }
  212.  
  213. void
  214. PoseableItem::getC2P (Elea::Matrix4x4f *c2p, Miletos::Item *child)
  215. {
  216.     *c2p = _i2p * c2o;
  217. }
  218.  
  219. void
  220. PoseableItem::setC2O (const Elea::Matrix4x4f& pc2o)
  221. {
  222.     c2o = pc2o;
  223.     requestUpdate (MODIFIED);
  224. }
  225.  
  226. void
  227. PoseableItem::updateSkeletonIndices (Skeleton *skeleton)
  228. {
  229.     skeletonanchoridx = skeleton->lookupBone (anchor);
  230.     if (skeletonanchoridx >= 0) {
  231.         setC2O (skeleton->bones[skeletonanchoridx]->getAB2O ());
  232.     }
  233. }
  234.  
  235. void
  236. PoseableItem::clearSkeletonIndices (void)
  237. {
  238.     skeletonanchoridx = -1;
  239. }
  240.  
  241. } // Namespace Miletos
  242.  
  243.