00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <3dsparse/MSModelFactory.h>
00022 #include <common/Defines.h>
00023
00024 MSModelFactory::MSModelFactory() : lineNo_(0)
00025 {
00026 }
00027
00028 MSModelFactory::~MSModelFactory()
00029 {
00030 }
00031
00032 Model *MSModelFactory::createModel(const char *fileName)
00033 {
00034 Model *model = new Model();
00035
00036 FILE *in = fopen(fileName, "r");
00037 if (!in)
00038 {
00039 S3D::dialogExit("MSModelFactory", S3D::formatStringBuffer(
00040 "Failed to open MS model \"%s\"",
00041 fileName));
00042 }
00043 loadFile(in, fileName, model);
00044 model->setup();
00045 fclose(in);
00046
00047 return model;
00048 }
00049
00050 bool MSModelFactory::getNextLine(char *line, FILE *in)
00051 {
00052 char * wincr;
00053 while (fgets(line, 256, in) != 0)
00054 {
00055 lineNo_++;
00056 if (wincr=strchr(line,'\r'))
00057 {
00058 *wincr='\n';
00059 *(wincr + 1) = '\0';
00060 }
00061
00062 if ((line[0] == '\\' && line[1] == '\\') ||
00063 (line[0] == '/' && line[1] == '/') ||
00064 (line[0] == '\0') ||
00065 (line[0] == '\n'))
00066 {
00067
00068 }
00069 else return true;
00070 }
00071
00072 return false;
00073 }
00074
00075 void MSModelFactory::returnError(const char *fileName, const std::string &error)
00076 {
00077 S3D::dialogExit("MSModelFactory", S3D::formatStringBuffer("%s in file %i:%s",
00078 error.c_str(), lineNo_, fileName));
00079 }
00080
00081 void MSModelFactory::loadFile(FILE *in, const char *fileName, Model *model)
00082 {
00083 char filePath[256];
00084 snprintf(filePath, sizeof(filePath), "%s", fileName);
00085
00086 char *sep;
00087 while (sep=strchr(filePath, '\\')) *sep = '/';
00088 sep = strrchr(filePath, '/');
00089 if (sep) *sep = '\0';
00090
00091 char buffer[256];
00092 int frames = 0;
00093 if (!getNextLine(buffer, in)) returnError(fileName, "No frames");
00094 if (sscanf(buffer, "Frames: %i", &frames) != 1)
00095 returnError(fileName, "Incorrect frames format");
00096 model->setTotalFrames(frames);
00097
00098 if (!getNextLine(buffer, in)) returnError(fileName, "No frame");
00099 if (sscanf(buffer, "Frame: %i", &frames) != 1)
00100 returnError(fileName, "Incorrect frame format");
00101 model->setStartFrame(frames);
00102
00103
00104 int noMeshes = 0;
00105 if (!getNextLine(buffer, in)) returnError(fileName, "No meshes");
00106 if (sscanf(buffer, "Meshes: %i", &noMeshes) != 1)
00107 returnError(fileName, "Incorrect meshes format");
00108
00109 std::vector<int> meshMaterials;
00110 for (int i=0; i<noMeshes; i++)
00111 {
00112
00113 char meshName[256];
00114 int meshFlags, meshMatIndex;
00115 if (!getNextLine(buffer, in))
00116 returnError(fileName, "No mesh name");
00117 if (sscanf(buffer, "%s %i %i", meshName, &meshFlags, &meshMatIndex) != 3)
00118 returnError(fileName, "Incorrect mesh name format");
00119 meshMaterials.push_back(meshMatIndex);
00120
00121
00122 Mesh *mesh = new Mesh(meshName);
00123 model->addMesh(mesh);
00124
00125
00126 int noVertices = 0;
00127 if (!getNextLine(buffer, in))
00128 returnError(fileName, "No num vertices");
00129 if (sscanf(buffer, "%i", &noVertices) != 1)
00130 returnError(fileName, "Incorrect num vertices format");
00131
00132 int j;
00133 std::vector<Vector> tcoords;
00134 for (j=0; j<noVertices; j++)
00135 {
00136
00137 int vertexFlags;
00138 Vector texCoord;
00139 Vertex vertex;
00140 if (!getNextLine(buffer, in))
00141 returnError(fileName, "No vertices");
00142 if (sscanf(buffer, "%i %f %f %f %f %f %i",
00143 &vertexFlags,
00144 &vertex.position[0], &vertex.position[2], &vertex.position[1],
00145 &texCoord[0], &texCoord[1], &vertex.boneIndex) != 7)
00146 returnError(fileName, "Incorrect vertices format");
00147 texCoord[1]=1.0f-texCoord[1];
00148
00149 tcoords.push_back(texCoord);
00150 mesh->insertVertex(vertex);
00151 }
00152
00153
00154 std::vector<Vector> normals;
00155 int noNormals = 0;
00156 if (!getNextLine(buffer, in))
00157 returnError(fileName, "No num normals");
00158 if (sscanf(buffer, "%i", &noNormals) != 1)
00159 returnError(fileName, "Incorrect num normals format");
00160 for (j=0; j<noNormals; j++)
00161 {
00162
00163 Vector normal;
00164 if (!getNextLine(buffer, in))
00165 returnError(fileName, "No normal");
00166 if (sscanf(buffer, "%f %f %f",
00167 &normal[0], &normal[2], &normal[1]) != 3)
00168 returnError(fileName, "Incorrect normal format");
00169
00170 normals.push_back(normal.Normalize());
00171 }
00172
00173
00174 int noFaces = 0;
00175 if (!getNextLine(buffer, in))
00176 returnError(fileName, "No num faces");
00177 if (sscanf(buffer, "%i", &noFaces) != 1)
00178 returnError(fileName, "Incorrect num faces format");
00179 for (j=0; j<noFaces; j++)
00180 {
00181
00182 int faceFlags, sGroup;
00183 int nIndex1, nIndex2, nIndex3;
00184 Face face;
00185 if (!getNextLine(buffer, in))
00186 returnError(fileName, "No face");
00187 if (sscanf(buffer, "%i %i %i %i %i %i %i %i",
00188 &faceFlags,
00189 &face.v[0], &face.v[2], &face.v[1],
00190 &nIndex1, &nIndex3, &nIndex2,
00191 &sGroup) != 8)
00192 returnError(fileName, "Incorrect face format");
00193
00194 mesh->insertFace(face);
00195 DIALOG_ASSERT (nIndex1 < (int) normals.size());
00196 mesh->setFaceNormal(normals[nIndex1], j, 0);
00197 DIALOG_ASSERT (nIndex2 < (int) normals.size());
00198 mesh->setFaceNormal(normals[nIndex2], j, 1);
00199 DIALOG_ASSERT (nIndex3 < (int) normals.size());
00200 mesh->setFaceNormal(normals[nIndex3], j, 2);
00201
00202 DIALOG_ASSERT (face.v[0] < (int) tcoords.size());
00203 mesh->setFaceTCoord(tcoords[face.v[0]], j, 0);
00204 DIALOG_ASSERT (face.v[1] < (int) tcoords.size());
00205 mesh->setFaceTCoord(tcoords[face.v[1]], j, 1);
00206 DIALOG_ASSERT (face.v[2] < (int) tcoords.size());
00207 mesh->setFaceTCoord(tcoords[face.v[2]], j, 2);
00208 }
00209 }
00210
00211
00212 int noMaterials = 0;
00213 if (!getNextLine(buffer, in))
00214 returnError(fileName, "No num materials");
00215 if (sscanf(buffer, "Materials: %i", &noMaterials) != 1)
00216 returnError(fileName, "Incorrect num materials format");
00217
00218 for (int m=0; m<noMaterials; m++)
00219 {
00220
00221 char materialName[256];
00222 if (!getNextLine(buffer, in))
00223 returnError(fileName, "No material name");
00224 if (sscanf(buffer, "%s", materialName) != 1)
00225 returnError(fileName, "Incorrect material name format");
00226
00227
00228 Vector4 ambient;
00229 if (!getNextLine(buffer, in))
00230 returnError(fileName, "No material ambient");
00231 if (sscanf(buffer, "%f %f %f %f",
00232 &ambient[0], &ambient[1], &ambient[2], &ambient[3]) != 4)
00233 returnError(fileName, "Incorrect material ambient format");
00234
00235
00236 Vector4 diffuse;
00237 if (!getNextLine(buffer, in))
00238 returnError(fileName, "No material diffuse");
00239 if (sscanf(buffer, "%f %f %f %f",
00240 &diffuse[0], &diffuse[1], &diffuse[2], &diffuse[3]) != 4)
00241 returnError(fileName, "Incorrect material diffuse format");
00242
00243
00244 Vector4 specular;
00245 if (!getNextLine(buffer, in))
00246 returnError(fileName, "No material specular");
00247 if (sscanf(buffer, "%f %f %f %f",
00248 &specular[0], &specular[1], &specular[2], &specular[3]) != 4)
00249 returnError(fileName, "Incorrect material specular format");
00250
00251
00252 Vector4 emissive;
00253 if (!getNextLine(buffer, in))
00254 returnError(fileName, "No material emissive");
00255 if (sscanf(buffer, "%f %f %f %f",
00256 &emissive[0], &emissive[1], &emissive[2], &emissive[3]) != 4)
00257 returnError(fileName, "Incorrect material emissive format");
00258
00259
00260 float shininess;
00261 if (!getNextLine(buffer, in))
00262 returnError(fileName, "No material shininess");
00263 if (sscanf(buffer, "%f", &shininess) != 1)
00264 returnError(fileName, "Incorrect material shininess format");
00265
00266
00267 float transparency;
00268 if (!getNextLine(buffer, in))
00269 returnError(fileName, "No material transparency");
00270 if (sscanf(buffer, "%f", &transparency) != 1)
00271 returnError(fileName, "Incorrect material transparency format");
00272
00273
00274 char textureName[256];
00275 char fullTextureName[256];
00276 if (!getNextLine(buffer, in))
00277 returnError(fileName, "No material texture");
00278 if (sscanf(buffer, "%s", textureName) != 1)
00279 returnError(fileName, "No material texture format");
00280 textureName[strlen(textureName)-1] = '\0';
00281 snprintf(fullTextureName, 256, "%s/%s", filePath, &textureName[1]);
00282 while (sep=strchr(fullTextureName, '\\')) *sep = '/';
00283
00284
00285 char textureNameAlpha[256];
00286 char fullTextureAlphaName[256];
00287 if (!getNextLine(buffer, in))
00288 returnError(fileName, "No material alpha texture");
00289 if (sscanf(buffer, "%s", textureNameAlpha) != 1)
00290 returnError(fileName, "No material alpha texture format");
00291 textureNameAlpha[strlen(textureNameAlpha)-1] = '\0';
00292 snprintf(fullTextureAlphaName, 256, "%s/%s", filePath, &textureNameAlpha[1]);
00293 while (sep=strchr(fullTextureAlphaName, '\\')) *sep = '/';
00294
00295
00296 int modelIndex = 0;
00297 std::vector<Mesh *>::iterator mitor;
00298 for (mitor = model->getMeshes().begin();
00299 mitor != model->getMeshes().end();
00300 mitor++, modelIndex++)
00301 {
00302 if (meshMaterials[modelIndex] == m)
00303 {
00304 Mesh *mesh = *mitor;
00305 if (textureName[1])
00306 {
00307 mesh->setTextureName(fullTextureName);
00308 if (!S3D::fileExists(fullTextureName))
00309 {
00310 returnError(fileName,
00311 S3D::formatStringBuffer("Failed to find texture \"%s\"",
00312 fullTextureName));
00313 }
00314 }
00315 if (textureNameAlpha[1])
00316 {
00317 mesh->setATextureName(fullTextureAlphaName);
00318 if (!S3D::fileExists(fullTextureAlphaName))
00319 {
00320 returnError(fileName,
00321 S3D::formatStringBuffer("Failed to find alpha texture \"%s\"",
00322 fullTextureAlphaName));
00323 }
00324 }
00325 mesh->getDiffuseColor() = diffuse;
00326 mesh->getAmbientColor() = ambient;
00327 mesh->getSpecularColor() = specular;
00328 mesh->getEmissiveColor() = emissive;
00329 mesh->getShininessColor() = shininess;
00330 mesh->getDiffuseNoTexColor() = diffuse;
00331 mesh->getAmbientNoTexColor() = ambient;
00332 mesh->getSpecularNoTexColor() = specular;
00333 mesh->getEmissiveNoTexColor() = emissive;
00334 }
00335 }
00336 }
00337
00338
00339 int modelIndex = 0;
00340 std::vector<Mesh *>::iterator mitor;
00341 for (mitor = model->getMeshes().begin();
00342 mitor != model->getMeshes().end();
00343 mitor++, modelIndex++)
00344 {
00345 int materialIndex = meshMaterials[modelIndex];
00346 if (materialIndex == -1)
00347 {
00348 Mesh *mesh = *mitor;
00349
00350 Vector4 ambientColor(0.3f, 0.3f, 0.3f, 1.0f);
00351 Vector4 diffuseColor(0.8f, 0.8f, 0.8f, 1.0f);
00352 mesh->getAmbientColor() = ambientColor;
00353 mesh->getDiffuseColor() = diffuseColor;
00354 mesh->getEmissiveColor() = Vector::getNullVector();
00355 mesh->getSpecularColor() = Vector::getNullVector();
00356
00357 mesh->getAmbientNoTexColor() = ambientColor;
00358 mesh->getDiffuseNoTexColor() = diffuseColor;
00359 mesh->getEmissiveNoTexColor() = Vector::getNullVector();
00360 mesh->getSpecularNoTexColor() = Vector::getNullVector();
00361
00362 mesh->getShininessColor() = 0.0f;
00363 }
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 int noBones = 0;
00375 if (!getNextLine(buffer, in))
00376 returnError(fileName, "No num bones");
00377 if (sscanf(buffer, "Bones: %i", &noBones) != 1)
00378 returnError(fileName, "Incorrect num bones format");
00379
00380 for (int b=0; b<noBones; b++)
00381 {
00382
00383 char boneName[256];
00384 if (!getNextLine(buffer, in))
00385 returnError(fileName, "No bone name");
00386 if (sscanf(buffer, "%s", boneName) != 1)
00387 returnError(fileName, "Incorrect bone name format");
00388
00389
00390 char boneParentName[256];
00391 if (!getNextLine(buffer, in))
00392 returnError(fileName, "No bone parent name");
00393 if (sscanf(buffer, "%s", boneParentName) != 1)
00394 returnError(fileName, "Incorrect bone parent name format");
00395
00396
00397 int boneFlags;
00398 Vector bonePos, boneRot;
00399 if (!getNextLine(buffer, in))
00400 returnError(fileName, "No bone pos/rot");
00401 if (sscanf(buffer, "%i %f %f %f %f %f %f",
00402 &boneFlags,
00403 &bonePos[0], &bonePos[1], &bonePos[2],
00404 &boneRot[0], &boneRot[1], &boneRot[2]) != 7)
00405 returnError(fileName, "Incorrect bone pos/rot format");
00406
00407 Bone *bone = new Bone(boneName);
00408 bone->setParentName(boneParentName);
00409 bone->setPosition(bonePos);
00410 bone->setRotation(boneRot);
00411
00412
00413 int noPositionKeys = 0;
00414 if (!getNextLine(buffer, in))
00415 returnError(fileName, "No bone position keys");
00416 if (sscanf(buffer, "%i", &noPositionKeys) != 1)
00417 returnError(fileName, "Incorrect bone position keys format");
00418
00419 for (int p=0; p<noPositionKeys; p++)
00420 {
00421 float time;
00422 Vector position;
00423 if (!getNextLine(buffer, in))
00424 returnError(fileName, "No bone position key");
00425 if (sscanf(buffer, "%f %f %f %f",
00426 &time,
00427 &position[0], &position[1], &position[2]) != 4)
00428 returnError(fileName, "Incorrect bone position key");
00429
00430 BonePositionKey *key = new BonePositionKey(time, position);
00431 bone->addPositionKey(key);
00432 }
00433
00434
00435 int noRotationKeys = 0;
00436 if (!getNextLine(buffer, in))
00437 returnError(fileName, "No bone rotation keys");
00438 if (sscanf(buffer, "%i", &noRotationKeys) != 1)
00439 returnError(fileName, "Incorrect bone rotation keys format");
00440
00441 for (int r=0; r<noRotationKeys; r++)
00442 {
00443 float time;
00444 Vector rotation;
00445 if (!getNextLine(buffer, in))
00446 returnError(fileName, "No bone position key");
00447 if (sscanf(buffer, "%f %f %f %f",
00448 &time,
00449 &rotation[0], &rotation[1], &rotation[2]) != 4)
00450 returnError(fileName, "Incorrect bone position key");
00451
00452 BoneRotationKey *key = new BoneRotationKey(time, rotation);
00453 bone->addRotationKey(key);
00454 }
00455
00456
00457 model->addBone(bone);
00458 }
00459 }