00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <3dsparse/ASEModelFactory.h>
00022 #include <common/Defines.h>
00023 #include <stdio.h>
00024 #include <math.h>
00025
00026 extern FILE *asein;
00027 extern int aseparse(void);
00028 extern int aselineno;
00029
00030 static ASEModelFactory *factory_ = 0;
00031 static Model *model_ = 0;
00032
00033 ASEModelFactory::ASEModelFactory()
00034 {
00035 }
00036
00037 ASEModelFactory::~ASEModelFactory()
00038 {
00039 }
00040
00041 Model *ASEModelFactory::createModel(const char *fileName,
00042 const char *texName)
00043 {
00044 model_ = new Model();
00045 if (loadFile(fileName))
00046 {
00047 model_->setup();
00048 calculateTexCoords(texName);
00049 }
00050 else
00051 {
00052 delete model_;
00053 model_ = 0;
00054 }
00055
00056 return model_;
00057 }
00058
00059 bool ASEModelFactory::loadFile(const char *fileName)
00060 {
00061 asein = fopen(fileName, "r");
00062 if (!asein)
00063 {
00064 return false;
00065 }
00066
00067
00068 factory_ = this;
00069 aselineno = 0;
00070 return (aseparse() == 0);
00071 }
00072
00073 ASEModelFactory *ASEModelFactory::getCurrent()
00074 {
00075 return factory_;
00076 }
00077
00078 void ASEModelFactory::addMesh(char *meshName)
00079 {
00080 Mesh *mesh = new Mesh(meshName);
00081 model_->addMesh(mesh);
00082 }
00083
00084 Mesh *ASEModelFactory::getCurrentMesh()
00085 {
00086 DIALOG_ASSERT(!model_->getMeshes().empty());
00087 Mesh *mesh = model_->getMeshes().back();
00088 return mesh;
00089 }
00090
00091 Vector ASEModelFactory::getTexCoord(Vector &tri, MaxMag mag, Vector &max, Vector &min)
00092 {
00093 Vector newTri = tri;
00094 newTri -= min;
00095 newTri /= (max - min);
00096
00097 switch(mag)
00098 {
00099 case MagX:
00100 newTri /= 2.0f;
00101 newTri[0] = newTri[1] * 2.0f;
00102 newTri[1] = newTri[2];
00103 break;
00104 case MagY:
00105 newTri /= 2.0f;
00106 newTri[0] = newTri[0];
00107 newTri[1] = newTri[2] + 0.5f;
00108 break;
00109 case MagZ:
00110 newTri /= 2.0f;
00111 newTri[0] += 0.5f;
00112 newTri[1] += 0.5f;
00113 break;
00114 }
00115
00116 return newTri;
00117 }
00118
00119 void ASEModelFactory::calculateTexCoords(const char *texName)
00120 {
00121 std::vector<Mesh *>::iterator itor;
00122 for (itor = model_->getMeshes().begin();
00123 itor != model_->getMeshes().end();
00124 itor++)
00125 {
00126 Mesh *mesh = *itor;
00127 mesh->setTextureName(texName);
00128
00129 std::vector<Face*>::iterator fitor;
00130 for (fitor = mesh->getFaces().begin();
00131 fitor != mesh->getFaces().end();
00132 fitor++)
00133 {
00134 Face &face = *(*fitor);
00135
00136 Vector &triA = mesh->getVertex(face.v[0])->position;
00137 Vector &triB = mesh->getVertex(face.v[1])->position;
00138 Vector &triC = mesh->getVertex(face.v[2])->position;
00139
00140 MaxMag maxMag = MagZ;
00141 Vector faceNormal = (face.normal[0] + face.normal[1] + face.normal[2]).Normalize();
00142 if (fabs(faceNormal[0]) >= fabs(faceNormal[1]) &&
00143 fabs(faceNormal[0]) >= fabs(faceNormal[2]))
00144 {
00145 maxMag = MagX;
00146 }
00147 else if (fabs(faceNormal[1]) >= fabs(faceNormal[0]) &&
00148 fabs(faceNormal[1]) >= fabs(faceNormal[2]))
00149 {
00150 maxMag = MagY;
00151 }
00152
00153 face.tcoord[0] = getTexCoord(triA, maxMag, model_->getMax(), model_->getMin());
00154 face.tcoord[1] = getTexCoord(triB, maxMag, model_->getMax(), model_->getMin());
00155 face.tcoord[2] = getTexCoord(triC, maxMag, model_->getMax(), model_->getMin());
00156 }
00157 }
00158 }
00159