#include <celengine/modelfile.h>#include <celengine/tokenizer.h>#include <celengine/texmanager.h>#include <cel3ds/3dsread.h>#include <cstring>#include <cassert>#include <cmath>#include <cstdio>Include dependency graph for 3dstocmod.cpp:

Go to the source code of this file.
Functions | |
| void | Convert3DSMesh (Model &model, M3DTriangleMesh &mesh3ds, const M3DScene &scene, const string &meshName) |
| static Model * | Convert3DSModel (const M3DScene &scene, const string &texPath) |
| int | main (int argc, char *argv[]) |
| void | usage () |
|
||||||||||||||||||||
|
Definition at line 72 of file 3dstocmod.cpp. References Mesh::addGroup(), M3DColor::blue, cross(), Mesh::Material::diffuse, M3DMaterial::getDiffuseColor(), ResourceManager< T >::getHandle(), M3DMaterial::getName(), M3DMaterial::getOpacity(), M3DMaterial::getShininess(), M3DMaterial::getSpecularColor(), GetTextureManager(), M3DMaterial::getTextureMap(), M3DColor::green, Mesh::Material::maps, norm(), Vector3< T >::normalize(), Mesh::Material::opacity, pow(), M3DColor::red, Mesh::setName(), Mesh::setVertexDescription(), Mesh::setVertices(), Mesh::Material::specular, Mesh::Material::specularPower, Vector3< T >::x, Point3< T >::x, Vector3< T >::y, Point3< T >::y, Vector3< T >::z, and Point3< T >::z. Referenced by Convert3DSModel(). 00076 {
00077 int nFaces = mesh3ds.getFaceCount();
00078 int nVertices = mesh3ds.getVertexCount();
00079 int nTexCoords = mesh3ds.getTexCoordCount();
00080 bool smooth = (mesh3ds.getSmoothingGroupCount() == nFaces);
00081 bool hasTexCoords = (nTexCoords == nVertices);
00082 int vertexSize = hasTexCoords ? 8 : 6;
00083 int i;
00084
00085 Vec3f* faceNormals = new Vec3f[nFaces];
00086 Vec3f* vertexNormals = new Vec3f[nFaces * 3];
00087 int* faceCounts = new int[nVertices];
00088 int** vertexFaces = new int*[nVertices];
00089
00090 int nOutputVertices = nFaces * 3;
00091 float* vertices = new float[nOutputVertices * vertexSize];
00092
00093
00094 for (i = 0; i < nVertices; i++)
00095 {
00096 faceCounts[i] = 0;
00097 vertexFaces[i] = NULL;
00098 }
00099
00100 // generate face normals
00101 for (i = 0; i < nFaces; i++)
00102 {
00103 uint16 v0, v1, v2;
00104 mesh3ds.getFace(i, v0, v1, v2);
00105
00106 faceCounts[v0]++;
00107 faceCounts[v1]++;
00108 faceCounts[v2]++;
00109
00110 Point3f p0 = mesh3ds.getVertex(v0);
00111 Point3f p1 = mesh3ds.getVertex(v1);
00112 Point3f p2 = mesh3ds.getVertex(v2);
00113 faceNormals[i] = cross(p1 - p0, p2 - p1);
00114 faceNormals[i].normalize();
00115 }
00116
00117 if (!smooth && 0)
00118 {
00119 for (i = 0; i < nFaces; i++)
00120 {
00121 vertexNormals[i * 3] = faceNormals[i];
00122 vertexNormals[i * 3 + 1] = faceNormals[i];
00123 vertexNormals[i * 3 + 2] = faceNormals[i];
00124 }
00125 }
00126 else
00127 {
00128 // allocate space for vertex face indices
00129 for (i = 0; i < nVertices; i++)
00130 {
00131 vertexFaces[i] = new int[faceCounts[i] + 1];
00132 vertexFaces[i][0] = faceCounts[i];
00133 }
00134
00135 for (i = 0; i < nFaces; i++)
00136 {
00137 uint16 v0, v1, v2;
00138 mesh3ds.getFace(i, v0, v1, v2);
00139 vertexFaces[v0][faceCounts[v0]--] = i;
00140 vertexFaces[v1][faceCounts[v1]--] = i;
00141 vertexFaces[v2][faceCounts[v2]--] = i;
00142 }
00143
00144 // average face normals to compute the vertex normals
00145 for (i = 0; i < nFaces; i++)
00146 {
00147 uint16 v0, v1, v2;
00148 mesh3ds.getFace(i, v0, v1, v2);
00149 // uint32 smoothingGroups = mesh3ds.getSmoothingGroups(i);
00150
00151 int j;
00152 Vec3f v = Vec3f(0, 0, 0);
00153 for (j = 1; j <= vertexFaces[v0][0]; j++)
00154 {
00155 int k = vertexFaces[v0][j];
00156 // if (k == i || (smoothingGroups & mesh3ds.getSmoothingGroups(k)) != 0)
00157 if (faceNormals[i] * faceNormals[k] > 0.5f)
00158 v += faceNormals[k];
00159 }
00160 if (v * v == 0.0f)
00161 v = Vec3f(1.0f, 0.0f, 0.0f);
00162 v.normalize();
00163 vertexNormals[i * 3] = v;
00164
00165 v = Vec3f(0, 0, 0);
00166 for (j = 1; j <= vertexFaces[v1][0]; j++)
00167 {
00168 int k = vertexFaces[v1][j];
00169 // if (k == i || (smoothingGroups & mesh3ds.getSmoothingGroups(k)) != 0)
00170 if (faceNormals[i] * faceNormals[k] > 0.5f)
00171 v += faceNormals[k];
00172 }
00173 if (v * v == 0.0f)
00174 v = Vec3f(1.0f, 0.0f, 0.0f);
00175 v.normalize();
00176 vertexNormals[i * 3 + 1] = v;
00177
00178 v = Vec3f(0, 0, 0);
00179 for (j = 1; j <= vertexFaces[v2][0]; j++)
00180 {
00181 int k = vertexFaces[v2][j];
00182 // if (k == i || (smoothingGroups & mesh3ds.getSmoothingGroups(k)) != 0)
00183 if (faceNormals[i] * faceNormals[k] > 0.5f)
00184 v += faceNormals[k];
00185 }
00186 if (v * v == 0.0f)
00187 v = Vec3f(1.0f, 0.0f, 0.0f);
00188 v.normalize();
00189 vertexNormals[i * 3 + 2] = v;
00190 }
00191 }
00192
00193 // build the triangle list
00194 for (i = 0; i < nFaces; i++)
00195 {
00196 uint16 triVert[3];
00197 mesh3ds.getFace(i, triVert[0], triVert[1], triVert[2]);
00198
00199 for (int j = 0; j < 3; j++)
00200 {
00201 Point3f pos = mesh3ds.getVertex(triVert[j]);
00202 Vec3f norm = vertexNormals[i * 3 + j];
00203 int k = (i * 3 + j) * vertexSize;
00204
00205 vertices[k + 0] = pos.x;
00206 vertices[k + 1] = pos.y;
00207 vertices[k + 2] = pos.z;
00208 vertices[k + 3] = norm.x;
00209 vertices[k + 4] = norm.y;
00210 vertices[k + 5] = norm.z;
00211 if (hasTexCoords)
00212 {
00213 vertices[k + 6] = mesh3ds.getTexCoord(triVert[j]).x;
00214 vertices[k + 7] = mesh3ds.getTexCoord(triVert[j]).y;
00215 }
00216 }
00217 }
00218
00219 // clean up
00220 if (faceNormals != NULL)
00221 delete[] faceNormals;
00222 if (vertexNormals != NULL)
00223 delete[] vertexNormals;
00224 if (faceCounts != NULL)
00225 delete[] faceCounts;
00226 if (vertexFaces != NULL)
00227 {
00228 for (i = 0; i < nVertices; i++)
00229 {
00230 if (vertexFaces[i] != NULL)
00231 delete[] vertexFaces[i];
00232 }
00233 delete[] vertexFaces;
00234 }
00235
00236
00237 Mesh::VertexAttribute attributes[8];
00238 uint32 nAttributes = 0;
00239 uint32 offset = 0;
00240
00241 // Position attribute is always present
00242 attributes[nAttributes] = Mesh::VertexAttribute(Mesh::Position, Mesh::Float3, 0);
00243 nAttributes++;
00244 offset += 12;
00245
00246 // Normal attribute is always present
00247 attributes[nAttributes] = Mesh::VertexAttribute(Mesh::Normal, Mesh::Float3, offset);
00248 nAttributes++;
00249 offset += 12;
00250
00251 if (hasTexCoords)
00252 {
00253 attributes[nAttributes] = Mesh::VertexAttribute(Mesh::Texture0, Mesh::Float2, offset);
00254 nAttributes++;
00255 offset += 8;
00256 }
00257
00258 // Create the Celestia mesh
00259 Mesh* mesh = new Mesh();
00260 mesh->setVertexDescription(Mesh::VertexDescription(offset, nAttributes, attributes));
00261 mesh->setVertices(nOutputVertices, vertices);
00262
00263 mesh->setName(meshName);
00264
00265 // Vertex lists are not indexed, so the conversion to an indexed format is
00266 // trivial (although much space is wasted storing unnecessary indices.)
00267 uint32* indices = new uint32[nOutputVertices];
00268 for (int i = 0; i < nOutputVertices; i++)
00269 indices[i] = i;
00270
00271 // Convert the 3DS mesh's material
00272 Mesh::Material* material = new Mesh::Material();
00273
00274 string material3dsName = mesh3ds.getMaterialName();
00275 if (material3dsName.length() > 0)
00276 {
00277 int nMaterials = scene.getMaterialCount();
00278 for (int i = 0; i < nMaterials; i++)
00279 {
00280 M3DMaterial* material3ds = scene.getMaterial(i);
00281 if (material3dsName == material3ds->getName())
00282 {
00283 M3DColor diffuse = material3ds->getDiffuseColor();
00284 material->diffuse = Color(diffuse.red, diffuse.green, diffuse.blue);
00285 M3DColor specular = material3ds->getSpecularColor();
00286 material->specular = Color(specular.red, specular.green, specular.blue);
00287 // Map the shininess from the 3DS file into the 0-128
00288 // range that OpenGL uses for the specular exponent.
00289 float specPow = (float) pow(2, 10.0 * material3ds->getShininess());
00290 if (specPow > 128.0f)
00291 specPow = 128.0f;
00292 material->specularPower = specPow;
00293
00294 material->opacity = material3ds->getOpacity();
00295 if (material3ds->getTextureMap() != "")
00296 {
00297 material->maps[Mesh::DiffuseMap] = GetTextureManager()->getHandle(TextureInfo(material3ds->getTextureMap(), ".", TextureInfo::WrapTexture));
00298 }
00299 }
00300 }
00301 }
00302
00303 uint32 materialIndex = model.addMaterial(material) - 1;
00304 mesh->addGroup(Mesh::TriList, materialIndex, nOutputVertices, indices);
00305 model.addMesh(mesh);
00306 }
|
|
||||||||||||
|
Definition at line 310 of file 3dstocmod.cpp. References Convert3DSMesh(), M3DTriangleMesh::getFaceCount(), M3DModel::getName(), and M3DModel::getTriMesh(). 00311 {
00312 Model* model = new Model();
00313 uint32 materialIndex = 0;
00314
00315 for (unsigned int i = 0; i < scene.getModelCount(); i++)
00316 {
00317 M3DModel* model3ds = scene.getModel(i);
00318 if (model3ds != NULL)
00319 {
00320 for (unsigned int j = 0; j < model3ds->getTriMeshCount(); j++)
00321 {
00322 M3DTriangleMesh* mesh = model3ds->getTriMesh(j);
00323
00324 if (mesh != NULL && mesh->getFaceCount() > 0)
00325 {
00326 Convert3DSMesh(*model, *mesh, scene, model3ds->getName());
00327 }
00328 }
00329 }
00330 }
00331
00332 return model;
00333 #if 0
00334 // Sort the vertex lists to make sure that the transparent ones are
00335 // rendered after the opaque ones and material state changes are minimized.
00336 sort(vertexLists.begin(), vertexLists.end(), compareVertexLists);
00337 #endif
00338 }
|
|
||||||||||||
|
Definition at line 31 of file 3dstocmod.cpp. References Convert3DSModel(), Mesh::getGroup(), Model::getMesh(), Mesh::PrimitiveGroup::nIndices, Read3DSFile(), and SaveModelAscii(). 00032 {
00033 if (argc != 2)
00034 {
00035 usage();
00036 return 1;
00037 }
00038
00039 string inputFileName = argv[1];
00040
00041 M3DScene* scene = Read3DSFile(inputFileName);
00042 if (scene == NULL)
00043 {
00044 cerr << "Error reading 3DS file '" << inputFileName << "'\n";
00045 return 1;
00046 }
00047
00048 Model* model = Convert3DSModel(*scene, ".");
00049 if (!model)
00050 {
00051 cerr << "Error converting 3DS file to Celestia model\n";
00052 return 1;
00053 }
00054
00055 for (uint32 i = 0; model->getMesh(i); i++)
00056 {
00057 const Mesh* mesh = model->getMesh(i);
00058 for (uint32 j = 0; mesh->getGroup(j); j++)
00059 {
00060 const Mesh::PrimitiveGroup* group = mesh->getGroup(j);
00061 cerr << "Group: #" << i << ", indices=" << group->nIndices << '\n';
00062 }
00063 }
00064
00065 SaveModelAscii(model, cout);
00066
00067 return 0;
00068 }
|
|
|
Definition at line 25 of file 3dstocmod.cpp. 00026 {
00027 cerr << "Usage: 3dstocmod <input 3ds file>\n";
00028 }
|
1.4.1