fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / FileIO / 3DS / OSG3DSSceneFileType.cpp
blob2ab77aa29daec73d4e7120766a981aac374b8985
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
40 #include <string>
42 #include "OSGConfig.h"
43 #include "OSGLog.h"
44 #include "OSGNode.h"
45 #include "OSGGeometry.h"
46 #include "OSGTypedGeoVectorProperty.h"
47 #include "OSGTypedGeoIntegralProperty.h"
48 #include "OSGGeoProperty.h"
49 #include "OSGGroup.h"
50 #include "OSGSimpleGeometry.h"
51 #include "OSGGeoProperty.h"
52 #include "OSGNameAttachment.h"
53 #include "OSGTriangleIterator.h"
54 #include "OSGGeoFunctions.h"
55 #include "OSGChunkMaterial.h"
56 #include "OSGMaterialChunk.h"
57 #include "OSGBlendChunk.h"
58 #include "OSGImage.h"
59 #include "OSGTextureObjChunk.h"
60 #include "OSGTextureEnvChunk.h"
61 #include "OSGImageFileHandler.h"
63 #include "OSG3DSSceneFileType.h"
65 OSG_USING_NAMESPACE
67 const Char8 *A3DSSceneFileType::_suffixA[] = {"3ds"};
69 A3DSSceneFileType A3DSSceneFileType::_the(_suffixA,
70 sizeof(_suffixA),
71 false,
72 10,
73 SceneFileType::OSG_READ_SUPPORTED);
75 NodeTransitPtr A3DSSceneFileType::read( std::istream &is,
76 const Char8 *,
77 Resolver ) const
79 if(!is)
80 return NodeTransitPtr(NULL);
82 _materials.clear();
84 L3DS scene;
86 if(!scene.Load(is))
88 SWARNING << "Couldn't read from stream!" << std::endl;
90 return NodeTransitPtr(NULL);
93 NodeTransitPtr root = Node::create();
95 root->setCore(Group::create());
97 for(uint i=0;i<scene.GetMeshCount();++i)
99 NodeUnrecPtr mesh = createMesh(scene, scene.GetMesh(i));
101 if(mesh != NULL)
102 root->addChild(mesh);
105 _materials.clear();
107 commitChanges();
109 return root;
112 A3DSSceneFileType::A3DSSceneFileType(const Char8 *suffixArray[],
113 UInt16 suffixByteCount,
114 bool override,
115 UInt32 overridePriority,
116 UInt32 flags) :
117 SceneFileType(suffixArray,
118 suffixByteCount,
119 override,
120 overridePriority,
121 flags),
122 _materials()
127 A3DSSceneFileType &A3DSSceneFileType::the(void)
129 return _the;
133 const Char8 *A3DSSceneFileType::getName(void) const
135 return "3DS Geometry";
139 A3DSSceneFileType::A3DSSceneFileType(const A3DSSceneFileType &obj) :
140 SceneFileType(obj),
141 _materials()
143 return;
147 A3DSSceneFileType::~A3DSSceneFileType (void )
149 return;
152 NodeTransitPtr A3DSSceneFileType::createMesh(L3DS &scene, LMesh &mesh) const
154 if(mesh.GetTriangleCount() == 0)
155 return NodeTransitPtr(NULL);
157 NodeUnrecPtr node = Node::create();
158 GeometryUnrecPtr geo = Geometry::create();
160 node->setCore(geo);
162 OSG::setName(node, mesh.GetName().c_str());
164 GeoPnt3fPropertyUnrecPtr points = GeoPnt3fProperty::create();
165 GeoVec3fPropertyUnrecPtr normals = GeoVec3fProperty::create();
166 GeoVec2fPropertyUnrecPtr texcoords = GeoVec2fProperty::create();
168 for(UInt32 i=0;i<mesh.GetTriangleCount();++i)
170 const LTriangle2 &t = mesh.GetTriangle2(i);
172 points->push_back(Pnt3f(t.vertices[0].x,
173 t.vertices[0].y,
174 t.vertices[0].z));
176 points->push_back(Pnt3f(t.vertices[1].x,
177 t.vertices[1].y,
178 t.vertices[1].z));
180 points->push_back(Pnt3f(t.vertices[2].x,
181 t.vertices[2].y,
182 t.vertices[2].z));
184 normals->push_back(Vec3f(t.vertexNormals[0].x,
185 t.vertexNormals[0].y,
186 t.vertexNormals[0].z));
188 normals->push_back(Vec3f(t.vertexNormals[1].x,
189 t.vertexNormals[1].y,
190 t.vertexNormals[1].z));
192 normals->push_back(Vec3f(t.vertexNormals[2].x,
193 t.vertexNormals[2].y,
194 t.vertexNormals[2].z));
196 texcoords->push_back(Vec2f(t.textureCoords[0].x, t.textureCoords[0].y));
197 texcoords->push_back(Vec2f(t.textureCoords[1].x, t.textureCoords[1].y));
198 texcoords->push_back(Vec2f(t.textureCoords[2].x, t.textureCoords[2].y));
201 // create material opensg supports only one material per geometry!
202 MaterialUnrecPtr mat = OSG::getDefaultMaterial();
204 if(mesh.GetMaterialCount() > 0)
205 mat = createMaterial(scene, mesh.GetMaterial(0));
207 int nv = mesh.GetTriangleCount() * 3;
209 GeoUInt32PropertyUnrecPtr indices = GeoUInt32Property::create();
211 indices->editFieldPtr()->reserve(nv);
213 for (int i = 0; i < nv; ++i)
214 indices->push_back(i);
216 GeoUInt32PropertyUnrecPtr lengths = GeoUInt32Property::create();
218 lengths->push_back(nv);
220 GeoUInt8PropertyUnrecPtr types = GeoUInt8Property::create();
221 types->push_back(GL_TRIANGLES);
223 geo->setMaterial(mat);
224 geo->setPositions(points);
225 geo->setNormals(normals);
226 geo->setTexCoords(texcoords);
227 geo->setIndices(indices);
228 geo->setLengths(lengths);
229 geo->setTypes(types);
231 //createSharedIndex(geo);
232 //OSG::calcVertexNormals(geo);
234 return NodeTransitPtr(node);
237 MaterialTransitPtr A3DSSceneFileType::createMaterial(L3DS &scene,
238 UInt32 id ) const
240 materialIt mi = _materials.find(id);
242 if(mi != _materials.end())
243 return MaterialTransitPtr((*mi).second);
245 LMaterial m = scene.GetMaterial(id);
247 ChunkMaterialUnrecPtr cmat = ChunkMaterial::create();
249 OSG::setName(cmat, m.GetName());
251 MaterialChunkUnrecPtr matc = MaterialChunk::create();
253 cmat->addChunk(matc);
255 Real32 t = m.GetTransparency();
257 matc->setAmbient(Color4f(m.GetAmbientColor().r, m.GetAmbientColor().g,
258 m.GetAmbientColor().b, 1.0f - t));
259 matc->setDiffuse(Color4f(m.GetDiffuseColor().r, m.GetDiffuseColor().g,
260 m.GetDiffuseColor().b, 1.0f - t));
261 matc->setSpecular(Color4f(m.GetSpecularColor().r, m.GetSpecularColor().g,
262 m.GetSpecularColor().b, 1.0f - t));
263 matc->setEmission(Color4f(0.0f, 0.0f, 0.0f, 1.0f - t));
264 matc->setShininess(m.GetShininess() * 128.0f);
267 // create a texture chunk
268 LMap &map = m.GetTextureMap1();
269 const char *texname = map.mapName;
271 ImageUnrecPtr image = NULL;
273 if(texname != NULL && strlen(texname) > 0)
275 image = Image::create();
276 bool img_ok = image->read(texname);
278 if(!img_ok)
280 std::string casename(texname);
281 for(std::string::reverse_iterator it = casename.rbegin();
282 it != casename.rend() && *it != '/' && *it != '\\';
283 ++it)
285 if(*it >= 'a' && *it <= 'z')
287 *it = 'A' + *it - 'a';
289 else
290 if(*it >= 'A' && *it <= 'Z')
292 *it = 'a' + *it - 'A';
297 FWARNING(("Couldn't load image '%s', trying case "
298 "reversed version '%s'! \n", texname,
299 casename.c_str()));
301 img_ok = image->read(casename.c_str());
304 if(img_ok)
306 image->setForceAlphaBinary(image->calcIsAlphaBinary());
308 TextureObjChunkUnrecPtr texc = TextureObjChunk::create();
309 TextureEnvChunkUnrecPtr texec = TextureEnvChunk::create();
311 texc->setImage(image);
313 // 0x0008 means no tiling.
314 GLenum wm = (map.tiling & 0x0008) ? GL_CLAMP_TO_EDGE : GL_REPEAT;
315 texc->setWrapS(wm);
316 texc->setWrapT(wm);
318 texec->setEnvMode(GL_MODULATE);
319 texc ->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
320 texc ->setMagFilter(GL_LINEAR);
322 cmat->addChunk(texc);
323 cmat->addChunk(texec);
327 // add a blend chunk for transparency
328 if(t > 0.0 ||
329 ( image != NULL &&
330 image->hasAlphaChannel()) )
332 BlendChunkUnrecPtr blendc = BlendChunk::create();
334 if(image != NULL && image->isAlphaBinary())
336 blendc->setAlphaFunc(GL_NOTEQUAL);
337 blendc->setAlphaValue(0);
339 else
341 blendc->setSrcFactor(GL_SRC_ALPHA);
342 blendc->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
345 cmat->addChunk(blendc);
348 _materials.insert(std::pair<UInt32, MaterialUnrecPtr>(
349 id, MaterialUnrecPtr(cmat)));
351 return MaterialTransitPtr(cmat);