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 NodeTransitPtr A3DSSceneFileType::read(      std::istream &is,
00081                                        const Char8        *,
00082                                              Resolver        ) const
00083 {
00084     if(!is)
00085         return NodeTransitPtr(NULL);
00086
00087     _materials.clear();
00088
00089     L3DS scene;
00090
00091     if(!scene.Load(is))
00092     {
00093         SWARNING << "Couldn't read from stream!" << std::endl;
00094
00095         return NodeTransitPtr(NULL);
00096     }
00097
00098     NodeTransitPtr  root = Node::create();
00099
00100     root->setCore(Group::create());
00101
00102     for(uint i=0;i<scene.GetMeshCount();++i)
00103     {
00104         NodeUnrecPtr mesh = createMesh(scene, scene.GetMesh(i));
00105
00106         if(mesh != NULL)
00107             root->addChild(mesh);
00108     }
00109
00110     _materials.clear();
00111
00112     return root;
00113 }
00114
00120 A3DSSceneFileType::A3DSSceneFileType(const Char8  *suffixArray[],
00121                                          UInt16  suffixByteCount,
00122                                          bool    override,
00123                                          UInt32  overridePriority,
00124                                          UInt32  flags) :
00125     SceneFileType(suffixArray,
00126                   suffixByteCount,
00127                   override,
00128                   overridePriority,
00129                   flags)
00130 {
00131 }
00132
00133
00139 A3DSSceneFileType &A3DSSceneFileType::the(void)
00140 {
00141     return _the;
00142 }
00143
00144
00150 const Char8 *A3DSSceneFileType::getName(void) const
00151 {
00152     return "3DS Geometry";
00153 }
00154
00155
00161 A3DSSceneFileType::A3DSSceneFileType(const A3DSSceneFileType &obj) :
00162     SceneFileType(obj),
00163     _materials()
00164 {
00165     return;
00166 }
00167
00168
00174 A3DSSceneFileType::~A3DSSceneFileType (void )
00175 {
00176     return;
00177 }
00178
00184 NodeTransitPtr A3DSSceneFileType::createMesh(L3DS &scene, LMesh &mesh) const
00185 {
00186     if(mesh.GetTriangleCount() == 0)
00187         return NodeTransitPtr(NULL);
00188
00189     NodeUnrecPtr     node = Node::create();
00190     GeometryUnrecPtr geo = Geometry::create();
00191
00192     node->setCore(geo);
00193
00194     OSG::setName(node, mesh.GetName().c_str());
00195
00196     GeoPnt3fPropertyUnrecPtr points    = GeoPnt3fProperty::create();
00197     GeoVec3fPropertyUnrecPtr normals   = GeoVec3fProperty::create();
00198     GeoVec2fPropertyUnrecPtr texcoords = GeoVec2fProperty::create();
00199
00200     for(UInt32 i=0;i<mesh.GetTriangleCount();++i)
00201     {
00202         const LTriangle2 &t = mesh.GetTriangle2(i);
00203
00204         points->push_back(Pnt3f(t.vertices[0].x,
00205                                 t.vertices[0].y,
00206                                 t.vertices[0].z));
00207
00208         points->push_back(Pnt3f(t.vertices[1].x,
00209                                 t.vertices[1].y,
00210                                 t.vertices[1].z));
00211
00212         points->push_back(Pnt3f(t.vertices[2].x,
00213                                 t.vertices[2].y,
00214                                 t.vertices[2].z));
00215
00216         normals->push_back(Vec3f(t.vertexNormals[0].x,
00217                                  t.vertexNormals[0].y,
00218                                  t.vertexNormals[0].z));
00219
00220         normals->push_back(Vec3f(t.vertexNormals[1].x,
00221                                  t.vertexNormals[1].y,
00222                                  t.vertexNormals[1].z));
00223
00224         normals->push_back(Vec3f(t.vertexNormals[2].x,
00225                                  t.vertexNormals[2].y,
00226                                  t.vertexNormals[2].z));
00227
00228         texcoords->push_back(Vec2f(t.textureCoords[0].x, t.textureCoords[0].y));
00229         texcoords->push_back(Vec2f(t.textureCoords[1].x, t.textureCoords[1].y));
00230         texcoords->push_back(Vec2f(t.textureCoords[2].x, t.textureCoords[2].y));
00231     }
00232
00233     // create material opensg supports only one material per geometry!
00234     MaterialUnrecPtr mat = OSG::getDefaultMaterial();
00235
00236     if(mesh.GetMaterialCount() > 0)
00237         mat = createMaterial(scene, mesh.GetMaterial(0));
00238
00239     int nv = mesh.GetTriangleCount() * 3;
00240
00241     GeoUInt32PropertyUnrecPtr indices = GeoUInt32Property::create();
00242
00243     indices->editFieldPtr()->reserve(nv);
00244
00245     for (int i = 0; i < nv; ++i)
00246         indices->push_back(i);
00247
00248     GeoUInt32PropertyUnrecPtr lengths = GeoUInt32Property::create();
00249
00250     lengths->push_back(nv);
00251
00252     GeoUInt8PropertyUnrecPtr types = GeoUInt8Property::create();
00253     types->push_back(GL_TRIANGLES);
00254
00255     geo->setMaterial(mat);
00256     geo->setPositions(points);
00257     geo->setNormals(normals);
00258     geo->setTexCoords(texcoords);
00259     geo->setIndices(indices);
00260     geo->setLengths(lengths);
00261     geo->setTypes(types);
00262
00263     //createSharedIndex(geo);
00264     //OSG::calcVertexNormals(geo);
00265
00266     return NodeTransitPtr(node);
00267 }
00268
00269 MaterialTransitPtr A3DSSceneFileType::createMaterial(L3DS   &scene,
00270                                                      UInt32  id   ) const
00271 {
00272     materialIt mi = _materials.find(id);
00273
00274     if(mi != _materials.end())
00275         return MaterialTransitPtr((*mi).second);
00276
00277     LMaterial m = scene.GetMaterial(id);
00278
00279     ChunkMaterialUnrecPtr cmat = ChunkMaterial::create();
00280
00281     OSG::setName(cmat, m.GetName());
00282
00283     MaterialChunkUnrecPtr matc = MaterialChunk::create();
00284
00285     cmat->addChunk(matc);
00286
00287     Real32 t = m.GetTransparency();
00288
00289     matc->setAmbient(Color4f(m.GetAmbientColor().r, m.GetAmbientColor().g,
00290                      m.GetAmbientColor().b, 1.0f - t));
00291     matc->setDiffuse(Color4f(m.GetDiffuseColor().r, m.GetDiffuseColor().g,
00292                      m.GetDiffuseColor().b, 1.0f - t));
00293     matc->setSpecular(Color4f(m.GetSpecularColor().r, m.GetSpecularColor().g,
00294                      m.GetSpecularColor().b, 1.0f - t));
00295     matc->setEmission(Color4f(0.0f, 0.0f, 0.0f, 1.0f - t));
00296     matc->setShininess(m.GetShininess() * 128.0f);
00297
00298
00299     // create a texture chunk
00300     LMap &map = m.GetTextureMap1();
00301     const char *texname = map.mapName;
00302
00303     ImageUnrecPtr image = NULL;
00304
00305     if(texname != NULL && strlen(texname) > 0)
00306     {
00307         image = Image::create();
00308         bool img_ok = image->read(texname);
00309
00310         if(!img_ok)
00311         {
00312             std::string casename(texname);
00313             for(std::string::reverse_iterator it = casename.rbegin();
00314                 it != casename.rend() && *it != '/' && *it != '\\';
00315                 ++it)
00316             {
00317                 if(*it >= 'a' && *it <= 'z')
00318                 {
00319                     *it = 'A' + *it - 'a';
00320                 }
00321                 else
00322                 if(*it >= 'A' && *it <= 'Z')
00323                 {
00324                     *it = 'a' + *it - 'A';
00325                 }
00326
00327             }
00328
00329             FWARNING(("Couldn't load image '%s', trying case "
00330                       "reversed version '%s'! \n", texname,
00331                       casename.c_str()));
00332
00333             img_ok = image->read(casename.c_str());
00334         }
00335
00336         if(img_ok)
00337         {
00338             image->setForceAlphaBinary(image->calcIsAlphaBinary());
00339
00340             TextureObjChunkUnrecPtr texc  = TextureObjChunk::create();
00341             TextureEnvChunkUnrecPtr texec = TextureEnvChunk::create();
00342
00343             texc->setImage(image);
00344
00345             // 0x0008 means no tiling.
00346             GLenum wm = (map.tiling & 0x0008) ? GL_CLAMP_TO_EDGE : GL_REPEAT;
00347             texc->setWrapS(wm);
00348             texc->setWrapT(wm);
00349
00350             texec->setEnvMode(GL_MODULATE);
00351             texc ->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
00352             texc ->setMagFilter(GL_LINEAR);
00353
00354             cmat->addChunk(texc);
00355             cmat->addChunk(texec);
00356         }
00357     }
00358
00359     // add a blend chunk for transparency
00360     if(t > 0.0 ||
00361        ( image != NULL &&
00362          image->hasAlphaChannel()) )
00363     {
00364         BlendChunkUnrecPtr blendc = BlendChunk::create();
00365
00366         if(image != NULL && image->isAlphaBinary())
00367         {
00368             blendc->setAlphaFunc(GL_NOTEQUAL);
00369             blendc->setAlphaValue(0);
00370         }
00371         else
00372         {
00373             blendc->setSrcFactor(GL_SRC_ALPHA);
00374             blendc->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
00375         }
00376
00377         cmat->addChunk(blendc);
00378     }
00379
00380     _materials.insert(std::pair<UInt32, MaterialUnrecPtr>(
00381                           id, MaterialUnrecPtr(cmat)));
00382
00383     return MaterialTransitPtr(cmat);
00384 }