00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 }