Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

MS_Bone.cpp

Go to the documentation of this file.
00001 
00007 #include "MilkShape.h"
00008 
00009 MS_Bone::MS_Bone() {
00010         this->keyFramesTrans    = NULL;
00011         this->keyFramesRot              = NULL;
00012         this->parent                    = NULL;
00013 }
00014 
00015 MS_Bone::~MS_Bone() {
00016         clear();
00017 }
00018 
00019 void MS_Bone::clear() {
00020         if (this->keyFramesTrans) {
00021                 free(keyFramesTrans);
00022                 keyFramesTrans = NULL;
00023         }
00024 
00025         if (this->keyFramesRot) {
00026                 free(keyFramesRot);
00027                 keyFramesRot = NULL;
00028         }
00029 }
00030 
00031 void MS_Bone::render() {
00032         MS_Vec vector;
00033         MS_Vec parentvector;
00034 
00035         vector.x = 0.0f;
00036         vector.y = 0.0f;
00037         vector.z = 0.0f;
00038         vector.w = 1.0f;
00039 
00040         MS_Vec_Transform(&vector, &this->matFinal);
00041 
00042         if (this->parent) {
00043                 parentvector.x = 0.0f;
00044                 parentvector.y = 0.0f;
00045                 parentvector.z = 0.0f;
00046                 parentvector.w = 1.0f;
00047                 MS_Vec_Transform(&parentvector, &this->parent->matFinal);
00048         }
00049 
00050         glDisable(GL_TEXTURE_2D);
00051 
00052         // render bones as lines
00053         glLineWidth(1.0f);
00054         glColor3f(1.0f, 0.0f, 0.0f);
00055         glBegin(GL_LINES);
00056                 glVertex3f(vector.x, vector.y, vector.z);
00057                 if (this->parent)
00058                         glVertex3f(parentvector.x, parentvector.y, parentvector.z);
00059                 else
00060                         glVertex3f(vector.x, vector.y, vector.z);
00061         glEnd();
00062 
00063         // render bone-ends
00064         glPointSize(4.0f);
00065         glColor3f(1.0f, 0.0f, 1.0f);
00066         glBegin(GL_POINTS);
00067                 glVertex3f(vector.x, vector.y, vector.z);
00068                 if (this->parent)
00069                         glVertex3f(parentvector.x, parentvector.y, parentvector.z);
00070         glEnd();
00071 
00072         glColor3f(1.0f, 1.0f, 1.0f);
00073 }
00074 
00075 bool MS_Bone::loadFromAsciiSegment(FILE *file) {
00076         char szLine[256] = {0};
00077         int j, nFlags;
00078 
00079         if (!fgets(szLine, 256, file)) {
00080                 return false;
00081         }
00082 
00083         //--------------------
00084         // Name
00085         //--------------------
00086         if (sscanf(szLine, "\"%[^\"]\"", this->name) != 1) {
00087                 return false;
00088         }
00089 
00090         //--------------------
00091         // Parent name
00092         //--------------------
00093         if (!fgets(szLine, 256, file))
00094                 return false;
00095         strcpy(this->parentName, "");
00096         sscanf(szLine, "\"%[^\"]\"", this->parentName);
00097 
00098         //--------------------
00099         // Position and rotation
00100         //--------------------
00101         if (!fgets(szLine, 256, file))
00102                 return false;
00103         if (sscanf(szLine, "%d %f %f %f %f %f %f",
00104                                                 &nFlags,
00105                                                 &this->position[0], &this->position[1], &this->position[2],
00106                                                 &this->rotation[0], &this->rotation[1], &this->rotation[2]) != 7) {
00107                 return false;
00108         }
00109 
00110         //--------------------
00111         // Position key count
00112         //--------------------
00113         if (!fgets(szLine, 256, file))
00114                 return false;
00115         if (sscanf(szLine, "%d", &this->numPosKeys) != 1)
00116                 return false;
00117 
00118         this->keyFramesTrans = (MS_KeyFramePos *)malloc(sizeof(MS_KeyFramePos) * this->numPosKeys);
00119         for (j=0; j<this->numPosKeys; j++) {
00120                 if (!fgets(szLine, 256, file))
00121                         return false;
00122                 if (sscanf(szLine, "%f %f %f %f", &this->keyFramesTrans[j].time,
00123                                                                                   &this->keyFramesTrans[j].position[0],
00124                                                                                   &this->keyFramesTrans[j].position[1],
00125                                                                                   &this->keyFramesTrans[j].position[2]) != 4) {
00126                         return false;
00127                 }
00128         }
00129 
00130         //--------------------
00131         // Rotation key count
00132         //--------------------
00133         if (!fgets(szLine, 256, file))
00134                 return false;
00135         if (sscanf(szLine, "%d", &this->numRotKeys) != 1)
00136                 return false;
00137 
00138         this->keyFramesRot = (MS_KeyFrameRot *)malloc(sizeof(MS_KeyFrameRot) * this->numRotKeys);
00139         for (j=0; j<this->numRotKeys; j++) {
00140                 if (!fgets(szLine, 256, file))
00141                         return false;
00142                 if (sscanf(szLine, "%f %f %f %f", &this->keyFramesRot[j].time,
00143                                                                                   &this->keyFramesRot[j].position[0],
00144                                                                                   &this->keyFramesRot[j].position[1],
00145                                                                                   &this->keyFramesRot[j].position[2]) != 4) {
00146                         return false;
00147                 }
00148         }
00149 
00150         return true;
00151 }
00152 
00153 void MS_Bone::initialize() {
00154         Mat4 m_rel;
00155 
00156         m_rel.loadRotateZXY(this->rotation[0], this->rotation[1], this->rotation[2]);
00157         m_rel.setTranslate(Vec3(this->position[0], this->position[1], this->position[2]));
00158 
00159         if (this->parent == NULL) {
00160                 this->matFinal = m_rel;
00161         }
00162         else {
00163                 this->matFinal = this->parent->matFinal;
00164                 this->matFinal *= m_rel;
00165         }
00166 }
00167 
00168 void MS_Bone::advanceTo(float fCurrentTime) {
00169         int i;
00170         float deltaTime;
00171         float fraction;
00172         float Position[3];
00173         float Rotation[3];
00174 
00175         //--------------------
00176         // Position
00177         //--------------------
00178         i = 0;
00179         while (i<this->numPosKeys-1 && this->keyFramesTrans[i].time < fCurrentTime)
00180                 i++;
00181 
00182         assert(i < this->numPosKeys);
00183 
00184         // Interpolate between two key frames
00185         if (i > 0) {
00186                 deltaTime = this->keyFramesTrans[i].time - this->keyFramesTrans[i-1].time;
00187 
00188                 assert(deltaTime > 0.0f);
00189 
00190                 fraction = (fCurrentTime - this->keyFramesTrans[i-1].time) / deltaTime;
00191 
00192                 assert(fraction > 0.0f);
00193                 assert(fraction < 1.0f);
00194 
00195                 Position[0] = this->keyFramesTrans[i-1].position[0] + fraction * (this->keyFramesTrans[i].position[0] - this->keyFramesTrans[i-1].position[0]);
00196                 Position[1] = this->keyFramesTrans[i-1].position[1] + fraction * (this->keyFramesTrans[i].position[1] - this->keyFramesTrans[i-1].position[1]);
00197                 Position[2] = this->keyFramesTrans[i-1].position[2] + fraction * (this->keyFramesTrans[i].position[2] - this->keyFramesTrans[i-1].position[2]);
00198         }
00199         else {
00200                 memcpy(Position, this->keyFramesTrans[i].position, 3*sizeof(float));
00201         }
00202 
00203         //--------------------
00204         // Rotation
00205         //--------------------
00206         i = 0;
00207         while (i<this->numRotKeys-1 && this->keyFramesRot[i].time < fCurrentTime)
00208                 i++;
00209 
00210         assert(i < this->numRotKeys);
00211 
00212         // Interpolate between two key frames
00213         if (i > 0) {
00214                 deltaTime = this->keyFramesRot[i].time - this->keyFramesRot[i-1].time;
00215 
00216                 assert(deltaTime > 0.0f);
00217 
00218                 fraction = (fCurrentTime - this->keyFramesRot[i-1].time) / deltaTime;
00219 
00220                 assert(fraction > 0.0f);
00221                 assert(fraction < 1.0f);
00222 
00223                 Rotation[0] = this->keyFramesRot[i-1].position[0] + fraction * (this->keyFramesRot[i].position[0] - this->keyFramesRot[i-1].position[0]);
00224                 Rotation[1] = this->keyFramesRot[i-1].position[1] + fraction * (this->keyFramesRot[i].position[1] - this->keyFramesRot[i-1].position[1]);
00225                 Rotation[2] = this->keyFramesRot[i-1].position[2] + fraction * (this->keyFramesRot[i].position[2] - this->keyFramesRot[i-1].position[2]);
00226         }
00227         else {
00228                 memcpy(Rotation, this->keyFramesRot[i].position, 3*sizeof(float));
00229         }
00230 
00231         //--------------------
00232         // Transformation matrix
00233         //--------------------
00234         Mat4 m_rel;
00235         Mat4 m_frame;
00236 
00237         m_rel.loadRotateZXY(this->rotation[0], this->rotation[1], this->rotation[2]);
00238         m_rel.setTranslate(Vec3(this->position[0], this->position[1], this->position[2]));
00239 
00240         m_frame.loadRotateZXY(Rotation[0], Rotation[1], Rotation[2]);
00241         m_frame.setTranslate(Vec3(Position[0], Position[1], Position[2]));
00242 
00243         m_rel *= m_frame;
00244 
00245         if (this->parent == NULL) {
00246                 this->matFinal = m_rel;
00247         }
00248         else {
00249                 this->matFinal = this->parent->matFinal;
00250                 this->matFinal *= m_rel;
00251         }
00252 }

Generated on Sun Jun 5 15:47:04 2005 for Defacto by  doxygen 1.4.3