Commit bbc215fd authored by cutealien's avatar cutealien

Add IMeshTextureLoader interface and replace texture-loading algorithms in most meshloaders.

Previously each meshloader had implemented texture loading independendly. This had caused a lot of redundant codes and behaviour 
between different meshloaders was often different. So we have now one common interface which should be used by all meshloaders.
This also allows deprecating TEXTURE_PATH attributes as those paths can now be set by that interface and for all meshloaders using it.
I have replaced the codes for the 3DS, B3D, CSM, Collada, DMF, LMTS, LWO, MY3D, OBJ, OCT, Ogre, SMF and X meshloader.
Not changed (just using old code) are: MS3D (I forgot that one), CIrrMeshFileLoader (haven't figured out how it works yet).
STL and PLY both don't load textures and need no changes.
MDL, MD3, MD2 and BSP all work a little different (the textureloading there isn't implemented inside the meshloaders). Those could maybe still be adapted.
Stuff still needs a lot more test (unfortunately I don't have test-models for most formats...), but wanted to check it in already to get some feedback.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4703 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 7d44da69
--------------------------
Changes in 1.9 (not yet released)
- Add IMeshTextureLoader interface and replace texture-loading algorithms in most meshloaders.
- CGUICheckBox no longer gives up focus on EMIE_LMOUSE_LEFT_UP (thx @Demre for reporting)
- Bugfix: IGUIElement::addChild now prevents setting an element as it's own child.
- Bugfix: getFont for xml-fonts now also works for fonts inside archives (thx @Neirdan for bugreport)
......
......@@ -7,6 +7,7 @@
#include "IReferenceCounted.h"
#include "path.h"
#include "IMeshTextureLoader.h"
namespace irr
{
......@@ -27,8 +28,15 @@ class IMeshLoader : public virtual IReferenceCounted
{
public:
//! Constructor
IMeshLoader() : TextureLoader(0) {}
//! Destructor
virtual ~IMeshLoader() {}
virtual ~IMeshLoader()
{
if ( TextureLoader )
TextureLoader->drop();
}
//! Returns true if the file might be loaded by this class.
/** This decision should be based on the file extension (e.g. ".cob")
......@@ -43,6 +51,30 @@ public:
If you no longer need the mesh, you should call IAnimatedMesh::drop().
See IReferenceCounted::drop() for more information. */
virtual IAnimatedMesh* createMesh(io::IReadFile* file) = 0;
//! Set a new texture loader which this meshloader can use when searching for textures.
/** \param textureLoader The textureloader to use. When set to NULL the mesh will not load any textures.
*/
virtual void setMeshTextureLoader(IMeshTextureLoader* textureLoader)
{
if ( textureLoader != TextureLoader )
{
if ( textureLoader )
textureLoader->grab();
if ( TextureLoader )
TextureLoader->drop();
TextureLoader = textureLoader;
}
}
//! Get the texture loader used when this meshloder searches for textures.
virtual IMeshTextureLoader* getMeshTextureLoader() const
{
return TextureLoader;
}
protected:
IMeshTextureLoader* TextureLoader;
};
......@@ -50,4 +82,3 @@ public:
} // end namespace irr
#endif
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef IRR_I_MESH_TEXTURE_LOADER_H_INCLUDED__
#define IRR_I_MESH_TEXTURE_LOADER_H_INCLUDED__
#include "path.h"
#include "IReferenceCounted.h"
namespace irr
{
namespace video
{
class ITexture;
}
namespace io
{
class IReadFile;
}
namespace scene
{
//! Finding and loading textures inside meshloaders.
/** A texture loader can search for a texture in several paths.
For example relative to a given texture-path, relative to the current
working directory or relative to a mesh- and/or material-file.
*/
class IMeshTextureLoader : public virtual IReferenceCounted
{
public:
//! Constructor
IMeshTextureLoader() : CheckForCachedTextures(false)
{}
//! Destructor
virtual ~IMeshTextureLoader() {}
//! Set a custom texture path.
/** This is the first path the texture-loader should search. */
virtual void setTexturePath(const irr::io::path& path) = 0;
//! Get the current custom texture path.
virtual const irr::io::path& getTexturePath() const = 0;
//! Get the texture by searching for it in all paths that makes sense for the given textureName.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
\param textureName Texturename as used in the mesh-format
\return Pointer to the texture. Returns 0 if loading failed.*/
virtual irr::video::ITexture* getTexture(const irr::io::path& textureName) = 0;
//! Check which texture-name was last recently used.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
It's updated on getTexture calls. When those succeed this will return the full name which was
used to find the texture. Then getTexture failed it will contain the last name which was tried. */
virtual const irr::io::path& getRecentTextureName() const = 0;
//! Check if the last call to getTexture found a texture which was already cached.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
This will only work when a) CheckForCachedTextures is set to true and b) getTexture was
successful.
\return When true the textuer was already cached. When false the texture was loaded newly. */
virtual bool wasRecentTextureInCache() const = 0;
//! Meshloaders will search paths relative to the meshFile.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
Any values you set here will likely be overwritten internally. */
virtual void setMeshFile(const irr::io::IReadFile* meshFile) = 0;
//! Meshloaders will try to look relative to the path of the materialFile
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
Any values you set here will likely be overwritten internally. */
virtual void setMaterialFile(const irr::io::IReadFile* materialFile) = 0;
//! Enable checking if a texture was already cached before loading.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
It's mostly used to modify texture when they are first loaded.
\param enableCacheCheck On true getTexture calls will update information
which can be received by wasRecentTextureInCache.*/
void setCheckForCachedTextures(bool enableCacheCheck)
{
CheckForCachedTextures = enableCacheCheck;
}
//! Are checks enabled which look if textures where cached before loading
bool getCheckForCachedTextures() const
{
return CheckForCachedTextures;
}
private:
bool CheckForCachedTextures;
};
} // end namespace scene
} // end namespace irr
#endif
......@@ -6,6 +6,7 @@
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
#include "C3DSMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "os.h"
#include "SMeshBuffer.h"
#include "SAnimatedMesh.h"
......@@ -136,6 +137,8 @@ C3DSMeshFileLoader::C3DSMeshFileLoader(ISceneManager* smgr, io::IFileSystem* fs)
if (FileSystem)
FileSystem->grab();
TextureLoader = new CMeshTextureLoader( FileSystem, SceneManager->getVideoDriver() );
}
......@@ -166,6 +169,9 @@ bool C3DSMeshFileLoader::isALoadableFileExtension(const io::path& filename) cons
//! See IReferenceCounted::drop() for more information.
IAnimatedMesh* C3DSMeshFileLoader::createMesh(io::IReadFile* file)
{
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
ChunkData data;
readChunkData(file, data);
......@@ -1127,12 +1133,10 @@ void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc&
void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file)
{
// create a mesh buffer for every material
core::stringc modelFilename = file->getFileName();
if (Materials.empty())
os::Printer::log("No materials found in 3ds file.", ELL_INFORMATION);
// create a mesh buffer for every material
MeshBufferNames.reallocate(Materials.size());
for (u32 i=0; i<Materials.size(); ++i)
{
......@@ -1143,33 +1147,19 @@ void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file)
m->getMaterial() = Materials[i].Material;
if (Materials[i].Filename[0].size())
{
video::ITexture* texture = 0;
if (FileSystem->existFile(Materials[i].Filename[0]))
texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[0]);
video::ITexture* texture = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(Materials[i].Filename[0]) : NULL;
if (!texture)
{
const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[0]);
if (FileSystem->existFile(fname))
texture = SceneManager->getVideoDriver()->getTexture(fname);
}
if (!texture)
os::Printer::log("Could not load a texture for entry in 3ds file",
Materials[i].Filename[0].c_str(), ELL_WARNING);
}
else
m->getMaterial().setTexture(0, texture);
}
if (Materials[i].Filename[2].size())
{
video::ITexture* texture = 0;
if (FileSystem->existFile(Materials[i].Filename[2]))
texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[2]);
if (!texture)
{
const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[2]);
if (FileSystem->existFile(fname))
texture = SceneManager->getVideoDriver()->getTexture(fname);
}
video::ITexture* texture = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(Materials[i].Filename[2]) : NULL;
if (!texture)
{
os::Printer::log("Could not load a texture for entry in 3ds file",
......@@ -1184,16 +1174,7 @@ void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file)
if (Materials[i].Filename[3].size())
{
video::ITexture* texture = 0;
if (FileSystem->existFile(Materials[i].Filename[3]))
texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[3]);
if (!texture)
{
const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[3]);
if (FileSystem->existFile(fname))
texture = SceneManager->getVideoDriver()->getTexture(fname);
}
video::ITexture* texture = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(Materials[i].Filename[3]) : NULL;
if (!texture)
{
os::Printer::log("Could not load a texture for entry in 3ds file",
......@@ -1209,18 +1190,12 @@ void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file)
if (Materials[i].Filename[4].size())
{
video::ITexture* texture = 0;
if (FileSystem->existFile(Materials[i].Filename[4]))
texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[4]);
video::ITexture* texture = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(Materials[i].Filename[4]) : NULL;
if (!texture)
{
const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[4]);
if (FileSystem->existFile(fname))
texture = SceneManager->getVideoDriver()->getTexture(fname);
}
if (!texture)
os::Printer::log("Could not load a texture for entry in 3ds file",
Materials[i].Filename[4].c_str(), ELL_WARNING);
}
else
{
m->getMaterial().setTexture(1, texture);
......
......@@ -10,6 +10,7 @@
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
#include "CB3DMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "IVideoDriver.h"
#include "IFileSystem.h"
......@@ -32,6 +33,8 @@ CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager* smgr)
#ifdef _DEBUG
setDebugName("CB3DMeshFileLoader");
#endif
TextureLoader = new CMeshTextureLoader( SceneManager->getFileSystem(), SceneManager->getVideoDriver() );
}
......@@ -47,12 +50,15 @@ bool CB3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) cons
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
IAnimatedMesh* CB3DMeshFileLoader::createMesh(io::IReadFile* f)
IAnimatedMesh* CB3DMeshFileLoader::createMesh(io::IReadFile* file)
{
if (!f)
if (!file)
return 0;
B3DFile = f;
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
B3DFile = file;
AnimatedMesh = new scene::CSkinnedMesh();
ShowWarning = true; // If true a warning is issued if too many textures are used
VerticesStart=0;
......@@ -1028,6 +1034,11 @@ bool CB3DMeshFileLoader::readChunkBRUS()
void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const
{
if ( getMeshTextureLoader() )
{
getMeshTextureLoader()->setTexturePath( SceneManager->getParameters()->getAttributeAsString(B3D_TEXTURE_PATH) );
}
const bool previous32BitTextureFlag = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT);
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
......@@ -1043,23 +1054,7 @@ void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const
if (!SceneManager->getParameters()->getAttributeAsBool(B3D_LOADER_IGNORE_MIPMAP_FLAG))
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, (B3dTexture->Flags & 0x8) ? true:false);
{
video::ITexture* tex = 0;
io::IFileSystem* fs = SceneManager->getFileSystem();
io::path texnameWithUserPath( SceneManager->getParameters()->getAttributeAsString(B3D_TEXTURE_PATH) );
if ( texnameWithUserPath.size() )
{
texnameWithUserPath += '/';
texnameWithUserPath += B3dTexture->TextureName;
}
if (fs->existFile(texnameWithUserPath))
tex = SceneManager->getVideoDriver()->getTexture(texnameWithUserPath);
else if (fs->existFile(B3dTexture->TextureName))
tex = SceneManager->getVideoDriver()->getTexture(B3dTexture->TextureName);
else if (fs->existFile(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName)))
tex = SceneManager->getVideoDriver()->getTexture(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName));
else
tex = SceneManager->getVideoDriver()->getTexture(fs->getFileBasename(B3dTexture->TextureName));
video::ITexture* tex = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(B3dTexture->TextureName) : NULL;
material.Material.setTexture(i, tex);
}
if (material.Textures[i]->Flags & 0x10) // Clamp U
......
......@@ -9,6 +9,7 @@
#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
#include "CCSMLoader.h"
#include "CMeshTextureLoader.h"
#include "os.h"
#include "IFileSystem.h"
#include "IReadFile.h"
......@@ -359,10 +360,11 @@ namespace scene
CCSMLoader::CCSMLoader(scene::ISceneManager* manager, io::IFileSystem* fs)
: FileSystem(fs), SceneManager(manager)
{
#ifdef _DEBUG
setDebugName("CCSMLoader");
#endif
TextureLoader = new CMeshTextureLoader( FileSystem, SceneManager->getVideoDriver() );
}
......@@ -377,6 +379,9 @@ namespace scene
//! creates/loads an animated mesh from the file.
IAnimatedMesh* CCSMLoader::createMesh(io::IReadFile* file)
{
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
scene::IMesh* m = createCSMMesh(file);
if (!m)
......@@ -400,15 +405,15 @@ namespace scene
CSMFile csmFile;
csmFile.load(&reader);
return createIrrlichtMesh(&csmFile,
SceneManager->getParameters()->getAttributeAsString(CSM_TEXTURE_PATH),
file->getFileName());
return createIrrlichtMesh(&csmFile, file->getFileName());
}
scene::IMesh* CCSMLoader::createIrrlichtMesh(const CSMFile* csmFile,
const core::stringc& textureRoot, const io::path& lmprefix)
scene::IMesh* CCSMLoader::createIrrlichtMesh(const CSMFile* csmFile, const io::path& lmprefix)
{
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setTexturePath( SceneManager->getParameters()->getAttributeAsString(CSM_TEXTURE_PATH) );
scene::SMesh *pMesh = new scene::SMesh();
video::IVideoDriver* driver = SceneManager->getVideoDriver();
......@@ -438,30 +443,9 @@ namespace scene
{
const Surface* surface = mshPtr->getSurfaceAt(s);
core::stringc texName;
if (textureRoot.size())
{
texName += textureRoot;
texName += "/";
}
texName+= surface->getTextureName();
video::ITexture* texture = 0;
if (texName.size())
{
if (FileSystem->existFile(texName))
texture = driver->getTexture(texName);
else if (FileSystem->existFile(surface->getTextureName()))
texture = driver->getTexture(surface->getTextureName());
else if (FileSystem->existFile(FileSystem->getFileBasename(surface->getTextureName())))
texture = driver->getTexture(FileSystem->getFileBasename(surface->getTextureName()));
else if (FileSystem->existFile(FileSystem->getFileDir(lmprefix)+"/"+surface->getTextureName()))
texture = driver->getTexture(FileSystem->getFileDir(lmprefix)+"/"+surface->getTextureName());
else
texture = driver->getTexture(FileSystem->getFileDir(lmprefix)+"/"+FileSystem->getFileBasename(surface->getTextureName()));
}
video::ITexture* texture = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(surface->getTextureName()) : NULL;
//material
// same lightmap name as above where they are created
io::path lmapName = lmprefix;
lmapName += "LMAP_";
lmapName += io::path(surface->getLightMapId());
......
......@@ -68,8 +68,7 @@ namespace scene
scene::IMesh* createCSMMesh(io::IReadFile* file);
scene::IMesh* createIrrlichtMesh(const CSMFile* csmFile,
const core::stringc& textureRoot, const io::path& lmprefix);
scene::IMesh* createIrrlichtMesh(const CSMFile* csmFile, const io::path& lmprefix);
io::IFileSystem* FileSystem;
scene::ISceneManager* SceneManager;
......
......@@ -6,6 +6,7 @@
#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_
#include "CColladaFileLoader.h"
#include "CMeshTextureLoader.h"
#include "os.h"
#include "IXMLReader.h"
#include "IDummyTransformationSceneNode.h"
......@@ -329,6 +330,8 @@ CColladaFileLoader::CColladaFileLoader(scene::ISceneManager* smgr,
#ifdef _DEBUG
setDebugName("CColladaFileLoader");
#endif
TextureLoader = new CMeshTextureLoader( FileSystem, SceneManager->getVideoDriver() );
}
......@@ -361,6 +364,9 @@ IAnimatedMesh* CColladaFileLoader::createMesh(io::IReadFile* file)
if (!reader)
return 0;
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
CurrentlyLoadingMesh = file->getFileName();
CreateInstances = SceneManager->getParameters()->getAttributeAsBool(
scene::COLLADA_CREATE_SCENE_INSTANCES);
......@@ -2799,9 +2805,7 @@ video::ITexture* CColladaFileLoader::getTextureFromImage(core::stringc uri, SCol
{
if (Images[i].Source.size() && Images[i].SourceIsFilename)
{
if (FileSystem->existFile(Images[i].Source))
return driver->getTexture(Images[i].Source);
return driver->getTexture((FileSystem->getFileDir(CurrentlyLoadingMesh)+"/"+Images[i].Source));
return getMeshTextureLoader() ? getMeshTextureLoader()->getTexture( Images[i].Source ) : NULL;
}
else
if (Images[i].Source.size())
......
......@@ -22,6 +22,7 @@
#endif
#include "CDMFLoader.h"
#include "CMeshTextureLoader.h"
#include "ISceneManager.h"
#include "IAttributes.h"
#include "SAnimatedMesh.h"
......@@ -42,32 +43,21 @@ CDMFLoader::CDMFLoader(ISceneManager* smgr, io::IFileSystem* filesys)
#ifdef _DEBUG
IReferenceCounted::setDebugName("CDMFLoader");
#endif
}
TextureLoader = new CMeshTextureLoader( FileSystem, SceneMgr->getVideoDriver() );
}
void CDMFLoader::findFile(bool use_mat_dirs, const core::stringc& path, const core::stringc& matPath, core::stringc& filename)
void CDMFLoader::addMaterialPath(core::stringc& filename, const core::stringc& matPath)
{
// path + texpath + full name
if (use_mat_dirs && FileSystem->existFile(path+matPath+filename))
filename = path+matPath+filename;
// path + full name
else if (FileSystem->existFile(path+filename))
filename = path+filename;
// path + texpath + base name
else if (use_mat_dirs && FileSystem->existFile(path+matPath+FileSystem->getFileBasename(filename)))
filename = path+matPath+FileSystem->getFileBasename(filename);
// path + base name
else if (FileSystem->existFile(path+FileSystem->getFileBasename(filename)))
filename = path+FileSystem->getFileBasename(filename);
// texpath + full name
else if (use_mat_dirs && FileSystem->existFile(matPath+filename))
c8 last = matPath.lastChar();
if ( last == '/' || last == '\\' )
filename = matPath+filename;
// texpath + base name
else if (use_mat_dirs && FileSystem->existFile(matPath+FileSystem->getFileBasename(filename)))
filename = matPath+FileSystem->getFileBasename(filename);
// base name
else if (FileSystem->existFile(FileSystem->getFileBasename(filename)))
filename = FileSystem->getFileBasename(filename);
else
{
core::stringc matPathSlash(matPath);
matPathSlash.append('/');
filename = matPathSlash+filename;
}
}
......@@ -79,6 +69,15 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
{
if (!file)
return 0;
if ( getMeshTextureLoader() )
{
getMeshTextureLoader()->setMeshFile(file);
if ( SceneMgr->getParameters()->existsAttribute(DMF_TEXTURE_PATH) )
getMeshTextureLoader()->setTexturePath( SceneMgr->getParameters()->getAttributeAsString(DMF_TEXTURE_PATH) );
}
video::IVideoDriver* driver = SceneMgr->getVideoDriver();
//Load stringlist
......@@ -250,13 +249,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
#endif
const bool use_mat_dirs=!SceneMgr->getParameters()->getAttributeAsBool(DMF_IGNORE_MATERIALS_DIRS);
core::stringc path;
if ( SceneMgr->getParameters()->existsAttribute(DMF_TEXTURE_PATH) )
path = SceneMgr->getParameters()->getAttributeAsString(DMF_TEXTURE_PATH);
else
path = FileSystem->getFileDir(file->getFileName());
path += ('/');
for (i=0; i<mesh->getMeshBufferCount(); i++)
{
//texture and lightmap
......@@ -271,8 +263,10 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
{
if (materiali[i].textureBlend==4)
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT,true);
findFile(use_mat_dirs, path, materiali[i].pathName, materiali[i].textureName);
tex = driver->getTexture(materiali[i].textureName);
if ( use_mat_dirs )
addMaterialPath(materiali[i].textureName, materiali[i].pathName);
tex = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture( materiali[i].textureName ) : NULL;
}
//Primary texture is just a color
else if(materiali[i].textureFlag==1)
......@@ -301,8 +295,9 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//Lightmap is present
if (materiali[i].lightmapFlag == 0)
{
findFile(use_mat_dirs, path, materiali[i].pathName, materiali[i].lightmapName);
lig = driver->getTexture(materiali[i].lightmapName);
if ( use_mat_dirs )
addMaterialPath(materiali[i].lightmapName, materiali[i].pathName);
lig = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(materiali[i].lightmapName) : NULL;
}
else //no lightmap
{
......
......@@ -78,7 +78,7 @@ namespace scene
bool mode = true);
private:
void findFile(bool use_mat_dirs, const core::stringc& path, const core::stringc& matPath, core::stringc& filename);
void addMaterialPath(core::stringc& filename, const core::stringc& matPath);
ISceneManager* SceneMgr;
io::IFileSystem* FileSystem;
......
......@@ -68,6 +68,8 @@ Version 1.0 - 29 July 2004
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_
#include "CLMTSMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "SMeshBufferLightMap.h"
#include "SAnimatedMesh.h"
#include "SMeshBuffer.h"
......@@ -75,7 +77,6 @@ Version 1.0 - 29 July 2004
#include "IReadFile.h"
#include "IAttributes.h"
#include "ISceneManager.h"
#include "CLMTSMeshFileLoader.h"
#include "os.h"
namespace irr
......@@ -97,6 +98,8 @@ CLMTSMeshFileLoader::CLMTSMeshFileLoader(io::IFileSystem* fs,
if (FileSystem)
FileSystem->grab();
TextureLoader = new CMeshTextureLoader( FileSystem, Driver );
}
......@@ -131,6 +134,9 @@ bool CLMTSMeshFileLoader::isALoadableFileExtension(const io::path& filename) con
IAnimatedMesh* CLMTSMeshFileLoader::createMesh(io::IReadFile* file)
{
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
u32 i;
u32 id;
......@@ -326,19 +332,17 @@ void CLMTSMeshFileLoader::loadTextures(SMesh* mesh)
core::array<u32> id2id;
id2id.reallocate(Header.TextureCount);
const core::stringc Path = Parameters->getAttributeAsString(LMTS_TEXTURE_PATH);
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setTexturePath(Parameters->getAttributeAsString(LMTS_TEXTURE_PATH));
core::stringc s;
for (u32 t=0; t<Header.TextureCount; ++t)
{
video::ITexture* tmptex = 0;
s = Path;
s.append(Textures[t].Filename);
if (FileSystem->existFile(s))
tmptex = Driver->getTexture(s);
else
video::ITexture* tmptex = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(Textures[t].Filename) : NULL;
if ( !tmptex )
{
os::Printer::log("LMTS WARNING: Texture does not exist", s.c_str(), ELL_WARNING);
}
if (Textures[t].Flags & 0x01)
{
......
......@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CLWOMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "os.h"
#include "SAnimatedMesh.h"
#include "SMesh.h"
......@@ -123,6 +124,8 @@ CLWOMeshFileLoader::CLWOMeshFileLoader(scene::ISceneManager* smgr,
#ifdef _DEBUG
setDebugName("CLWOMeshFileLoader");
#endif
TextureLoader = new CMeshTextureLoader( FileSystem, SceneManager->getVideoDriver() );
}
......@@ -145,6 +148,9 @@ bool CLWOMeshFileLoader::isALoadableFileExtension(const io::path& filename) cons
//! creates/loads an animated mesh from the file.
IAnimatedMesh* CLWOMeshFileLoader::createMesh(io::IReadFile* file)
{
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
File = file;
if (Mesh)
......@@ -2090,22 +2096,14 @@ bool CLWOMeshFileLoader::readFileHeader()
video::ITexture* CLWOMeshFileLoader::loadTexture(const core::stringc& file)
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if (FileSystem->existFile(file))
return driver->getTexture(file);
core::stringc strippedName=FileSystem->getFileBasename(file);
if (FileSystem->existFile(strippedName))
return driver->getTexture(strippedName);
core::stringc newpath = FileSystem->getFileDir(File->getFileName());
newpath.append("/");
newpath.append(strippedName);
if (FileSystem->existFile(newpath))
return driver->getTexture(newpath);
os::Printer::log("Could not load texture", file.c_str(), ELL_WARNING);
return 0;
video::ITexture* texture = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(file) : NULL;
if (!texture)
{
os::Printer::log("Could not load texture", file.c_str(), ELL_WARNING);
}
return texture;
}
......
......@@ -12,6 +12,7 @@
#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_
#include "CMY3DMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "SAnimatedMesh.h"
#include "SMeshBuffer.h"
......@@ -60,6 +61,8 @@ CMY3DMeshFileLoader::CMY3DMeshFileLoader(ISceneManager* scmgr, io::IFileSystem*
if (FileSystem)
FileSystem->grab();
TextureLoader = new CMeshTextureLoader( FileSystem, SceneManager->getVideoDriver() );
}
......@@ -78,17 +81,16 @@ bool CMY3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) con
IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
{
if ( getMeshTextureLoader() )
{
getMeshTextureLoader()->setMeshFile(file);
getMeshTextureLoader()->setTexturePath(SceneManager->getParameters()->getAttributeAsString(MY3D_TEXTURE_PATH));
}
MaterialEntry.clear();
MeshBufferEntry.clear();
ChildNodes.clear();
// working directory (from which we load the scene)
core::stringc filepath = FileSystem->getFileDir(file->getFileName());
if (filepath==".")
filepath="";
else
filepath.append("/");
// read file into memory
SMyFileHeader fileHeader;
file->read(&fileHeader, sizeof(SMyFileHeader));
......@@ -134,9 +136,6 @@ IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
return 0;
}
core::stringc texturePath =
SceneManager->getParameters()->getAttributeAsString(MY3D_TEXTURE_PATH);
file->read(&id, sizeof(id));
#ifdef __BIG_ENDIAN__
id = os::Byteswap::byteswap(id);
......@@ -188,12 +187,9 @@ IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
me.Texture2FileName = texturePath.size() ? texturePath : filepath;
me.Texture2FileName.append("Lightmaps/");
me.Texture2FileName = "Lightmaps/";
me.Texture2FileName.append(name);
if (name.size())
me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName);
me.Texture2 = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(me.Texture2FileName) : NULL;
me.MaterialType = video::EMT_LIGHTMAP_M2;
gotLightMap = true;
......@@ -203,21 +199,26 @@ IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file)
else
if (!gotLightMap && gotMainMap)
{
me.Texture2FileName = texturePath.size() ? texturePath : filepath;
me.Texture2FileName.append(name);
if (name.size())
me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName);
if ( getMeshTextureLoader() )
{
me.Texture2 = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(name) : NULL;
me.Texture2FileName = getMeshTextureLoader()->getRecentTextureName();
}
else
me.Texture2FileName = name;
me.MaterialType = video::EMT_REFLECTION_2_LAYER;
}
else
if (!gotMainMap && !gotLightMap)
{
me.Texture1FileName = filepath;
me.Texture1FileName.append(name);
if (name.size())
me.Texture1 = SceneManager->getVideoDriver()->getTexture(me.Texture1FileName);
if ( getMeshTextureLoader() )
{
me.Texture1 = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(name) : NULL;
me.Texture1FileName = getMeshTextureLoader()->getRecentTextureName();
}
else
me.Texture1FileName = name;
gotMainMap = true;
me.MaterialType = video::EMT_SOLID;
......
#include "CMeshTextureLoader.h"
#include "IFileSystem.h"
#include "IVideoDriver.h"
namespace irr
{
namespace scene
{
CMeshTextureLoader::CMeshTextureLoader(irr::io::IFileSystem* fs, irr::video::IVideoDriver* driver)
: FileSystem(fs)
, VideoDriver(driver)
, MeshFile(0)
, MaterialFile(0)
, WasRecentTextureCached(false)
{
}
//! Set a custom texture path.
void CMeshTextureLoader::setTexturePath(const irr::io::path& path)
{
TexturePath = path;
preparePath(TexturePath);
}
//! Get the current custom texture path.
const irr::io::path& CMeshTextureLoader::getTexturePath() const
{
return TexturePath;
}
bool CMeshTextureLoader::checkTextureName( const irr::io::path& filename, bool checkCache)
{
if (FileSystem->existFile(filename))
{
TextureName = filename;
WasRecentTextureCached = checkCache && VideoDriver->findTexture(TextureName) != 0;
return true;
}
return false;
}
//! Get the texture by searching for it in all paths that makes sense for the given textureName.
irr::video::ITexture* CMeshTextureLoader::getTexture(const irr::io::path& textureName)
{
if ( textureName.empty() || !FileSystem || !VideoDriver)
return NULL;
// Pre-process texture filename.
irr::io::path simplifiedTexName(textureName);
simplifiedTexName.replace(_IRR_TEXT('\\'),_IRR_TEXT('/'));
bool checkCache = getCheckForCachedTextures();
// user defined texture path
if ( !TexturePath.empty() )
{
if ( checkTextureName(TexturePath + simplifiedTexName, checkCache) )
return VideoDriver->getTexture(TextureName);
if ( checkTextureName(TexturePath + FileSystem->getFileBasename(simplifiedTexName), checkCache) )
return VideoDriver->getTexture(TextureName);
}
// just the name itself
if ( checkTextureName(simplifiedTexName, checkCache) )
return VideoDriver->getTexture(TextureName);
// look in files relative to the folder of the meshfile
if ( MeshFile )
{
if ( MeshPath.empty() )
{
MeshPath = FileSystem->getFileDir(MeshFile->getFileName());
preparePath(MeshPath);
}
if ( !MeshPath.empty() )
{
if ( checkTextureName(MeshPath + simplifiedTexName, checkCache) )
return VideoDriver->getTexture(TextureName);
if ( checkTextureName(MeshPath + FileSystem->getFileBasename(simplifiedTexName), checkCache) )
return VideoDriver->getTexture(TextureName);
}
}
// look in files relative to the folder of the materialfile
if ( MaterialFile )
{
if ( MaterialPath.empty() )
{
MaterialPath = FileSystem->getFileDir(MaterialFile->getFileName());
preparePath(MaterialPath);
}
if ( !MaterialPath.empty() )
{
if ( checkTextureName(MaterialPath + simplifiedTexName, checkCache) )
return VideoDriver->getTexture(TextureName);
if ( checkTextureName(MaterialPath + FileSystem->getFileBasename(simplifiedTexName), checkCache) )
return VideoDriver->getTexture(TextureName);
}
}
// check current working directory
if ( checkTextureName(FileSystem->getFileBasename(simplifiedTexName), checkCache) )
return VideoDriver->getTexture(TextureName);
TextureName = _IRR_TEXT("");
return NULL;
}
//! Check which texture-name was last recently used.
const irr::io::path& CMeshTextureLoader::getRecentTextureName() const
{
return TextureName;
}
//! Check if the last call to getTexture found a texture which was already cached.
bool CMeshTextureLoader::wasRecentTextureInCache() const
{
return WasRecentTextureCached;
}
//! Meshloaders will search paths relative to the meshFile.
void CMeshTextureLoader::setMeshFile(const irr::io::IReadFile* meshFile)
{
// no grab (would need a weak_ptr)
MeshFile = meshFile;
MeshPath = _IRR_TEXT(""); // do a lazy evaluation later
}
//! Meshloaders will try to look relative to the path of the materialFile
void CMeshTextureLoader::setMaterialFile(const irr::io::IReadFile* materialFile)
{
// no grab (would need a weak_ptr)
MaterialFile = materialFile;
MaterialPath = _IRR_TEXT(""); // do a lazy evaluation later
}
} // end namespace scnene
} // end namespace irr
#ifndef IRR_C_MESH_TEXTURE_LOADER_H_INCLUDED
#define IRR_C_MESH_TEXTURE_LOADER_H_INCLUDED
#include "IMeshTextureLoader.h"
namespace irr
{
namespace io
{
class IFileSystem;
} // end namespace io
namespace video
{
class IVideoDriver;
}
namespace scene
{
class CMeshTextureLoader : public IMeshTextureLoader
{
public:
CMeshTextureLoader(irr::io::IFileSystem* fs, irr::video::IVideoDriver* driver);
//! Set a custom texture path.
/** This is the first path the texture-loader should search. */
virtual void setTexturePath(const irr::io::path& path) _IRR_OVERRIDE_;
//! Get the current custom texture path.
virtual const irr::io::path& getTexturePath() const _IRR_OVERRIDE_;
//! Get the texture by searching for it in all paths that makes sense for the given textureName.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
\param textureName Texturename as used in the mesh-format
\return Pointer to the texture. Returns 0 if loading failed.*/
virtual irr::video::ITexture* getTexture(const irr::io::path& textureName) _IRR_OVERRIDE_;
//! Check which texture-name was last recently used.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
It's updated on getTexture calls. When those succeed this will return the full name which was
used to find the texture. Then getTexture failed it will contain the last name which was tried. */
virtual const irr::io::path& getRecentTextureName() const _IRR_OVERRIDE_;
//! Check if the last call to getTexture found a texture which was already cached.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
This will only work when a) CheckForCachedTextures is set to true and b) getTexture was
successful.
\return When true the textuer was already cached. When false the texture was loaded newly. */
virtual bool wasRecentTextureInCache() const _IRR_OVERRIDE_;
//! Meshloaders will search paths relative to the meshFile.
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
Any values you set here will likely be overwritten internally. */
virtual void setMeshFile(const irr::io::IReadFile* meshFile) _IRR_OVERRIDE_;
//! Meshloaders will try to look relative to the path of the materialFile
/** Usually you do not have to use this method, it is used internally by IMeshLoader's.
Any values you set here will likely be overwritten internally. */
virtual void setMaterialFile(const irr::io::IReadFile* materialFile) _IRR_OVERRIDE_;
protected:
// make certain path's have a certain internal format
void preparePath(irr::io::path& directory)
{
if (!directory.empty())
{
if (directory == _IRR_TEXT("."))
directory = _IRR_TEXT("");
directory.replace(_IRR_TEXT('\\'),_IRR_TEXT('/'));
if (directory.lastChar() != _IRR_TEXT('/'))
directory.append(_IRR_TEXT('/'));
}
}
// Save the texturename when it's a an existing file
bool checkTextureName( const irr::io::path& filename, bool checkCache);
private:
irr::io::IFileSystem * FileSystem;
irr::video::IVideoDriver* VideoDriver;
irr::io::path TexturePath;
const irr::io::IReadFile* MeshFile;
irr::io::path MeshPath;
const irr::io::IReadFile* MaterialFile;
irr::io::path MaterialPath;
irr::io::path TextureName;
bool WasRecentTextureCached;
};
} // end namespace scene
} // end namespace irr
#endif
......@@ -6,6 +6,7 @@
#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
#include "COBJMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "IMeshManipulator.h"
#include "IVideoDriver.h"
#include "SMesh.h"
......@@ -38,6 +39,8 @@ COBJMeshFileLoader::COBJMeshFileLoader(scene::ISceneManager* smgr, io::IFileSyst
if (FileSystem)
FileSystem->grab();
TextureLoader = new CMeshTextureLoader( FileSystem, SceneManager->getVideoDriver() );
}
......@@ -63,6 +66,12 @@ bool COBJMeshFileLoader::isALoadableFileExtension(const io::path& filename) cons
//! See IReferenceCounted::drop() for more information.
IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
{
if (!file)
return 0;
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
const long filesize = file->getSize();
if (!filesize)
return 0;
......@@ -420,31 +429,13 @@ const c8* COBJMeshFileLoader::readTextures(const c8* bufPtr, const c8* const buf
currMaterial->Meshbuffer->Material.setFlag(video::EMF_TEXTURE_WRAP, video::ETC_CLAMP);
io::path texname(textureNameBuf);
texname.replace('\\', '/');
video::ITexture * texture = 0;
bool newTexture=false;
if (texname.size())
if (texname.size() && getMeshTextureLoader())
{
io::path texnameWithUserPath( SceneManager->getParameters()->getAttributeAsString(OBJ_TEXTURE_PATH) );
if ( texnameWithUserPath.size() )
{
texnameWithUserPath += '/';
texnameWithUserPath += texname;
}
if (FileSystem->existFile(texnameWithUserPath))
texture = SceneManager->getVideoDriver()->getTexture(texnameWithUserPath);
else if (FileSystem->existFile(texname))
{
newTexture = SceneManager->getVideoDriver()->findTexture(texname) == 0;
texture = SceneManager->getVideoDriver()->getTexture(texname);
}
else
{
newTexture = SceneManager->getVideoDriver()->findTexture(relPath + texname) == 0;
// try to read in the relative path, the .obj is loaded from
texture = SceneManager->getVideoDriver()->getTexture( relPath + texname );
}
texture = getMeshTextureLoader()->getTexture(texname);
newTexture = !getMeshTextureLoader()->wasRecentTextureInCache();
}
if ( texture )
{
......@@ -497,6 +488,13 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, const io::path& relPath)
return;
}
if ( getMeshTextureLoader() )
{
getMeshTextureLoader()->setMaterialFile(mtlReader);
getMeshTextureLoader()->setCheckForCachedTextures(true);
getMeshTextureLoader()->setTexturePath(SceneManager->getParameters()->getAttributeAsString(OBJ_TEXTURE_PATH));
}
const long filesize = mtlReader->getSize();
if (!filesize)
{
......
......@@ -13,6 +13,7 @@
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
#include "COCTLoader.h"
#include "CMeshTextureLoader.h"
#include "IVideoDriver.h"
#include "IFileSystem.h"
#include "os.h"
......@@ -35,6 +36,8 @@ COCTLoader::COCTLoader(ISceneManager* smgr, io::IFileSystem* fs)
#endif
if (FileSystem)
FileSystem->grab();
TextureLoader = new CMeshTextureLoader( FileSystem, SceneManager->getVideoDriver() );
}
......@@ -85,6 +88,9 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
if (!file)
return 0;
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
octHeader header;
file->read(&header, sizeof(octHeader));
......@@ -199,16 +205,9 @@ IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file)
tex.reallocate(header.numTextures + 1);
tex.push_back(0);
const core::stringc relpath = FileSystem->getFileDir(file->getFileName())+"/";
for (i = 1; i < (header.numTextures + 1); i++)
{
core::stringc path(textures[i-1].fileName);
path.replace('\\','/');
if (FileSystem->existFile(path))
tex.push_back(SceneManager->getVideoDriver()->getTexture(path));
else
// try to read in the relative path of the OCT file
tex.push_back(SceneManager->getVideoDriver()->getTexture( (relpath + path) ));
tex.push_back( getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(textures[i-1].fileName) : NULL );
}
// prepare lightmaps
......
......@@ -7,6 +7,7 @@
#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_
#include "COgreMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "os.h"
#include "SMeshBuffer.h"
#include "SAnimatedMesh.h"
......@@ -76,6 +77,8 @@ COgreMeshFileLoader::COgreMeshFileLoader(io::IFileSystem* fs, video::IVideoDrive
if (Driver)
Driver->grab();
TextureLoader = new CMeshTextureLoader( FileSystem, Driver );
}
......@@ -109,6 +112,12 @@ bool COgreMeshFileLoader::isALoadableFileExtension(const io::path& filename) con
//! See IReferenceCounted::drop() for more information.
IAnimatedMesh* COgreMeshFileLoader::createMesh(io::IReadFile* file)
{
if ( !file )
return 0;
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
s16 id;
file->read(&id, 2);
......@@ -469,10 +478,13 @@ void COgreMeshFileLoader::composeMeshBufferMaterial(scene::IMeshBuffer* mb, cons
material=Materials[k].Techniques[0].Passes[0].Material;
for (u32 i=0; i<Materials[k].Techniques[0].Passes[0].Texture.Filename.size(); ++i)
{
if (FileSystem->existFile(Materials[k].Techniques[0].Passes[0].Texture.Filename[i]))
material.setTexture(i, Driver->getTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename[i]));
else
material.setTexture(i, Driver->getTexture((CurrentlyLoadingFromPath+"/"+FileSystem->getFileBasename(Materials[k].Techniques[0].Passes[0].Texture.Filename[i]))));
video::ITexture * texture = NULL;
if ( getMeshTextureLoader() )
{
texture = getMeshTextureLoader()->getTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename[i]);
if ( texture )
material.setTexture(i, texture);
}
}
break;
}
......
......@@ -7,6 +7,7 @@
#ifdef _IRR_COMPILE_WITH_SMF_LOADER_
#include "CSMFMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "SAnimatedMesh.h"
#include "SMeshBuffer.h"
#include "IReadFile.h"
......@@ -19,9 +20,10 @@ namespace irr
namespace scene
{
CSMFMeshFileLoader::CSMFMeshFileLoader(video::IVideoDriver* driver)
CSMFMeshFileLoader::CSMFMeshFileLoader(irr::io::IFileSystem* fs, video::IVideoDriver* driver)
: Driver(driver)
{
TextureLoader = new CMeshTextureLoader( fs, driver );
}
//! Returns true if the file might be loaded by this class.
......@@ -33,6 +35,12 @@ bool CSMFMeshFileLoader::isALoadableFileExtension(const io::path& filename) cons
//! Creates/loads an animated mesh from the file.
IAnimatedMesh* CSMFMeshFileLoader::createMesh(io::IReadFile* file)
{
if ( !file )
return 0;
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
// create empty mesh
SMesh *mesh = new SMesh();
......@@ -93,9 +101,12 @@ void CSMFMeshFileLoader::loadLimb(io::IReadFile* file, SMesh* mesh, const core::
for (const c8 **ext = extensions; !texture && *ext; ++ext)
{
texture = Driver->getTexture(textureName + *ext);
texture = getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(textureName + *ext) : NULL;
if (texture)
{
textureName = textureName + *ext;
break;
}
}
// find the correct mesh buffer
u32 i;
......
// Copyright (C) 2010-2012 Gaz Davidson
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_SMF_MESH_LOADER_H_INCLUDED__
#define __C_SMF_MESH_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "SMesh.h"
namespace irr
{
namespace video
{
class IVideoDriver;
}
namespace scene
{
//! Class which can load
class CSMFMeshFileLoader : public virtual IMeshLoader
{
public:
CSMFMeshFileLoader(video::IVideoDriver* driver);
//! Returns true if the file might be loaded by this class.
virtual bool isALoadableFileExtension(const io::path& filename) const _IRR_OVERRIDE_;
//! Creates/loads an animated mesh from the file.
virtual IAnimatedMesh* createMesh(io::IReadFile* file) _IRR_OVERRIDE_;
private:
void loadLimb(io::IReadFile* file, scene::SMesh* mesh, const core::matrix4 &parentTransformation);
video::IVideoDriver* Driver;
};
} // end namespace scene
namespace io
{
class BinaryFile
{
public:
//! reads most types from the given file, moving the file pointer along
template <class T>
static void read(io::IReadFile* file, T &out, bool bigEndian=false);
//! reads a 3d vector from the file, moving the file pointer along
static void read(io::IReadFile* file, core::vector3df &outVector2d, bool bigEndian=false);
//! reads a 2d vector from the file, moving the file pointer along
static void read(io::IReadFile* file, core::vector2df &outVector2d, bool bigEndian=false);
//! reads a null terminated string from the file, moving the file pointer along
static void read(io::IReadFile* file, core::stringc &outString, bool bigEndian=false);
};
}
} // end namespace irr
#endif // __C_SMF_MESH_LOADER_H_INCLUDED__
// Copyright (C) 2010-2012 Gaz Davidson
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_SMF_MESH_LOADER_H_INCLUDED__
#define __C_SMF_MESH_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "SMesh.h"
namespace irr
{
namespace video
{
class IVideoDriver;
}
namespace io
{
class IFileSystem;
}
namespace scene
{
//! Class which can load
class CSMFMeshFileLoader : public virtual IMeshLoader
{
public:
CSMFMeshFileLoader(irr::io::IFileSystem* fs, video::IVideoDriver* driver);
//! Returns true if the file might be loaded by this class.
virtual bool isALoadableFileExtension(const io::path& filename) const _IRR_OVERRIDE_;
//! Creates/loads an animated mesh from the file.
virtual IAnimatedMesh* createMesh(io::IReadFile* file) _IRR_OVERRIDE_;
private:
void loadLimb(io::IReadFile* file, scene::SMesh* mesh, const core::matrix4 &parentTransformation);
video::IVideoDriver* Driver;
};
} // end namespace scene
namespace io
{
class BinaryFile
{
public:
//! reads most types from the given file, moving the file pointer along
template <class T>
static void read(io::IReadFile* file, T &out, bool bigEndian=false);
//! reads a 3d vector from the file, moving the file pointer along
static void read(io::IReadFile* file, core::vector3df &outVector2d, bool bigEndian=false);
//! reads a 2d vector from the file, moving the file pointer along
static void read(io::IReadFile* file, core::vector2df &outVector2d, bool bigEndian=false);
//! reads a null terminated string from the file, moving the file pointer along
static void read(io::IReadFile* file, core::stringc &outString, bool bigEndian=false);
};
}
} // end namespace irr
#endif // __C_SMF_MESH_LOADER_H_INCLUDED__
......@@ -238,7 +238,7 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
MeshLoaderList.push_back(new CPLYMeshFileLoader(this));
#endif
#ifdef _IRR_COMPILE_WITH_SMF_LOADER_
MeshLoaderList.push_back(new CSMFMeshFileLoader(Driver));
MeshLoaderList.push_back(new CSMFMeshFileLoader(FileSystem, Driver));
#endif
#ifdef _IRR_COMPILE_WITH_OCT_LOADER_
MeshLoaderList.push_back(new COCTLoader(this, FileSystem));
......
......@@ -7,6 +7,7 @@
#ifdef _IRR_COMPILE_WITH_X_LOADER_
#include "CXMeshFileLoader.h"
#include "CMeshTextureLoader.h"
#include "os.h"
#include "fast_atof.h"
......@@ -35,6 +36,8 @@ CXMeshFileLoader::CXMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem*
#ifdef _DEBUG
setDebugName("CXMeshFileLoader");
#endif
TextureLoader = new CMeshTextureLoader( FileSystem, SceneManager->getVideoDriver() );
}
......@@ -50,18 +53,21 @@ bool CXMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
IAnimatedMesh* CXMeshFileLoader::createMesh(io::IReadFile* f)
IAnimatedMesh* CXMeshFileLoader::createMesh(io::IReadFile* file)
{
if (!f)
if (!file)
return 0;
if ( getMeshTextureLoader() )
getMeshTextureLoader()->setMeshFile(file);
#ifdef _XREADER_DEBUG
u32 time = os::Timer::getRealTime();
#endif
AnimatedMesh = new CSkinnedMesh();
if (load(f))
if (load(file))
{
AnimatedMesh->finalize();
}
......@@ -458,7 +464,6 @@ bool CXMeshFileLoader::readFileIntoMemory(io::IReadFile* file)
P = &Buffer[16];
readUntilEndOfLine();
FilePath = FileSystem->getFileDir(file->getFileName()) + "/";
return true;
}
......@@ -1524,19 +1529,8 @@ bool CXMeshFileLoader::parseDataObjectMaterial(video::SMaterial& material)
if (!parseDataObjectTextureFilename(TextureFileName))
return false;
// original name
if (FileSystem->existFile(TextureFileName))
material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(TextureFileName));
// mesh path
else
{
TextureFileName=FilePath + FileSystem->getFileBasename(TextureFileName);
if (FileSystem->existFile(TextureFileName))
material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(TextureFileName));
// working directory
else
material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(FileSystem->getFileBasename(TextureFileName)));
}
material.setTexture( textureLayer, getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(TextureFileName) : NULL );
++textureLayer;
if (textureLayer==2)
material.MaterialType=video::EMT_LIGHTMAP;
......@@ -1549,19 +1543,8 @@ bool CXMeshFileLoader::parseDataObjectMaterial(video::SMaterial& material)
if (!parseDataObjectTextureFilename(TextureFileName))
return false;
// original name
if (FileSystem->existFile(TextureFileName))
material.setTexture(1, SceneManager->getVideoDriver()->getTexture(TextureFileName));
// mesh path
else
{
TextureFileName=FilePath + FileSystem->getFileBasename(TextureFileName);
if (FileSystem->existFile(TextureFileName))
material.setTexture(1, SceneManager->getVideoDriver()->getTexture(TextureFileName));
// working directory
else
material.setTexture(1, SceneManager->getVideoDriver()->getTexture(FileSystem->getFileBasename(TextureFileName)));
}
material.setTexture( 1, getMeshTextureLoader() ? getMeshTextureLoader()->getTexture(TextureFileName) : NULL );
if (textureLayer==1)
++textureLayer;
}
......
This diff is collapsed.
......@@ -919,6 +919,7 @@
<ClInclude Include="..\..\include\IMeshLoader.h" />
<ClInclude Include="..\..\include\IMeshManipulator.h" />
<ClInclude Include="..\..\include\IMeshSceneNode.h" />
<ClInclude Include="..\..\include\IMeshTextureLoader.h" />
<ClInclude Include="..\..\include\IMeshWriter.h" />
<ClInclude Include="..\..\include\IMetaTriangleSelector.h" />
<ClInclude Include="..\..\include\IParticleAffector.h" />
......@@ -1014,6 +1015,7 @@
<ClInclude Include="CLWOMeshFileLoader.h" />
<ClInclude Include="CMD2MeshFileLoader.h" />
<ClInclude Include="CMD3MeshFileLoader.h" />
<ClInclude Include="CMeshTextureLoader.h" />
<ClInclude Include="CMS3DMeshFileLoader.h" />
<ClInclude Include="CMY3DHelper.h" />
<ClInclude Include="CMY3DMeshFileLoader.h" />
......@@ -1263,6 +1265,7 @@
<ClCompile Include="CLWOMeshFileLoader.cpp" />
<ClCompile Include="CMD2MeshFileLoader.cpp" />
<ClCompile Include="CMD3MeshFileLoader.cpp" />
<ClCompile Include="CMeshTextureLoader.cpp" />
<ClCompile Include="CMS3DMeshFileLoader.cpp" />
<ClCompile Include="CMY3DMeshFileLoader.cpp" />
<ClCompile Include="COBJMeshFileLoader.cpp" />
......
......@@ -353,6 +353,9 @@
</ClInclude>
<ClInclude Include="..\..\include\IMeshSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IMeshTextureLoader.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IMeshWriter.h">
<Filter>include\scene</Filter>
......@@ -623,6 +626,9 @@
</ClInclude>
<ClInclude Include="CMD3MeshFileLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>
<ClInclude Include="CMeshTextureLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>
<ClInclude Include="CMS3DMeshFileLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
......@@ -1378,6 +1384,9 @@
</ClCompile>
<ClCompile Include="CMD3MeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CMeshTextureLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CMS3DMeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
......
......@@ -926,6 +926,7 @@
<ClInclude Include="..\..\include\IMeshLoader.h" />
<ClInclude Include="..\..\include\IMeshManipulator.h" />
<ClInclude Include="..\..\include\IMeshSceneNode.h" />
<ClInclude Include="..\..\include\IMeshTextureLoader.h" />
<ClInclude Include="..\..\include\IMeshWriter.h" />
<ClInclude Include="..\..\include\IMetaTriangleSelector.h" />
<ClInclude Include="..\..\include\IParticleAffector.h" />
......@@ -1021,6 +1022,7 @@
<ClInclude Include="CLWOMeshFileLoader.h" />
<ClInclude Include="CMD2MeshFileLoader.h" />
<ClInclude Include="CMD3MeshFileLoader.h" />
<ClInclude Include="CMeshTextureLoader.h" />
<ClInclude Include="CMS3DMeshFileLoader.h" />
<ClInclude Include="CMY3DHelper.h" />
<ClInclude Include="CMY3DMeshFileLoader.h" />
......@@ -1270,6 +1272,7 @@
<ClCompile Include="CLWOMeshFileLoader.cpp" />
<ClCompile Include="CMD2MeshFileLoader.cpp" />
<ClCompile Include="CMD3MeshFileLoader.cpp" />
<ClCompile Include="CMeshTextureLoader.cpp" />
<ClCompile Include="CMS3DMeshFileLoader.cpp" />
<ClCompile Include="CMY3DMeshFileLoader.cpp" />
<ClCompile Include="COBJMeshFileLoader.cpp" />
......
......@@ -356,6 +356,9 @@
</ClInclude>
<ClInclude Include="..\..\include\IMeshSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IMeshTextureLoader.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IMeshWriter.h">
<Filter>include\scene</Filter>
......@@ -626,6 +629,9 @@
</ClInclude>
<ClInclude Include="CMD3MeshFileLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>
<ClInclude Include="CMeshTextureLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>
<ClInclude Include="CMS3DMeshFileLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
......@@ -1378,6 +1384,9 @@
</ClCompile>
<ClCompile Include="CMD3MeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CMeshTextureLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CMS3DMeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
......
......@@ -925,6 +925,10 @@
RelativePath=".\..\..\include\IMeshSceneNode.h"
>
</File>
<File
RelativePath=".\..\..\include\IMeshTextureLoader.h"
>
</File>
<File
RelativePath="..\..\include\IMeshWriter.h"
>
......@@ -2424,6 +2428,14 @@
RelativePath=".\CMeshSceneNode.h"
>
</File>
<File
RelativePath=".\CMeshTextureLoader.cpp"
>
</File>
<File
RelativePath=".\CMeshTextureLoader.h"
>
</File>
<File
RelativePath=".\COctreeSceneNode.cpp"
>
......
......@@ -1040,6 +1040,10 @@
RelativePath="..\..\include\IMeshSceneNode.h"
>
</File>
<File
RelativePath="..\..\include\IMeshTextureLoader.h"
>
</File>
<File
RelativePath="..\..\include\IMeshWriter.h"
>
......@@ -1691,6 +1695,14 @@
RelativePath="CMeshSceneNode.h"
>
</File>
<File
RelativePath="CMeshTextureLoader.cpp"
>
</File>
<File
RelativePath="CMeshTextureLoader.h"
>
</File>
<File
RelativePath="COctreeSceneNode.cpp"
>
......
......@@ -644,6 +644,10 @@
RelativePath="..\..\include\IMeshSceneNode.h"
>
</File>
<File
RelativePath="..\..\include\IMeshTextureLoader.h"
>
</File>
<File
RelativePath="..\..\include\IMeshWriter.h"
>
......@@ -2013,6 +2017,14 @@
RelativePath="CMeshSceneNode.h"
>
</File>
<File
RelativePath="CMeshTextureLoader.cpp"
>
</File>
<File
RelativePath="CMeshTextureLoader.h"
>
</File>
<File
RelativePath="COctreeSceneNode.cpp"
>
......
......@@ -444,6 +444,9 @@
<File
RelativePath="..\..\include\IMeshSceneNode.h">
</File>
<File
RelativePath="..\..\include\IMeshTextureLoader.h">
</File>
<File
RelativePath="..\..\include\IMeshWriter.h">
</File>
......@@ -1062,6 +1065,12 @@
<File
RelativePath=".\CMeshSceneNode.h">
</File>
<File
RelativePath=".\CMeshTextureLoader.cpp">
</File>
<File
RelativePath=".\CMeshTextureLoader.h">
</File>
<File
RelativePath=".\CMetaTriangleSelector.cpp">
</File>
......
......@@ -29,7 +29,7 @@ VERSION_RELEASE = 0
#
#List of object files, separated based on engine architecture
IRRMESHLOADER = CBSPMeshFileLoader.o CMD2MeshFileLoader.o CMD3MeshFileLoader.o CMS3DMeshFileLoader.o CB3DMeshFileLoader.o C3DSMeshFileLoader.o COgreMeshFileLoader.o COBJMeshFileLoader.o CColladaFileLoader.o CCSMLoader.o CDMFLoader.o CLMTSMeshFileLoader.o CMY3DMeshFileLoader.o COCTLoader.o CXMeshFileLoader.o CIrrMeshFileLoader.o CSTLMeshFileLoader.o CLWOMeshFileLoader.o CPLYMeshFileLoader.o CSMFMeshFileLoader.o
IRRMESHLOADER = CBSPMeshFileLoader.o CMD2MeshFileLoader.o CMD3MeshFileLoader.o CMS3DMeshFileLoader.o CB3DMeshFileLoader.o C3DSMeshFileLoader.o COgreMeshFileLoader.o COBJMeshFileLoader.o CColladaFileLoader.o CCSMLoader.o CDMFLoader.o CLMTSMeshFileLoader.o CMY3DMeshFileLoader.o COCTLoader.o CXMeshFileLoader.o CIrrMeshFileLoader.o CSTLMeshFileLoader.o CLWOMeshFileLoader.o CPLYMeshFileLoader.o CSMFMeshFileLoader.o CMeshTextureLoader.o
IRRMESHWRITER = CColladaMeshWriter.o CIrrMeshWriter.o CSTLMeshWriter.o COBJMeshWriter.o CPLYMeshWriter.o
IRRMESHOBJ = $(IRRMESHLOADER) $(IRRMESHWRITER) \
CSkinnedMesh.o CBoneSceneNode.o CMeshSceneNode.o \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment