home *** CD-ROM | disk | FTP | other *** search
- #define __MILETOS_IKCHAIN_CPP__
-
- //
- // Libmiletos
- //
- // Copyright (C) Lauris Kaplinski 2010
- //
-
- #include <malloc.h>
-
- #include "xml/base.h"
- #include "skeleton.h"
- #include "bone.h"
-
- #include "ikchain.h"
-
- namespace Miletos {
-
- //
- // IK chain controller for skeletal meshes
- //
-
- IKChain::IKChain (void)
- : Object(0), sid (NULL), first(NULL), last(NULL), end(NULL), endPosition(Elea::Vector3f0), targetPosition(Elea::Vector3f0), enabled(1)
- {
- }
-
- IKChain::~IKChain (void)
- {
- if (sid) free (sid);
- if (first) free (first);
- if (last) free (last);
- if (end) free (end);
- }
-
- static Object *
- ikchain_factory (void)
- {
- return new IKChain();
- }
-
- const Object::Type *
- IKChain::objectType (void)
- {
- return type ();
- }
-
- const Object::Type *
- IKChain::type (void)
- {
- static Type *mytype = NULL;
- static const Attribute attrs[] = {
- { "sid", NULL, 0 },
- { "first", NULL, 0 },
- { "last", NULL, 0 },
- { "end", NULL, 0 },
- { "endPosition", NULL, 0 },
- { "targetPosition", NULL, 0 }
- };
- if (!mytype) mytype = new Type(Object::type (), "IKChain", "ikChain", ikchain_factory, sizeof (attrs) / sizeof (attrs[0]), attrs);
- return mytype;
- }
-
- void
- IKChain::build (Thera::Node *pnode, Document *doc, BuildCtx *ctx)
- {
- Object::build (pnode, doc, ctx);
- buildAllAttributes (type (), ctx);
- requestUpdate (CHAIN_STRUCTURE_MODIFIED);
- }
-
- void
- IKChain::release (void)
- {
- Object::release ();
- }
-
- void
- IKChain::set (const char *attrid, const char *val)
- {
- if (!strcmp (attrid, "sid")) {
- if (sid) free (sid);
- sid = (val) ? strdup (val) : NULL;
- requestUpdate (MODIFIED);
- } else if (!strcmp (attrid, "first")) {
- if (first) free (first);
- first = (val) ? strdup (val) : NULL;
- requestUpdate (MODIFIED | CHAIN_STRUCTURE_MODIFIED);
- } else if (!strcmp (attrid, "last")) {
- if (last) free (last);
- last = (val) ? strdup (val) : NULL;
- requestUpdate (MODIFIED | CHAIN_STRUCTURE_MODIFIED);
- } else if (!strcmp (attrid, "end")) {
- if (end) free (end);
- end = (val) ? strdup (val) : NULL;
- requestUpdate (MODIFIED | CHAIN_STRUCTURE_MODIFIED);
- } else if (!strcmp (attrid, "endPosition")) {
- if (!Miletos::XML::parseNumbers (endPosition, 3, val)) endPosition = Elea::Vector3f0;
- requestUpdate (MODIFIED);
- } else if (!strcmp (attrid, "targetPosition")) {
- if (!Miletos::XML::parseNumbers (targetPosition, 3, val)) targetPosition = Elea::Vector3f0;
- requestUpdate (MODIFIED);
- }
- // Object does not implement set
- }
-
- void
- IKChain::write (const char *attrid)
- {
- if (!strcmp (attrid, "first")) {
- } else if (!strcmp (attrid, "last")) {
- } else if (!strcmp (attrid, "end")) {
- } else if (!strcmp (attrid, "endPosition")) {
- } else if (!strcmp (attrid, "targetPosition")) {
- char c[128];
- XML::writeNumbers (c, 128, targetPosition, 3);
- node->setAttribute (attrid, c);
- }
- }
-
- void
- IKChain::update (UpdateCtx *ctx, unsigned int flags)
- {
- Object::update (ctx, flags);
- }
-
- void
- IKChain::attach (Skeleton *skeleton)
- {
- bones.clear ();
- endbone = NULL;
- if (!skeleton || !first || !last || !end) return;
- int boneidx = skeleton->lookupBone (last);
- if (boneidx < 0) return;
- Bone *bone = skeleton->bones[boneidx];
- std::vector<Bone *> lbones;
- while (bone) {
- lbones.push_back (bone);
- if (!strcmp (bone->sid, first)) break;
- bone = (Bone *) bone->parent;
- if (!bone->isType (Bone::type ())) return;
- if (!bone->sid) return;
- }
- boneidx = skeleton->lookupBone (end);
- if (boneidx < 0) return;
- endbone = skeleton->bones[boneidx];
- bones.resize (lbones.size ());
- for (size_t i = 0; i < lbones.size (); i++) {
- bones[i].bone = lbones[lbones.size () - 1 - i];
- Elea::Matrix4x4f p2b = bones[i].bone->b2p.invertNormalized ();
- Elea::Matrix4x4f ab2b = p2b * bones[i].bone->ab2p;
- const int order[] = { Elea::Z, Elea::X, Elea::Y };
- ab2b.getEulerAngles (bones[i].angles, order);
- }
- }
-
- void
- IKChain::setTargetPosition (const Elea::Vector3f *pos)
- {
- targetPosition = *pos;
- requestUpdate (MODIFIED);
- }
-
- } // Namespace Miletos
-
-
-