Major update to LWO loader to support more material properties and work with more meshes. Changed some meshloader constructors to take scenemanager instead of other parameters. Fixed obj loader texture loading with mixed file separators.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1215 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
hybrid 2008-01-29 16:59:36 +00:00
parent b5ac2dfa27
commit a3a41d8085
16 changed files with 218 additions and 213 deletions

View File

@ -14,14 +14,12 @@ namespace scene
{ {
//! Constructor //! Constructor
CBSPMeshFileLoader::CBSPMeshFileLoader(io::IFileSystem* fs,video::IVideoDriver* driver, scene::ISceneManager* smgr) CBSPMeshFileLoader::CBSPMeshFileLoader(scene::ISceneManager* smgr,
: FileSystem(fs), Driver(driver), SceneManager(smgr) io::IFileSystem* fs)
: FileSystem(fs), SceneManager(smgr)
{ {
if (FileSystem) if (FileSystem)
FileSystem->grab(); FileSystem->grab();
if (Driver)
Driver->grab();
} }
@ -30,9 +28,6 @@ CBSPMeshFileLoader::~CBSPMeshFileLoader()
{ {
if (FileSystem) if (FileSystem)
FileSystem->drop(); FileSystem->drop();
if (Driver)
Driver->drop();
} }
@ -53,7 +48,7 @@ IAnimatedMesh* CBSPMeshFileLoader::createMesh(io::IReadFile* file)
// load quake 3 bsp // load quake 3 bsp
if (strstr(file->getFileName(), ".bsp")) if (strstr(file->getFileName(), ".bsp"))
{ {
CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, Driver, SceneManager); CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, SceneManager);
q->getShader ( "scripts/models.shader", 1 ); q->getShader ( "scripts/models.shader", 1 );
q->getShader ( "scripts/liquid.shader", 1 ); q->getShader ( "scripts/liquid.shader", 1 );
@ -68,7 +63,7 @@ IAnimatedMesh* CBSPMeshFileLoader::createMesh(io::IReadFile* file)
// load quake 3 shader container // load quake 3 shader container
if (strstr(file->getFileName(), ".shader")) if (strstr(file->getFileName(), ".shader"))
{ {
CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, Driver, SceneManager); CQ3LevelMesh* q = new CQ3LevelMesh(FileSystem, SceneManager);
q->getShader ( file->getFileName(), 1 ); q->getShader ( file->getFileName(), 1 );
return q; return q;
} }

View File

@ -21,7 +21,7 @@ class CBSPMeshFileLoader : public IMeshLoader
public: public:
//! Constructor //! Constructor
CBSPMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver, scene::ISceneManager* smgr); CBSPMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs);
//! destructor //! destructor
virtual ~CBSPMeshFileLoader(); virtual ~CBSPMeshFileLoader();
@ -39,7 +39,6 @@ public:
private: private:
io::IFileSystem* FileSystem; io::IFileSystem* FileSystem;
video::IVideoDriver* Driver;
scene::ISceneManager* SceneManager; scene::ISceneManager* SceneManager;
}; };

View File

@ -266,9 +266,9 @@ namespace scene
//! Constructor //! Constructor
CColladaFileLoader::CColladaFileLoader(video::IVideoDriver* driver, CColladaFileLoader::CColladaFileLoader(scene::ISceneManager* smgr,
scene::ISceneManager* smgr, io::IFileSystem* fs) io::IFileSystem* fs)
: Driver(driver), SceneManager(smgr), FileSystem(fs), DummyMesh(0), : SceneManager(smgr), FileSystem(fs), DummyMesh(0),
FirstLoadedMesh(0), LoadedMeshCount(0), CreateInstances(false) FirstLoadedMesh(0), LoadedMeshCount(0), CreateInstances(false)
{ {
@ -2485,6 +2485,7 @@ video::ITexture* CColladaFileLoader::getTextureFromImage(core::stringc uri)
#ifdef COLLADA_READER_DEBUG #ifdef COLLADA_READER_DEBUG
os::Printer::log("COLLADA searching texture", uri.c_str()); os::Printer::log("COLLADA searching texture", uri.c_str());
#endif #endif
video::IVideoDriver* driver = SceneManager->getVideoDriver();
for (;;) for (;;)
{ {
uriToId(uri); uriToId(uri);
@ -2493,7 +2494,7 @@ video::ITexture* CColladaFileLoader::getTextureFromImage(core::stringc uri)
if (uri == Images[i].Id) if (uri == Images[i].Id)
{ {
if (Images[i].Source.size() && Images[i].SourceIsFilename) if (Images[i].Source.size() && Images[i].SourceIsFilename)
return Driver->getTexture(Images[i].Source.c_str()); return driver->getTexture(Images[i].Source.c_str());
else else
if (Images[i].Source.size()) if (Images[i].Source.size())
{ {
@ -2508,8 +2509,8 @@ video::ITexture* CColladaFileLoader::getTextureFromImage(core::stringc uri)
++ptrdest; ++ptrdest;
ptrsrc += 4; ptrsrc += 4;
} }
video::IImage* img = Driver->createImageFromData(video::ECF_A8R8G8B8, Images[i].Dimension, data, true, true); video::IImage* img = driver->createImageFromData(video::ECF_A8R8G8B8, Images[i].Dimension, data, true, true);
video::ITexture* tex = Driver->addTexture((CurrentlyLoadingMesh+"#"+Images[i].Id).c_str(), img); video::ITexture* tex = driver->addTexture((CurrentlyLoadingMesh+"#"+Images[i].Id).c_str(), img);
img->drop(); img->drop();
return tex; return tex;
} }

View File

@ -177,8 +177,7 @@ class CColladaFileLoader : public IMeshLoader
public: public:
//! Constructor //! Constructor
CColladaFileLoader(video::IVideoDriver* driver, CColladaFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs);
scene::ISceneManager* smgr, io::IFileSystem* fs);
//! destructor //! destructor
virtual ~CColladaFileLoader(); virtual ~CColladaFileLoader();
@ -331,7 +330,6 @@ private:
//! read a parameter and value //! read a parameter and value
void readParameter(io::IXMLReaderUTF8* reader); void readParameter(io::IXMLReaderUTF8* reader);
video::IVideoDriver* Driver;
scene::ISceneManager* SceneManager; scene::ISceneManager* SceneManager;
io::IFileSystem* FileSystem; io::IFileSystem* FileSystem;

View File

@ -31,27 +31,15 @@ namespace scene
{ {
/** Constructor*/ /** Constructor*/
CDMFLoader::CDMFLoader(video::IVideoDriver* driver, ISceneManager* smgr) CDMFLoader::CDMFLoader(ISceneManager* smgr)
: Driver(driver) , SceneMgr(smgr) : SceneMgr(smgr)
{ {
#ifdef _DEBUG #ifdef _DEBUG
IReferenceCounted::setDebugName("CDMFLoader"); IReferenceCounted::setDebugName("CDMFLoader");
#endif #endif
if (Driver)
Driver->grab();
} }
/** Destructor*/
CDMFLoader::~CDMFLoader()
{
if (Driver)
Driver->drop();
}
/** Given first three points of a face, returns a face normal*/ /** Given first three points of a face, returns a face normal*/
void CDMFLoader::GetFaceNormal( f32 a[3], //First point void CDMFLoader::GetFaceNormal( f32 a[3], //First point
f32 b[3], //Second point f32 b[3], //Second point
@ -91,6 +79,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
{ {
if (!file) if (!file)
return 0; return 0;
video::IVideoDriver* driver = SceneMgr->getVideoDriver();
//Load stringlist //Load stringlist
StringList dmfRawFile(file); StringList dmfRawFile(file);
@ -229,8 +218,8 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//Primary texture is normal //Primary texture is normal
if ((materiali[i].textureFlag==0) || (materiali[i].textureBlend==4)) if ((materiali[i].textureFlag==0) || (materiali[i].textureBlend==4))
Driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true); driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true);
tex = Driver->getTexture((path+String(materiali[i].textureName)).c_str()); tex = driver->getTexture((path+String(materiali[i].textureName)).c_str());
//Primary texture is just a colour //Primary texture is just a colour
if(materiali[i].textureFlag==1) if(materiali[i].textureFlag==1)
@ -260,12 +249,12 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//just for compatibility with older Irrlicht versions //just for compatibility with older Irrlicht versions
//to support transparent materials //to support transparent materials
if (color.getAlpha()!=255 && materiali[i].textureBlend==4) if (color.getAlpha()!=255 && materiali[i].textureBlend==4)
Driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true); driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true);
IImage *immagine=Driver->createImageFromData(ECF_A8R8G8B8, IImage *immagine=driver->createImageFromData(ECF_A8R8G8B8,
core::dimension2d<s32>(8,8),buf); core::dimension2d<s32>(8,8),buf);
tex = Driver->addTexture("", immagine); tex = driver->addTexture("", immagine);
//to support transparent materials //to support transparent materials
if(color.getAlpha()!=255 && materiali[i].textureBlend==4) if(color.getAlpha()!=255 && materiali[i].textureBlend==4)
@ -278,7 +267,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//Lightmap is present //Lightmap is present
if (materiali[i].lightmapFlag == 0) if (materiali[i].lightmapFlag == 0)
lig = Driver->getTexture((path+String(materiali[i].lightmapName)).c_str()); lig = driver->getTexture((path+String(materiali[i].lightmapName)).c_str());
else //no lightmap else //no lightmap
{ {
lig = 0; lig = 0;

View File

@ -50,10 +50,7 @@ namespace scene
public: public:
/** constructor*/ /** constructor*/
CDMFLoader(video::IVideoDriver* driver, ISceneManager* smgr); CDMFLoader(ISceneManager* smgr);
/** destructor*/
virtual ~CDMFLoader();
//! returns true if the file maybe is able to be loaded by this class //! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".cob") //! based on the file extension (e.g. ".cob")

View File

@ -22,15 +22,9 @@ namespace scene
//! Constructor //! Constructor
CIrrMeshFileLoader::CIrrMeshFileLoader(video::IVideoDriver* driver, CIrrMeshFileLoader::CIrrMeshFileLoader(scene::ISceneManager* smgr,
scene::ISceneManager* smgr, io::IFileSystem* fs) io::IFileSystem* fs)
: Driver(driver), SceneManager(smgr), FileSystem(fs) : SceneManager(smgr), FileSystem(fs)
{
}
//! destructor
CIrrMeshFileLoader::~CIrrMeshFileLoader()
{ {
} }
@ -175,10 +169,10 @@ IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader)
{ {
//we've got a material //we've got a material
io::IAttributes* attributes = FileSystem->createEmptyAttributes(Driver); io::IAttributes* attributes = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver());
attributes->read(reader, true, L"material"); attributes->read(reader, true, L"material");
Driver->fillMaterialStructureFromAttributes(material, attributes); SceneManager->getVideoDriver()->fillMaterialStructureFromAttributes(material, attributes);
attributes->drop(); attributes->drop();
} }
else else

View File

@ -25,11 +25,7 @@ class CIrrMeshFileLoader : public IMeshLoader
public: public:
//! Constructor //! Constructor
CIrrMeshFileLoader(video::IVideoDriver* driver, CIrrMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs);
scene::ISceneManager* smgr, io::IFileSystem* fs);
//! destructor
virtual ~CIrrMeshFileLoader();
//! returns true if the file maybe is able to be loaded by this class //! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".cob") //! based on the file extension (e.g. ".cob")
@ -83,7 +79,6 @@ private:
// member variables // member variables
video::IVideoDriver* Driver;
scene::ISceneManager* SceneManager; scene::ISceneManager* SceneManager;
io::IFileSystem* FileSystem; io::IFileSystem* FileSystem;
}; };

View File

@ -102,8 +102,8 @@ bool CIrrMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
void CIrrMeshWriter::writeBoundingBox(const core::aabbox3df& box) void CIrrMeshWriter::writeBoundingBox(const core::aabbox3df& box)
{ {
Writer->writeElement(L"boundingBox", true, Writer->writeElement(L"boundingBox", true,
L"minEdge", getVectorAsStringLine(box.MinEdge).c_str(), L"minEdge", getVectorAsStringLine(box.MinEdge).c_str(),
L"maxEdge", getVectorAsStringLine(box.MaxEdge).c_str() ); L"maxEdge", getVectorAsStringLine(box.MaxEdge).c_str());
} }
@ -176,7 +176,7 @@ void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
str += getVectorAsStringLine(vtx[j].TCoords); str += getVectorAsStringLine(vtx[j].TCoords);
Writer->writeText(str.c_str()); Writer->writeText(str.c_str());
Writer->writeLineBreak(); Writer->writeLineBreak();
} }
} }
@ -198,7 +198,7 @@ void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
str += L" "; str += L" ";
str += getVectorAsStringLine(vtx[j].TCoords2); str += getVectorAsStringLine(vtx[j].TCoords2);
Writer->writeText(str.c_str()); Writer->writeText(str.c_str());
Writer->writeLineBreak(); Writer->writeLineBreak();
} }
} }
@ -222,7 +222,7 @@ void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer)
str += L" "; str += L" ";
str += getVectorAsStringLine(vtx[j].Binormal); str += getVectorAsStringLine(vtx[j].Binormal);
Writer->writeText(str.c_str()); Writer->writeText(str.c_str());
Writer->writeLineBreak(); Writer->writeLineBreak();
} }
} }

View File

@ -1,9 +1,12 @@
#include "CLWOMeshFileLoader.h" #include "CLWOMeshFileLoader.h"
#include <cstring>
#include "os.h" #include "os.h"
#include "SAnimatedMesh.h" #include "SAnimatedMesh.h"
#include "SMesh.h" #include "SMesh.h"
#include "IReadFile.h" #include "IReadFile.h"
#include "ISceneManager.h"
#include "IFileSystem.h"
#include "IVideoDriver.h"
#include "IMeshManipulator.h"
using namespace std; using namespace std;
@ -49,7 +52,7 @@ struct tLWOTextureInfo
struct CLWOMeshFileLoader::tLWOMaterial struct CLWOMeshFileLoader::tLWOMaterial
{ {
tLWOMaterial() : Meshbuffer(0), Flags(0), ReflMode(3), TranspMode(3), tLWOMaterial() : Meshbuffer(0), TagType(0), Flags(0), ReflMode(3), TranspMode(3),
Glow(0), AlphaMode(2), Luminance(0.0f), Diffuse(1.0f), Specular(0.0f), Glow(0), AlphaMode(2), Luminance(0.0f), Diffuse(1.0f), Specular(0.0f),
Reflection(0.0f), Transparency(0.0f), Translucency(0.0f), Reflection(0.0f), Transparency(0.0f), Translucency(0.0f),
Sharpness(0.0f), ReflSeamAngle(0.0f), ReflBlur(0.0f), Sharpness(0.0f), ReflSeamAngle(0.0f), ReflBlur(0.0f),
@ -61,6 +64,7 @@ struct CLWOMeshFileLoader::tLWOMaterial
core::stringc Name; core::stringc Name;
scene::SMeshBuffer *Meshbuffer; scene::SMeshBuffer *Meshbuffer;
core::stringc ReflMap; core::stringc ReflMap;
u16 TagType;
u16 Flags; u16 Flags;
u16 ReflMode; u16 ReflMode;
u16 TranspMode; u16 TranspMode;
@ -103,27 +107,21 @@ struct tLWOLayerInfo
//! Constructor //! Constructor
CLWOMeshFileLoader::CLWOMeshFileLoader(video::IVideoDriver* driver) CLWOMeshFileLoader::CLWOMeshFileLoader(scene::ISceneManager* smgr,
: Driver(driver), File(0), Mesh(0) io::IFileSystem* fs)
: SceneManager(smgr), FileSystem(fs), File(0), Mesh(0)
{ {
if (Driver)
Driver->grab();
} }
//! destructor //! destructor
CLWOMeshFileLoader::~CLWOMeshFileLoader() CLWOMeshFileLoader::~CLWOMeshFileLoader()
{ {
if (Driver)
Driver->drop();
if (Mesh) if (Mesh)
Mesh->drop(); Mesh->drop();
} }
//! returns true if the file maybe is able to be loaded by this class //! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp") //! based on the file extension (e.g. ".bsp")
bool CLWOMeshFileLoader::isALoadableFileExtension(const c8* filename) const bool CLWOMeshFileLoader::isALoadableFileExtension(const c8* filename) const
@ -155,13 +153,51 @@ IAnimatedMesh* CLWOMeshFileLoader::createMesh(io::IReadFile* file)
SAnimatedMesh* am = new SAnimatedMesh(); SAnimatedMesh* am = new SAnimatedMesh();
am->Type = EAMT_3DS; am->Type = EAMT_3DS;
for (u32 polyIndex=0; polyIndex<MaterialMapping.size(); ++polyIndex)
{
const u16 tag=MaterialMapping[polyIndex];
scene::SMeshBuffer *mb=Materials[tag]->Meshbuffer;
const s32 vertCount=mb->Vertices.size();
const core::array<u32>& poly = Indices[polyIndex];
const u32 polySize=poly.size();
video::S3DVertex vertex;
for (u32 i=0; i<polySize; ++i)
{
const s32 j=poly[i];
vertex.Pos=Points[j];
if (Materials[tag]->Texture[0].TCoords && (Materials[tag]->Texture[0].TCoords->size()>0))
vertex.TCoords=(*Materials[tag]->Texture[0].TCoords)[j];
mb->Vertices.push_back(vertex);
}
if (polySize>2)
{
for (u32 i=1; i<polySize-1; ++i)
{
core::vector3df normal = core::plane3df(mb->Vertices[vertCount].Pos,mb->Vertices[vertCount+i].Pos,mb->Vertices[vertCount+i+1].Pos).Normal.normalize();
mb->Vertices[vertCount].Normal=normal;
mb->Vertices[vertCount+i].Normal=normal;
mb->Vertices[vertCount+i+1].Normal=normal;
mb->Indices.push_back(vertCount);
mb->Indices.push_back(vertCount+i);
mb->Indices.push_back(vertCount+i+1);
}
}
}
for (u32 i=0; i<Materials.size(); ++i) for (u32 i=0; i<Materials.size(); ++i)
{ {
for (u32 j=0; j<Materials[i]->Meshbuffer->Vertices.size(); ++j) for (u32 j=0; j<Materials[i]->Meshbuffer->Vertices.size(); ++j)
Materials[i]->Meshbuffer->Vertices[j].Color=Materials[i]->Meshbuffer->Material.DiffuseColor; Materials[i]->Meshbuffer->Vertices[j].Color=Materials[i]->Meshbuffer->Material.DiffuseColor;
Materials[i]->Meshbuffer->recalculateBoundingBox(); Materials[i]->Meshbuffer->recalculateBoundingBox();
Mesh->addMeshBuffer(Materials[i]->Meshbuffer); if (Materials[i]->Meshbuffer->Material.MaterialType==video::EMT_NORMAL_MAP_SOLID)
Materials[i]->Meshbuffer->drop(); {
SMesh tmpmesh;
tmpmesh.addMeshBuffer(Materials[i]->Meshbuffer);
SceneManager->getMeshManipulator()->createMeshWithTangents(&tmpmesh);
Mesh->addMeshBuffer(tmpmesh.getMeshBuffer(0));
}
else
Mesh->addMeshBuffer(Materials[i]->Meshbuffer);
Mesh->getMeshBuffer(Mesh->getMeshBufferCount()-1)->drop();
} }
Mesh->recalculateBoundingBox(); Mesh->recalculateBoundingBox();
@ -172,7 +208,9 @@ IAnimatedMesh* CLWOMeshFileLoader::createMesh(io::IReadFile* file)
Mesh = 0; Mesh = 0;
Points.clear(); Points.clear();
Polygons.clear(); Indices.clear();
MaterialMapping.clear();
VMap.clear();
TCoords.clear(); TCoords.clear();
Materials.clear(); Materials.clear();
Images.clear(); Images.clear();
@ -372,6 +410,7 @@ bool CLWOMeshFileLoader::readChunks()
return true; return true;
} }
void CLWOMeshFileLoader::readObj1(u32 size) void CLWOMeshFileLoader::readObj1(u32 size)
{ {
u32 pos; u32 pos;
@ -435,7 +474,7 @@ void CLWOMeshFileLoader::readVertexMapping(u32 size)
core::stringc name; core::stringc name;
File->read(&type, 4); File->read(&type, 4);
#ifdef LWO_READER_DEBUG #ifdef LWO_READER_DEBUG
os::Printer::log("LWO loader: Vertex map", type); os::Printer::log("LWO loader: Vertex map type", type);
#endif #endif
File->read(&dimension, 2); File->read(&dimension, 2);
#ifndef __BIG_ENDIAN__ #ifndef __BIG_ENDIAN__
@ -451,10 +490,13 @@ void CLWOMeshFileLoader::readVertexMapping(u32 size)
File->seek(size, true); File->seek(size, true);
return; return;
} }
VMap.insert(name,TCoords.size());
TCoords.push_back(core::array<core::vector2df>());
u32 index; u32 index;
core::vector2df tcoord; core::vector2df tcoord;
TCoords.set_used(Points.size()); core::array<core::vector2df>& tcArray = TCoords.getLast();
tcArray.set_used(Points.size());
while (size!=0) while (size!=0)
{ {
size -= readVX(index); size -= readVX(index);
@ -466,8 +508,8 @@ void CLWOMeshFileLoader::readVertexMapping(u32 size)
#ifndef __BIG_ENDIAN__ #ifndef __BIG_ENDIAN__
tcoord.Y=os::Byteswap::byteswap(tcoord.Y); tcoord.Y=os::Byteswap::byteswap(tcoord.Y);
#endif #endif
tcoord.Y=-tcoord.Y; tcoord.Y=tcoord.Y;
TCoords[index]=tcoord; tcArray[index]=tcoord;
size -= 8; size -= 8;
} }
} }
@ -478,7 +520,7 @@ void CLWOMeshFileLoader::readTagMapping(u32 size)
type[4]=0; type[4]=0;
File->read(&type, 4); File->read(&type, 4);
size -= 4; size -= 4;
if ((strncmp(type, "SURF", 4))||(Polygons.size()==0)) if ((strncmp(type, "SURF", 4))||(Indices.size()==0))
{ {
File->seek(size, true); File->seek(size, true);
return; return;
@ -494,28 +536,8 @@ void CLWOMeshFileLoader::readTagMapping(u32 size)
tag=os::Byteswap::byteswap(tag); tag=os::Byteswap::byteswap(tag);
#endif #endif
size -= 2; size -= 2;
MaterialMapping[polyIndex]=tag;
scene::SMeshBuffer *mb=Materials[tag]->Meshbuffer; Materials[tag]->TagType=1;
const s32 vertCount=mb->Vertices.size();
const s32 polySize=Polygons[polyIndex].size();
video::S3DVertex vertex;
for (s32 i=0; i<polySize; ++i)
{
vertex.Pos=Points[Polygons[polyIndex][i]];
if (TCoords.size()>0)
vertex.TCoords=TCoords[Polygons[polyIndex][i]];
mb->Vertices.push_back(vertex);
}
for (s32 i=1; i<polySize-1; ++i)
{
core::vector3df normal = core::plane3df(mb->Vertices[vertCount].Pos,mb->Vertices[vertCount+i].Pos,mb->Vertices[vertCount+i+1].Pos).Normal.normalize();
mb->Vertices[vertCount].Normal=normal;
mb->Vertices[vertCount+i].Normal=normal;
mb->Vertices[vertCount+i+1].Normal=normal;
mb->Indices.push_back(vertCount);
mb->Indices.push_back(vertCount+i);
mb->Indices.push_back(vertCount+i+1);
}
} }
} }
@ -525,7 +547,7 @@ void CLWOMeshFileLoader::readObj2(u32 size)
type[4]=0; type[4]=0;
File->read(&type, 4); File->read(&type, 4);
size -= 4; size -= 4;
Polygons.clear(); Indices.clear();
if (strncmp(type, "FACE", 4)) // also possible are splines, subdivision patches, metaballs, and bones if (strncmp(type, "FACE", 4)) // also possible are splines, subdivision patches, metaballs, and bones
{ {
File->seek(size, true); File->seek(size, true);
@ -542,9 +564,9 @@ void CLWOMeshFileLoader::readObj2(u32 size)
numVerts &= 0x03FF; numVerts &= 0x03FF;
size -= 2; size -= 2;
Polygons.push_back(core::array<u32>()); Indices.push_back(core::array<u32>());
u32 vertIndex; u32 vertIndex;
core::array<u32>& polyArray = Polygons.getLast(); core::array<u32>& polyArray = Indices.getLast();
polyArray.reallocate(numVerts); polyArray.reallocate(numVerts);
for (u16 i=0; i<numVerts; ++i) for (u16 i=0; i<numVerts; ++i)
{ {
@ -552,6 +574,9 @@ void CLWOMeshFileLoader::readObj2(u32 size)
polyArray.push_back(vertIndex); polyArray.push_back(vertIndex);
} }
} }
MaterialMapping.reallocate(Indices.size());
for (u32 j=0; j<Indices.size(); ++j)
MaterialMapping.push_back(0);
} }
@ -563,7 +588,7 @@ void CLWOMeshFileLoader::readMat(u32 size)
size -= readString(name); size -= readString(name);
for (u32 i=0; i<Materials.size(); ++i) for (u32 i=0; i<Materials.size(); ++i)
{ {
if (Materials[i]->Name==name) if ((Materials[i]->TagType==1) && (Materials[i]->Name==name))
{ {
mat=Materials[i]; mat=Materials[i];
break; break;
@ -1479,7 +1504,8 @@ void CLWOMeshFileLoader::readMat(u32 size)
{ {
core::stringc name; core::stringc name;
size -= readString(name); size -= readString(name);
mat->Texture[currTexture].TCoords = &TCoords; // TODO: Needs to be searched for if (VMap.find(name) != 0)
mat->Texture[currTexture].TCoords = &TCoords[VMap.find(name)->getValue()];
} }
break; break;
case charsToUIntD('B','L','O','K'): case charsToUIntD('B','L','O','K'):
@ -1543,30 +1569,11 @@ void CLWOMeshFileLoader::readMat(u32 size)
} }
} }
s32 stringPos;
if (mat->Texture[0].Map != "") // diffuse if (mat->Texture[0].Map != "") // diffuse
{ irrMat->setTexture(0,loadTexture(mat->Texture[0].Map));
irrMat->setTexture(0,Driver->getTexture(mat->Texture[0].Map.c_str()));
if (!irrMat->getTexture(0))
{
stringPos = mat->Texture[0].Map.findLast('/');
if (stringPos==-1)
stringPos = mat->Texture[0].Map.findLast('\\');
if (stringPos != -1)
irrMat->setTexture(0, Driver->getTexture(mat->Texture[0].Map.subString(stringPos+1, mat->Texture[0].Map.size()-stringPos).c_str()));
}
}
if (mat->Texture[3].Map != "") // reflection if (mat->Texture[3].Map != "") // reflection
{ {
video::ITexture* reflTexture = Driver->getTexture(mat->Texture[3].Map.c_str()); video::ITexture* reflTexture = loadTexture(mat->Texture[3].Map);
if (!reflTexture)
{
stringPos = mat->Texture[3].Map.findLast('/');
if (stringPos==-1)
stringPos = mat->Texture[3].Map.findLast('\\');
if (stringPos != -1)
reflTexture = Driver->getTexture(mat->Texture[3].Map.subString(stringPos+1, mat->Texture[3].Map.size()-stringPos).c_str());
}
if (reflTexture) if (reflTexture)
{ {
irrMat->setTexture(1, irrMat->getTexture(0)); irrMat->setTexture(1, irrMat->getTexture(0));
@ -1576,15 +1583,7 @@ void CLWOMeshFileLoader::readMat(u32 size)
} }
if (mat->Texture[4].Map != "") // transparency if (mat->Texture[4].Map != "") // transparency
{ {
video::ITexture* transTexture = Driver->getTexture(mat->Texture[4].Map.c_str()); video::ITexture* transTexture = loadTexture(mat->Texture[4].Map);
if (!transTexture)
{
stringPos = mat->Texture[4].Map.findLast('/');
if (stringPos==-1)
stringPos = mat->Texture[4].Map.findLast('\\');
if (stringPos != -1)
transTexture = Driver->getTexture(mat->Texture[4].Map.subString(stringPos+1, mat->Texture[4].Map.size()-stringPos).c_str());
}
if (transTexture) if (transTexture)
{ {
irrMat->setTexture(1, irrMat->getTexture(0)); irrMat->setTexture(1, irrMat->getTexture(0));
@ -1594,19 +1593,11 @@ void CLWOMeshFileLoader::readMat(u32 size)
} }
if (mat->Texture[6].Map != "") // bump if (mat->Texture[6].Map != "") // bump
{ {
irrMat->setTexture(1, Driver->getTexture(mat->Texture[6].Map.c_str())); irrMat->setTexture(1, loadTexture(mat->Texture[6].Map));
if (!irrMat->getTexture(1))
{
stringPos = mat->Texture[6].Map.findLast('/');
if (stringPos==-1)
stringPos = mat->Texture[6].Map.findLast('\\');
if (stringPos != -1)
irrMat->setTexture(1, Driver->getTexture(mat->Texture[6].Map.subString(stringPos+1, mat->Texture[6].Map.size()-stringPos).c_str()));
}
if (irrMat->getTexture(1)) if (irrMat->getTexture(1))
{ {
Driver->makeNormalMapTexture(irrMat->getTexture(1)); // SceneManager->getVideoDriver()->makeNormalMapTexture(irrMat->getTexture(1));
irrMat->MaterialType=video::EMT_PARALLAX_MAP_SOLID; irrMat->MaterialType=video::EMT_NORMAL_MAP_SOLID;
} }
} }
} }
@ -1748,6 +1739,41 @@ bool CLWOMeshFileLoader::readFileHeader()
} }
video::ITexture* CLWOMeshFileLoader::loadTexture(const core::stringc& file)
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if (FileSystem->existFile(file.c_str()))
return driver->getTexture(file.c_str());
core::stringc strippedName;
s32 stringPos = file.findLast('/');
if (stringPos==-1)
stringPos = file.findLast('\\');
if (stringPos != -1)
{
strippedName = file.subString(stringPos+1, file.size()-stringPos);
if (FileSystem->existFile(strippedName.c_str()))
return driver->getTexture(strippedName.c_str());
}
else
strippedName = file;
core::stringc newpath = File->getFileName();
stringPos = newpath.findLast('/');
if (stringPos==-1)
stringPos = newpath.findLast('\\');
if (stringPos != -1)
{
newpath = newpath.subString(0,stringPos+1);
newpath.append(strippedName);
if (FileSystem->existFile(newpath.c_str()))
return driver->getTexture(newpath.c_str());
}
os::Printer::log("Could not load texture", file.c_str(), ELL_WARNING);
return 0;
}
} // end namespace scene } // end namespace scene
} // end namespace irr } // end namespace irr

View File

@ -2,20 +2,22 @@
#define __C_LWO_MESH_FILE_LOADER_H_INCLUDED__ #define __C_LWO_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h" #include "IMeshLoader.h"
#include "IVideoDriver.h"
#include "irrString.h"
#include "SMeshBuffer.h" #include "SMeshBuffer.h"
#include "irrString.h"
#include "irrMap.h"
namespace irr namespace irr
{ {
namespace io namespace io
{ {
class IReadFile; class IReadFile;
class IFileSystem;
} // end namespace io } // end namespace io
namespace scene namespace scene
{ {
struct SMesh; struct SMesh;
class ISceneManager;
//! Meshloader capable of loading Lightwave 3D meshes. //! Meshloader capable of loading Lightwave 3D meshes.
class CLWOMeshFileLoader : public IMeshLoader class CLWOMeshFileLoader : public IMeshLoader
@ -23,7 +25,7 @@ class CLWOMeshFileLoader : public IMeshLoader
public: public:
//! Constructor //! Constructor
CLWOMeshFileLoader(video::IVideoDriver* driver); CLWOMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs);
//! destructor //! destructor
virtual ~CLWOMeshFileLoader(); virtual ~CLWOMeshFileLoader();
@ -53,14 +55,18 @@ private:
u32 readVec(core::vector3df& vec); u32 readVec(core::vector3df& vec);
u32 readVX(u32& num); u32 readVX(u32& num);
u32 readColor(video::SColor& color); u32 readColor(video::SColor& color);
video::ITexture* loadTexture(const core::stringc& file);
video::IVideoDriver* Driver; scene::ISceneManager* SceneManager;
io::IFileSystem* FileSystem;
io::IReadFile* File; io::IReadFile* File;
SMesh* Mesh; SMesh* Mesh;
core::array<core::vector3df> Points; core::array<core::vector3df> Points;
core::array<core::array<u32> > Polygons; core::array<core::array<u32> > Indices;
core::array<core::vector2df> TCoords; core::array<u16> MaterialMapping;
core::map<core::stringc, u32> VMap;
core::array<core::array<core::vector2df> > TCoords;
core::array<tLWOMaterial*> Materials; core::array<tLWOMaterial*> Materials;
core::array<core::stringc> Images; core::array<core::stringc> Images;
u8 FormatVersion; u8 FormatVersion;

View File

@ -454,11 +454,13 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
} }
video::ITexture * texture = 0; video::ITexture * texture = 0;
if (FileSystem->existFile(textureNameBuf)) core::stringc texname(textureNameBuf);
texture = Driver->getTexture( textureNameBuf ); texname.replace('\\', '/');
if (FileSystem->existFile(texname.c_str()))
texture = Driver->getTexture(texname.c_str());
else else
// try to read in the relative path, the .obj is loaded from // try to read in the relative path, the .obj is loaded from
texture = Driver->getTexture( (relPath + textureNameBuf).c_str() ); texture = Driver->getTexture( (relPath + texname).c_str() );
if ( texture ) if ( texture )
{ {
if (type==0) if (type==0)

View File

@ -20,10 +20,10 @@ namespace scene
//! constructor //! constructor
CQ3LevelMesh::CQ3LevelMesh(io::IFileSystem* fs, video::IVideoDriver* driver, scene::ISceneManager* smgr) CQ3LevelMesh::CQ3LevelMesh(io::IFileSystem* fs, scene::ISceneManager* smgr)
: Textures(0), LightMaps(0), : Textures(0), LightMaps(0),
Vertices(0), Faces(0), Planes(0), Nodes(0), Leafs(0), LeafFaces(0), Vertices(0), Faces(0), Planes(0), Nodes(0), Leafs(0), LeafFaces(0),
MeshVerts(0), Brushes(0), Driver(driver), FileSystem(fs), SceneManager ( smgr ) MeshVerts(0), Brushes(0), FileSystem(fs), SceneManager ( smgr )
{ {
#ifdef _DEBUG #ifdef _DEBUG
IReferenceCounted::setDebugName("CQ3LevelMesh"); IReferenceCounted::setDebugName("CQ3LevelMesh");
@ -34,6 +34,10 @@ CQ3LevelMesh::CQ3LevelMesh(io::IFileSystem* fs, video::IVideoDriver* driver, sce
Mesh[i] = 0; Mesh[i] = 0;
} }
if (smgr)
Driver = smgr->getVideoDriver();
else
Driver = 0;
if (Driver) if (Driver)
Driver->grab(); Driver->grab();

View File

@ -24,7 +24,7 @@ namespace scene
public: public:
//! constructor //! constructor
CQ3LevelMesh(io::IFileSystem* fs, video::IVideoDriver* driver, scene::ISceneManager* smgr); CQ3LevelMesh(io::IFileSystem* fs, scene::ISceneManager* smgr);
//! destructor //! destructor
virtual ~CQ3LevelMesh(); virtual ~CQ3LevelMesh();

View File

@ -192,10 +192,10 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
// add file format loaders // add file format loaders
#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ #ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_
MeshLoaderList.push_back(new CIrrMeshFileLoader(Driver, this, FileSystem)); MeshLoaderList.push_back(new CIrrMeshFileLoader(this, FileSystem));
#endif #endif
#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ #ifdef _IRR_COMPILE_WITH_BSP_LOADER_
MeshLoaderList.push_back(new CBSPMeshFileLoader(FileSystem, Driver, this)); MeshLoaderList.push_back(new CBSPMeshFileLoader(this, FileSystem));
#endif #endif
#ifdef _IRR_COMPILE_WITH_MD2_LOADER_ #ifdef _IRR_COMPILE_WITH_MD2_LOADER_
MeshLoaderList.push_back(new CMD2MeshFileLoader()); MeshLoaderList.push_back(new CMD2MeshFileLoader());
@ -222,10 +222,10 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
MeshLoaderList.push_back(new CMY3DMeshFileLoader(FileSystem, Driver, this)); MeshLoaderList.push_back(new CMY3DMeshFileLoader(FileSystem, Driver, this));
#endif #endif
#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_ #ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
MeshLoaderList.push_back(new CColladaFileLoader(Driver, this, FileSystem)); MeshLoaderList.push_back(new CColladaFileLoader(this, FileSystem));
#endif #endif
#ifdef _IRR_COMPILE_WITH_DMF_LOADER_ #ifdef _IRR_COMPILE_WITH_DMF_LOADER_
MeshLoaderList.push_back(new CDMFLoader(Driver, this)); MeshLoaderList.push_back(new CDMFLoader(this));
#endif #endif
#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_ #ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
MeshLoaderList.push_back(new COgreMeshFileLoader(MeshManipulator, FileSystem, Driver)); MeshLoaderList.push_back(new COgreMeshFileLoader(MeshManipulator, FileSystem, Driver));
@ -240,7 +240,7 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
MeshLoaderList.push_back(new CB3DMeshFileLoader(this)); MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
#endif #endif
#ifdef _IRR_COMPILE_WITH_LWO_LOADER_ #ifdef _IRR_COMPILE_WITH_LWO_LOADER_
MeshLoaderList.push_back(new CLWOMeshFileLoader(Driver)); MeshLoaderList.push_back(new CLWOMeshFileLoader(this, FileSystem));
#endif #endif
#ifdef _IRR_COMPILE_WITH_STL_LOADER_ #ifdef _IRR_COMPILE_WITH_STL_LOADER_
MeshLoaderList.push_back(new CSTLMeshFileLoader()); MeshLoaderList.push_back(new CSTLMeshFileLoader());
@ -1813,7 +1813,6 @@ bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* use
reader->drop(); reader->drop();
return true; return true;
} }

View File

@ -304,7 +304,7 @@ namespace scene
f32 slidingValue = 0.0005f); f32 slidingValue = 0.0005f);
//! Creates a follow spline animator. //! Creates a follow spline animator.
virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points, const core::array< core::vector3df >& points,
f32 speed = 1.0f, f32 tightness = 0.5f); f32 speed = 1.0f, f32 tightness = 0.5f);