OSG3DSSceneFileType.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
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     // create material opensg supports only one material per geometry!
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     //createSharedIndex(geo);
00237     //OSG::calcVertexNormals(geo);
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     // create a texture chunk
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             // 0x0008 means no tiling.
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     // add a blend chunk for transparency
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 }