1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
42 #include "OSGConfig.h"
45 #include "OSGGeometry.h"
46 #include "OSGTypedGeoVectorProperty.h"
47 #include "OSGTypedGeoIntegralProperty.h"
48 #include "OSGGeoProperty.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"
59 #include "OSGTextureObjChunk.h"
60 #include "OSGTextureEnvChunk.h"
61 #include "OSGImageFileHandler.h"
63 #include "OSG3DSSceneFileType.h"
67 const Char8
*A3DSSceneFileType::_suffixA
[] = {"3ds"};
69 A3DSSceneFileType
A3DSSceneFileType::_the(_suffixA
,
73 SceneFileType::OSG_READ_SUPPORTED
);
75 NodeTransitPtr
A3DSSceneFileType::read( std::istream
&is
,
80 return NodeTransitPtr(NULL
);
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
));
102 root
->addChild(mesh
);
112 A3DSSceneFileType::A3DSSceneFileType(const Char8
*suffixArray
[],
113 UInt16 suffixByteCount
,
115 UInt32 overridePriority
,
117 SceneFileType(suffixArray
,
127 A3DSSceneFileType
&A3DSSceneFileType::the(void)
133 const Char8
*A3DSSceneFileType::getName(void) const
135 return "3DS Geometry";
139 A3DSSceneFileType::A3DSSceneFileType(const A3DSSceneFileType
&obj
) :
147 A3DSSceneFileType::~A3DSSceneFileType (void )
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();
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
,
176 points
->push_back(Pnt3f(t
.vertices
[1].x
,
180 points
->push_back(Pnt3f(t
.vertices
[2].x
,
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
,
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
);
280 std::string
casename(texname
);
281 for(std::string::reverse_iterator it
= casename
.rbegin();
282 it
!= casename
.rend() && *it
!= '/' && *it
!= '\\';
285 if(*it
>= 'a' && *it
<= 'z')
287 *it
= 'A' + *it
- 'a';
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
,
301 img_ok
= image
->read(casename
.c_str());
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
;
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
330 image
->hasAlphaChannel()) )
332 BlendChunkUnrecPtr blendc
= BlendChunk::create();
334 if(image
!= NULL
&& image
->isAlphaBinary())
336 blendc
->setAlphaFunc(GL_NOTEQUAL
);
337 blendc
->setAlphaValue(0);
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
);