--- Irrlicht.org/CSceneManager.cpp 2006-03-22 11:35:15.000000000 +0100 +++ Irrlicht.new/CSceneManager.cpp 2006-03-30 17:40:43.000000000 +0200 @@ -15,6 +15,7 @@ #include "CDefaultMeshFormatLoader.h" #include "C3DSMeshFileLoader.h" +#include "CDXFMeshFileLoader.h" #include "CXMeshFileLoader.h" #include "COCTLoader.h" #include "CCSMLoader.h" @@ -100,6 +102,7 @@ MeshLoaderList.push_back(new CDefaultMeshFormatLoader(FileSystem, Driver)); MeshLoaderList.push_back(new C3DSMeshFileLoader(FileSystem, Driver)); + MeshLoaderList.push_back(new CDXFMeshFileLoader(FileSystem, Driver)); MeshLoaderList.push_back(new CXMeshFileLoader(MeshManipulator, Driver)); MeshLoaderList.push_back(new COCTLoader(Driver)); MeshLoaderList.push_back(new CCSMLoader(this, FileSystem)); --- Irrlicht.org/CDXFMeshFileLoader.h 2006-04-03 13:24:09.754688939 +0200 +++ Irrlicht.new/CDXFMeshFileLoader.h 2006-04-03 13:24:52.823037132 +0200 @@ -0,0 +1,57 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DXF_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_DXF_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "irrString.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading dxf meshes. +class CDXFMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CDXFMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver); + + //! destructor + virtual ~CDXFMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const c8* fileName); + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IUnknown::drop() for more information. + virtual IAnimatedMesh* createMesh(irr::io::IReadFile* file); + +private: + core::stringc getNextToken(io::IReadFile* file); + bool getNextFace(io::IReadFile* file, SMeshBuffer* mb); + bool getNextVertex(io::IReadFile* file, SMeshBuffer* mb); + + io::IFileSystem* FileSystem; + video::IVideoDriver* Driver; + SMesh* Mesh; + u32 polycount, polydim; + bool polyClosed, polymeshClosed; +}; + +} // end namespace scene +} // end namespace irr + +#endif + --- Irrlicht.org/CDXFMeshFileLoader.cpp 2006-04-03 13:23:41.787009385 +0200 +++ Irrlicht.new/CDXFMeshFileLoader.cpp 2006-04-03 13:24:55.973550607 +0200 @@ -0,0 +1,317 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CDXFMeshFileLoader.h" +#include "os.h" +#include "irrString.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "fast_atof.h" + +namespace irr +{ +namespace scene +{ + +//! Constructor +CDXFMeshFileLoader::CDXFMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver) +: FileSystem(fs), Driver(driver), Mesh(0), polycount(0), polydim(0) +{ + if (FileSystem) + FileSystem->grab(); + + if (Driver) + Driver->grab(); +} + + + +//! destructor +CDXFMeshFileLoader::~CDXFMeshFileLoader() +{ + if (FileSystem) + FileSystem->drop(); + + if (Driver) + Driver->drop(); + + if (Mesh) + Mesh->drop(); +} + + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CDXFMeshFileLoader::isALoadableFileExtension(const c8* filename) +{ + return strstr(filename, ".dxf")!=0; +} + + +// returns next line contents (token) +core::stringc CDXFMeshFileLoader::getNextToken(io::IReadFile* file) +{ + core::stringc out; + c8 c; + file->read(&c, sizeof(c8)); + while(isspace(c)) + file->read(&c, sizeof(c8)); + while(isprint(c)) { + out.append(c); + file->read(&c, sizeof(c8)); + } + while((c!='\n')&&(c!='\r')&&isspace(c)) + file->read(&c, sizeof(c8)); + out.trim(); + return out; +} + +bool CDXFMeshFileLoader::getNextVertex(io::IReadFile* file, scene::SMeshBuffer *mb) { + // skip name + while (getNextToken(file)!="10") + getNextToken(file); + core::vector3df vertex; + vertex.X=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="20") { + return false; + } + vertex.Y=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="30") { + return false; + } + vertex.Z=core::fast_atof(getNextToken(file).c_str()); + core::stringc token=getNextToken(file); + if (token=="70") { + token=getNextToken(file); + if ((token=="192")||(token=="64")) { + video::S3DVertex vtx; + vtx.Color.set(255,255,255,255); + vtx.Pos=vertex; + mb->Vertices.push_back(vtx); + } else if (token=="128") { + int ind[4]; + getNextToken(file); + ind[0]=atol(getNextToken(file).c_str())-1; + getNextToken(file); + ind[1]=atol(getNextToken(file).c_str())-1; + getNextToken(file); + ind[2]=atol(getNextToken(file).c_str())-1; + getNextToken(file); + ind[3]=atol(getNextToken(file).c_str())-1; + mb->Indices.push_back(ind[0]); + mb->Indices.push_back(ind[2]); + mb->Indices.push_back(ind[1]); + mb->Indices.push_back(ind[2]); + mb->Indices.push_back(ind[0]); + mb->Indices.push_back(ind[3]); + } + } + getNextToken(file); + return true; +} + + +bool CDXFMeshFileLoader::getNextFace(io::IReadFile* file, scene::SMeshBuffer *mb) { + // skip name + while (getNextToken(file)!="10") + getNextToken(file); + core::stringc token; + core::vector3df face[4]; + face[0].X=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="20") { + return false; + } + face[0].Y=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="30") { + return false; + } + face[0].Z=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="11") { + return false; + } + face[1].X=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="21") { + return false; + } + face[1].Y=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="31") { + return false; + } + face[1].Z=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="12") { + return false; + } + face[2].X=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="22") { + return false; + } + face[2].Y=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="32") { + return false; + } + face[2].Z=core::fast_atof(getNextToken(file).c_str()); + if ((token=getNextToken(file))!="13") { + face[3]=face[2]; + } else { + face[3].X=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="23") { + return false; + } + face[3].Y=core::fast_atof(getNextToken(file).c_str()); + if (getNextToken(file)!="33") { + return false; + } + face[3].Z=core::fast_atof(getNextToken(file).c_str()); + } + // skip flags + if (token!="0") + while (getNextToken(file)!="0") { + getNextToken(file); + } + + // handle data + video::S3DVertex vtx; + s32 idx = mb->getVertexCount(); + vtx.Color.set(255,255,255,255); + vtx.Pos=face[0]; + mb->Vertices.push_back(vtx); + vtx.Pos=face[1]; + mb->Vertices.push_back(vtx); + vtx.Pos=face[2]; + mb->Vertices.push_back(vtx); + mb->Indices.push_back(idx); + mb->Indices.push_back(idx+1); + mb->Indices.push_back(idx+2); + if (face[2]!=face[3]) { + vtx.Pos=face[3]; + mb->Vertices.push_back(vtx); + mb->Indices.push_back(idx+2); + mb->Indices.push_back(idx+3); + mb->Indices.push_back(idx); + } + return true; +} + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IUnknown::drop() for more information. +IAnimatedMesh* CDXFMeshFileLoader::createMesh(io::IReadFile* file) +{ + if (!file) + return 0; + + file->seek(0); + + if (Mesh) + Mesh->drop(); + Mesh = new SMesh(); + + SMeshBuffer* mb = new scene::SMeshBuffer(); + Mesh->addMeshBuffer(mb); + mb->drop(); + mb->Material.MaterialType = video::EMT_SOLID; + + core::stringc token; + getNextToken(file); + while(1) { + token=getNextToken(file); + if (token=="EOF") + break; + else if (token=="SEQEND") { + if (polycount && polydim) { + u32 i,j; + for (i=0; iIndices.push_back(i*polydim+j); + mb->Indices.push_back(i*polydim+polydim+j); + mb->Indices.push_back(i*polydim+j+1); + mb->Indices.push_back(i*polydim+j+1); + mb->Indices.push_back(i*polydim+polydim+j); + mb->Indices.push_back(i*polydim+polydim+j+1); + } + if (polyClosed) { + mb->Indices.push_back(i*polydim+polydim-1); + mb->Indices.push_back(i*polydim+2*polydim-1); + mb->Indices.push_back(i*polydim); + mb->Indices.push_back(i*polydim); + mb->Indices.push_back(i*polydim+2*polydim-1); + mb->Indices.push_back(i*polydim+polydim); + } + } + if (polymeshClosed) { + for (j=0; jIndices.push_back((polycount-1)*polydim+j); + mb->Indices.push_back(j); + mb->Indices.push_back((polycount-1)*polydim+j+1); + mb->Indices.push_back((polycount-1)*polydim+j+1); + mb->Indices.push_back(j); + mb->Indices.push_back(j+1); + } + if (polyClosed) { + mb->Indices.push_back(polycount*polydim-1); + mb->Indices.push_back(polydim-1); + mb->Indices.push_back((polycount-1)*polydim); + mb->Indices.push_back(polydim-1); + mb->Indices.push_back(0); + mb->Indices.push_back((polycount-1)*polydim); + } + } + } + polycount=polydim=0; + getNextToken(file); + } + else if (token=="VERTEX") { + getNextVertex(file, mb); + } + else if (token=="3DFACE") { + getNextFace(file, mb); + } + else if (token=="POLYLINE") { + while(getNextToken(file)!="70") + getNextToken(file); + u32 num=atol(getNextToken(file).c_str()); + if ((num>15)&&(num<64)) { + mb = new scene::SMeshBuffer(); + Mesh->addMeshBuffer(mb); + mb->drop(); + mb->Material.MaterialType = video::EMT_SOLID; + getNextToken(file); + polycount=atol(getNextToken(file).c_str()); + getNextToken(file); + polydim=atol(getNextToken(file).c_str()); + if ((num%2)==1) + polymeshClosed=true; + else + polymeshClosed=false; + if (num>32) + polyClosed=true; + else + polyClosed=false; + } + getNextToken(file); + } + else + getNextToken(file); + } + + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_3DS; + + for (s32 i=0; igetMeshBufferCount(); ++i) + ((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox(); + + Mesh->recalculateBoundingBox(); + + am->addMesh(Mesh); + am->recalculateBoundingBox(); + Mesh->drop(); + Mesh = 0; + return am; +} + +} // end namespace scene +} // end namespace irr +