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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <string>
00041
00042 #include "OSGConfig.h"
00043 #include "OSGLog.h"
00044 #include "OSGNode.h"
00045 #include "OSGGeometry.h"
00046 #include "OSGTypedGeoVectorProperty.h"
00047 #include "OSGTypedGeoIntegralProperty.h"
00048 #include "OSGGeoProperty.h"
00049 #include "OSGGroup.h"
00050 #include "OSGSimpleGeometry.h"
00051 #include "OSGGeoProperty.h"
00052 #include "OSGNameAttachment.h"
00053 #include "OSGTriangleIterator.h"
00054 #include "OSGGeoFunctions.h"
00055 #include "OSGChunkMaterial.h"
00056 #include "OSGMaterialChunk.h"
00057 #include "OSGBlendChunk.h"
00058 #include "OSGImage.h"
00059 #include "OSGTextureObjChunk.h"
00060 #include "OSGTextureEnvChunk.h"
00061 #include "OSGImageFileHandler.h"
00062
00063 #include "OSG3DSSceneFileType.h"
00064
00065 OSG_USING_NAMESPACE
00066
00067 const Char8 *A3DSSceneFileType::_suffixA[] = {"3ds"};
00068
00069 A3DSSceneFileType A3DSSceneFileType::_the(_suffixA,
00070 sizeof(_suffixA),
00071 false,
00072 10,
00073 SceneFileType::OSG_READ_SUPPORTED);
00074
00080 NodePtr A3DSSceneFileType::read(std::istream &is, const Char8 *) const
00081 {
00082 if(!is)
00083 return NullFC;
00084
00085 _materials.clear();
00086
00087 L3DS scene;
00088 if(!scene.Load(is))
00089 {
00090 SWARNING << "Couldn't read from stream!" << std::endl;
00091 return NullFC;
00092 }
00093
00094 NodePtr root = Node::create();
00095 GroupPtr group = Group::create();
00096 root->setCore(group);
00097
00098 for(uint i=0;i<scene.GetMeshCount();++i)
00099 {
00100 NodePtr mesh = createMesh(scene, scene.GetMesh(i));
00101 if(mesh != NullFC)
00102 root->addChild(mesh);
00103 }
00104
00105 return root;
00106 }
00107
00113 A3DSSceneFileType::A3DSSceneFileType(const Char8 *suffixArray[],
00114 UInt16 suffixByteCount,
00115 bool override,
00116 UInt32 overridePriority,
00117 UInt32 flags) :
00118 SceneFileType(suffixArray,
00119 suffixByteCount,
00120 override,
00121 overridePriority,
00122 flags)
00123 {
00124 }
00125
00126
00132 A3DSSceneFileType &A3DSSceneFileType::the(void)
00133 {
00134 return _the;
00135 }
00136
00137
00143 const Char8 *A3DSSceneFileType::getName(void) const
00144 {
00145 return "3DS Geometry";
00146 }
00147
00148
00154 A3DSSceneFileType::A3DSSceneFileType(const A3DSSceneFileType &obj) :
00155 SceneFileType(obj),
00156 _materials()
00157 {
00158 return;
00159 }
00160
00161
00167 A3DSSceneFileType::~A3DSSceneFileType (void )
00168 {
00169 return;
00170 }
00171
00177 NodePtr A3DSSceneFileType::createMesh(L3DS &scene, LMesh &mesh) const
00178 {
00179 if(mesh.GetTriangleCount() == 0)
00180 return NullFC;
00181
00182 NodePtr node = Node::create();
00183 GeometryPtr geo = Geometry::create();
00184
00185 node->setCore(geo);
00186
00187 OSG::setName(node, mesh.GetName().c_str());
00188
00189 GeoPnt3fPropertyPtr points = GeoPnt3fProperty::create();
00190 GeoVec3fPropertyPtr normals = GeoVec3fProperty::create();
00191 GeoVec2fPropertyPtr texcoords = GeoVec2fProperty::create();
00192
00193 for(UInt32 i=0;i<mesh.GetTriangleCount();++i)
00194 {
00195 const LTriangle2 &t = mesh.GetTriangle2(i);
00196
00197 points->push_back(Pnt3f(t.vertices[0].x, t.vertices[0].y, t.vertices[0].z));
00198 points->push_back(Pnt3f(t.vertices[1].x, t.vertices[1].y, t.vertices[1].z));
00199 points->push_back(Pnt3f(t.vertices[2].x, t.vertices[2].y, t.vertices[2].z));
00200
00201 normals->push_back(Vec3f(t.vertexNormals[0].x, t.vertexNormals[0].y, t.vertexNormals[0].z));
00202 normals->push_back(Vec3f(t.vertexNormals[1].x, t.vertexNormals[1].y, t.vertexNormals[1].z));
00203 normals->push_back(Vec3f(t.vertexNormals[2].x, t.vertexNormals[2].y, t.vertexNormals[2].z));
00204
00205 texcoords->push_back(Vec2f(t.textureCoords[0].x, t.textureCoords[0].y));
00206 texcoords->push_back(Vec2f(t.textureCoords[1].x, t.textureCoords[1].y));
00207 texcoords->push_back(Vec2f(t.textureCoords[2].x, t.textureCoords[2].y));
00208 }
00209
00210
00211 MaterialPtr mat = OSG::getDefaultMaterial();
00212 if(mesh.GetMaterialCount() > 0)
00213 mat = createMaterial(scene, mesh.GetMaterial(0));
00214
00215 int nv = mesh.GetTriangleCount() * 3;
00216
00217 GeoUInt32PropertyPtr indices = GeoUInt32Property::create();
00218 indices->editFieldPtr()->reserve(nv);
00219 for (int i = 0; i < nv; ++i)
00220 indices->push_back(i);
00221
00222 GeoUInt32PropertyPtr lengths = GeoUInt32Property::create();
00223 lengths->push_back(nv);
00224
00225 GeoUInt8PropertyPtr types = GeoUInt8Property::create();
00226 types->push_back(GL_TRIANGLES);
00227
00228 geo->setMaterial(mat);
00229 geo->setPositions(points);
00230 geo->setNormals(normals);
00231 geo->setTexCoords(texcoords);
00232 geo->setIndices(indices);
00233 geo->setLengths(lengths);
00234 geo->setTypes(types);
00235
00236
00237
00238
00239 return node;
00240 }
00241
00242 MaterialPtr A3DSSceneFileType::createMaterial(L3DS &scene, UInt32 id) const
00243 {
00244 materialIt mi = _materials.find(id);
00245 if(mi != _materials.end())
00246 return (*mi).second;
00247
00248 LMaterial m = scene.GetMaterial(id);
00249
00250 ChunkMaterialPtr cmat = ChunkMaterial::create();
00251
00252 OSG::setName(cmat, m.GetName());
00253
00254 MaterialChunkPtr matc = MaterialChunk::create();
00255
00256 cmat->addChunk(matc);
00257
00258 Real32 t = m.GetTransparency();
00259
00260 matc->setAmbient(Color4f(m.GetAmbientColor().r, m.GetAmbientColor().g,
00261 m.GetAmbientColor().b, 1.0f - t));
00262 matc->setDiffuse(Color4f(m.GetDiffuseColor().r, m.GetDiffuseColor().g,
00263 m.GetDiffuseColor().b, 1.0f - t));
00264 matc->setSpecular(Color4f(m.GetSpecularColor().r, m.GetSpecularColor().g,
00265 m.GetSpecularColor().b, 1.0f - t));
00266 matc->setEmission(Color4f(0.0f, 0.0f, 0.0f, 1.0f - t));
00267 matc->setShininess(m.GetShininess() * 128.0f);
00268
00269
00270
00271 LMap &map = m.GetTextureMap1();
00272 const char *texname = map.mapName;
00273 ImagePtr image = NullFC;
00274 if(texname != NULL && strlen(texname) > 0)
00275 {
00276 image = Image::create();
00277 bool img_ok = image->read(texname);
00278
00279 if(!img_ok)
00280 {
00281 std::string casename(texname);
00282 for(std::string::reverse_iterator it = casename.rbegin();
00283 it != casename.rend() && *it != '/' && *it != '\\';
00284 ++it)
00285 {
00286 if(*it >= 'a' && *it <= 'z')
00287 {
00288 *it = 'A' + *it - 'a';
00289 }
00290 else
00291 if(*it >= 'A' && *it <= 'Z')
00292 {
00293 *it = 'a' + *it - 'A';
00294 }
00295
00296 }
00297
00298 FWARNING(("Couldn't load image '%s', trying case "
00299 "reversed version '%s'! \n", texname,
00300 casename.c_str()));
00301
00302 img_ok = image->read(casename.c_str());
00303 }
00304
00305 if(img_ok)
00306 {
00307 image->setForceAlphaBinary(image->calcIsAlphaBinary());
00308
00309 TextureObjChunkPtr texc = TextureObjChunk::create();
00310 TextureEnvChunkPtr texec = TextureEnvChunk::create();
00311
00312 texc->setImage(image);
00313
00314
00315 GLenum wm = (map.tiling & 0x0008) ? GL_CLAMP_TO_EDGE : GL_REPEAT;
00316 texc->setWrapS(wm);
00317 texc->setWrapT(wm);
00318
00319 texec->setEnvMode(GL_MODULATE);
00320 texc ->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
00321 texc ->setMagFilter(GL_LINEAR);
00322
00323 cmat->addChunk(texc);
00324 cmat->addChunk(texec);
00325 }
00326 }
00327
00328
00329 if(t > 0.0 ||
00330 ( image != NullFC &&
00331 image->hasAlphaChannel()
00332 ))
00333 {
00334 BlendChunkPtr blendc = BlendChunk::create();
00335
00336 if(image != NullFC && image->isAlphaBinary())
00337 {
00338 blendc->setAlphaFunc(GL_NOTEQUAL);
00339 blendc->setAlphaValue(0);
00340 }
00341 else
00342 {
00343 blendc->setSrcFactor(GL_SRC_ALPHA);
00344 blendc->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
00345 }
00346
00347 cmat->addChunk(blendc);
00348 }
00349
00350 _materials.insert(std::pair<UInt32, MaterialPtr>(id, cmat));
00351
00352 return cmat;
00353 }