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 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
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
00264
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
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
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
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 }