00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <sofa/helper/io/bvh/BVHLoader.h>
00028 #include <iostream>
00029
00030 namespace sofa
00031 {
00032
00033 namespace helper
00034 {
00035
00036 namespace io
00037 {
00038
00039 namespace bvh
00040 {
00041
00042 BVHJoint *BVHLoader::load(const char *filename)
00043 {
00044 FILE *file = fopen(filename, "r");
00045
00046 if (file)
00047 {
00048 BVHJoint *retBVHJoint = NULL;
00049 char buf[256];
00050
00051 while (fscanf(file, "%s", buf) != EOF)
00052 {
00053 if (strcmp(buf, "ROOT") == 0)
00054 retBVHJoint = parseJoint(file);
00055 else if (strcmp(buf, "MOTION") == 0)
00056 parseMotion(file, retBVHJoint);
00057 }
00058
00059 return retBVHJoint;
00060 }
00061
00062 std::cout << "File " << filename << " not found\n";
00063 return NULL;
00064 }
00065
00066
00067 BVHJoint *BVHLoader::parseJoint(FILE *f, bool isEndSite, BVHJoint *parent)
00068 {
00069 char buf[256];
00070
00071 if (!isEndSite)
00072 fscanf(f,"%s",buf);
00073
00074 BVHJoint *j = new BVHJoint(buf, isEndSite, parent);
00075
00076 fscanf(f,"%s",buf);
00077
00078 while (!(strcmp(buf,"}") == 0))
00079 {
00080 if (strcmp(buf,"OFFSET") == 0)
00081 {
00082 j->setOffset(parseOffset(f));
00083 }
00084 else if (strcmp(buf,"CHANNELS") == 0)
00085 {
00086 j->setChannels(parseChannels(f));
00087 }
00088 else if (strcmp(buf,"JOINT") == 0)
00089 {
00090 j->addChild(parseJoint(f, false, j));
00091 }
00092 else if (strcmp(buf,"End") == 0)
00093 {
00094 fscanf(f,"%s",buf);
00095 if (strcmp(buf, "Site") == 0)
00096 j->addChild(parseJoint(f, true, j));
00097 }
00098
00099 fscanf(f,"%s",buf);
00100 }
00101
00102 return j;
00103 }
00104
00105
00106 BVHOffset *BVHLoader::parseOffset(FILE *f)
00107 {
00108 double x(0);
00109 double y(0);
00110 double z(0);
00111
00112 fscanf(f,"%lf",&x);
00113 fscanf(f,"%lf",&y);
00114 fscanf(f,"%lf",&z);
00115
00116 return new BVHOffset(x,y,z);
00117 }
00118
00119
00120 BVHChannels *BVHLoader::parseChannels(FILE *f)
00121 {
00122 int cSize(0);
00123 fscanf(f,"%d",&cSize);
00124
00125 if (cSize <= 0)
00126 return NULL;
00127
00128 BVHChannels *c = new BVHChannels(cSize);
00129 char buf[256];
00130
00131 for (int i=0; i<cSize; i++)
00132 {
00133 fscanf(f,"%s",buf);
00134
00135 if (strcmp(buf, "Xposition") == 0)
00136 c->addChannel(BVHChannels::Xposition);
00137 else if (strcmp(buf, "Yposition") == 0)
00138 c->addChannel(BVHChannels::Yposition);
00139 else if (strcmp(buf, "Zposition") == 0)
00140 c->addChannel(BVHChannels::Zposition);
00141 else if (strcmp(buf, "Xrotation") == 0)
00142 c->addChannel(BVHChannels::Xrotation);
00143 else if (strcmp(buf, "Yrotation") == 0)
00144 c->addChannel(BVHChannels::Yrotation);
00145 else if (strcmp(buf, "Zrotation") == 0)
00146 c->addChannel(BVHChannels::Zrotation);
00147 else
00148 c->addChannel(BVHChannels::NOP);
00149 }
00150
00151 return c;
00152 }
00153
00154
00155 void BVHLoader::parseMotion(FILE *f, BVHJoint *j)
00156 {
00157 if (j == NULL)
00158 return;
00159
00160 char buf[256];
00161 bool framesFound(false);
00162 bool frameTimeFound(false);
00163 int frameCount;
00164 double frameTime;
00165
00166 while (!framesFound || !frameTimeFound)
00167 {
00168 fscanf(f,"%s",buf);
00169
00170 if (strcmp(buf,"Frames:") == 0)
00171 {
00172 fscanf(f,"%d",&(frameCount));
00173 framesFound = true;
00174 }
00175 else if (strcmp(buf, "Time:") == 0)
00176 {
00177 fscanf(f,"%lf",&(frameTime));
00178 frameTimeFound = true;
00179 }
00180 }
00181
00182 j->initMotion(frameTime, frameCount);
00183
00184 for (int i=0; i < frameCount; i++)
00185 parseFrames(j, i, f);
00186 }
00187
00188
00189 void BVHLoader::parseFrames(BVHJoint *joint, unsigned int frameIndex, FILE *f)
00190 {
00191 if (joint->getChannels() != NULL)
00192 for (unsigned int i=0; i < joint->getChannels()->size; i++)
00193 fscanf(f,"%lf",&joint->getMotion()->frames[frameIndex][i]);
00194
00195 for (unsigned int i=0; i < joint->getChildren().size(); i++)
00196 parseFrames(joint->getChildren()[i], frameIndex, f);
00197 }
00198
00199 }
00200
00201 }
00202
00203 }
00204
00205 }