Bone.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <3dsparse/Bone.h>
00022 #include <3dsparse/ModelMaths.h>
00023 #include <common/Defines.h>
00024 
00025 BoneType::BoneType() : parent_(-1)
00026 {
00027 }
00028 
00029 BonePositionKey::BonePositionKey(float t, Vector &pos) :
00030         time(t), position(pos)
00031 {
00032 }
00033 
00034 BoneRotationKey::BoneRotationKey(float t, Vector &rot) :
00035         time(t), rotation(rot)
00036 {
00037 }
00038 
00039 Bone::Bone(const char *name) : name_(name)
00040 {
00041         while (!positionKeys_.empty())
00042         {
00043                 BonePositionKey *key = positionKeys_.back();
00044                 positionKeys_.pop_back();
00045                 delete key;
00046         }
00047         while (!rotationKeys_.empty())
00048         {
00049                 BoneRotationKey *key = rotationKeys_.back();
00050                 rotationKeys_.pop_back();
00051                 delete key;
00052         }
00053 }
00054 
00055 Bone::~Bone()
00056 {
00057 }
00058 
00059 Vector &Bone::getPositionAtTime(float currentTime)
00060 {
00061         static Vector tmp;
00062         BonePositionKey *lastPositionKey = 0, *thisPositionKey = 0;
00063         std::vector<BonePositionKey *>::iterator itor;
00064         for (itor = positionKeys_.begin();
00065                 itor != positionKeys_.end();
00066                 itor++)
00067         {
00068                 BonePositionKey *key = (*itor);
00069                 if (key->time >= currentTime)
00070                 {
00071                         thisPositionKey = key;
00072                         break;
00073                 }
00074                 lastPositionKey = key;
00075         }
00076         if (lastPositionKey && thisPositionKey)
00077         {
00078                 float d = thisPositionKey->time - lastPositionKey->time;
00079                 float s = (currentTime - lastPositionKey->time) / d;
00080                 tmp[0] = lastPositionKey->position[0] + (thisPositionKey->position[0] - lastPositionKey->position[0]) * s;
00081                 tmp[1] = lastPositionKey->position[1] + (thisPositionKey->position[1] - lastPositionKey->position[1]) * s;
00082                 tmp[2] = lastPositionKey->position[2] + (thisPositionKey->position[2] - lastPositionKey->position[2]) * s;
00083         }
00084         else if (thisPositionKey)
00085         {
00086                 return thisPositionKey->position;
00087         }
00088         else if (lastPositionKey)
00089         {
00090                 return lastPositionKey->position;
00091         }
00092 
00093         return tmp;
00094 }
00095 
00096 void Bone::getRotationAtTime(float currentTime, BoneMatrixType &m)
00097 {
00098         BoneRotationKey *lastRotationKey = 0, *thisRotationKey = 0;
00099         std::vector<BoneRotationKey *>::iterator itor;
00100         for (itor = rotationKeys_.begin();
00101                 itor != rotationKeys_.end();
00102                 itor++)
00103         {
00104                 BoneRotationKey *key = (*itor);
00105                 if (key->time >= currentTime)
00106                 {
00107                         thisRotationKey = key;
00108                         break;
00109                 }
00110                 lastRotationKey = key;
00111         }
00112         if (lastRotationKey && thisRotationKey)
00113         {
00114                 float d = thisRotationKey->time - lastRotationKey->time;
00115                 float s = (currentTime - lastRotationKey->time) / d;
00116 
00117 #ifndef MODEL_FAST_ANGLE_CALC
00118                 float q1[4], q2[4], q[4];
00119                 ModelMaths::angleQuaternion(lastRotationKey->rotation, q1);
00120                 ModelMaths::angleQuaternion(thisRotationKey->rotation, q2);
00121                 ModelMaths::quaternionSlerp(q1, q2, s, q);
00122                 ModelMaths::quaternionMatrix(q, m);
00123 #else
00124                 Vector rot;
00125                 rot[0] = lastRotationKey->rotation[0] + (thisRotationKey->rotation[0] - lastRotationKey->rotation[0]) * s;
00126                 rot[1] = lastRotationKey->rotation[1] + (thisRotationKey->rotation[1] - lastRotationKey->rotation[1]) * s;
00127                 rot[2] = lastRotationKey->rotation[2] + (thisRotationKey->rotation[2] - lastRotationKey->rotation[2]) * s;
00128                 rot[0] *= 180.0f / PI;
00129                 rot[1] *= 180.0f / PI;
00130                 rot[2] *= 180.0f / PI;
00131                 ModelMaths::angleMatrix(rot, m);
00132 #endif
00133         }
00134         else if (thisRotationKey)
00135         {
00136                 Vector rot;
00137                 rot[0] = thisRotationKey->rotation[0] * 180.0f / PI;
00138                 rot[1] = thisRotationKey->rotation[1] * 180.0f / PI;
00139                 rot[2] = thisRotationKey->rotation[2] * 180.0f / PI;
00140                 ModelMaths::angleMatrix(rot, m);
00141         }
00142         else if (lastRotationKey )
00143         {
00144                 Vector rot;
00145                 rot[0] = lastRotationKey->rotation[0] * 180.0f / PI;
00146                 rot[1] = lastRotationKey->rotation[1] * 180.0f / PI;
00147                 rot[2] = lastRotationKey->rotation[2] * 180.0f / PI;
00148                 ModelMaths::angleMatrix(rot, m);
00149         }
00150 }

Generated on Mon Feb 16 15:14:48 2009 for Scorched3D by  doxygen 1.5.3