Fixed obj bumpmap and clamp support.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1255 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2008-02-25 01:32:36 +00:00
parent 54b918f770
commit 913ef64b5e
3 changed files with 80 additions and 38 deletions

View File

@ -6,6 +6,8 @@
#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
#include "COBJMeshFileLoader.h"
#include "IMeshManipulator.h"
#include "IVideoDriver.h"
#include "SMesh.h"
#include "SMeshBuffer.h"
#include "SAnimatedMesh.h"
@ -20,30 +22,22 @@ namespace scene
{
//! Constructor
COBJMeshFileLoader::COBJMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver)
: FileSystem(fs), Driver(driver)
COBJMeshFileLoader::COBJMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs)
: SceneManager(smgr), FileSystem(fs)
{
if (FileSystem)
FileSystem->grab();
if (Driver)
Driver->grab();
}
//! destructor
COBJMeshFileLoader::~COBJMeshFileLoader()
{
if (FileSystem)
FileSystem->drop();
if (Driver)
Driver->drop();
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
bool COBJMeshFileLoader::isALoadableFileExtension(const c8* filename) const
@ -258,6 +252,14 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
if ( Materials[m]->Meshbuffer->getIndexCount() > 0 )
{
Materials[m]->Meshbuffer->recalculateBoundingBox();
if (Materials[m]->Meshbuffer->Material.MaterialType == video::EMT_PARALLAX_MAP_SOLID)
{
SMesh tmp;
tmp.addMeshBuffer(Materials[m]->Meshbuffer);
IMesh* tangentMesh = SceneManager->getMeshManipulator()->createMeshWithTangents(&tmp);
mesh->addMeshBuffer(tangentMesh->getMeshBuffer(0));
}
else
mesh->addMeshBuffer( Materials[m]->Meshbuffer );
}
}
@ -335,8 +337,12 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
currMaterial->Illumination = (c8)atol(illumStr);
}
break;
case 'N': // Ns - shininess
case 'N':
if ( currMaterial )
{
switch(bufPtr[1])
{
case 's': // Ns - shininess
{
const u32 COLOR_BUFFER_LENGTH = 16;
c8 nsStr[COLOR_BUFFER_LENGTH];
@ -349,6 +355,15 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
currMaterial->Meshbuffer->Material.Shininess = shininessValue;
}
break;
case 'i': // Ni - refraction index
{
c8 tmpbuf[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(tmpbuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
}
break;
}
}
break;
case 'K':
if ( currMaterial )
{
@ -380,38 +395,58 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
} // end switch(bufPtr[1])
} // end case 'K': if ( 0 != currMaterial )...
break;
case 'b': // bump
case 'm': // texture maps
if (currMaterial)
{
u8 type=0; // map_Kd - diffuse texture map
if (!strncmp(bufPtr,"map_bump",8))
type=1;
u8 type=0; // map_Kd - diffuse color texture map
// map_Ks - specular color texture map
// map_Ka - ambient color texture map
if ((!strncmp(bufPtr,"map_bump",8)) || (!strncmp(bufPtr,"bump",4)))
type=1; // normal map
else if (!strncmp(bufPtr,"map_d",5))
type=2;
type=2; // opactity map
else if (!strncmp(bufPtr,"map_refl",8))
type=3;
type=3; // reflection map
// extract new material's name
c8 textureNameBuf[WORD_BUFFER_LENGTH];
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
core::stringc texname(textureNameBuf);
texname.replace('\\', '/');
f32 bumpiness = 1.0f;
bool clamp = false;
// handle options
while (textureNameBuf[0]=='-')
{
if (!strncmp(bufPtr,"-bm",3))
{
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
bumpiness = core::fast_atof(textureNameBuf);
}
else
if (!strncmp(bufPtr,"-blendu",7))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
else
if (!strncmp(bufPtr,"-blendv",7))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
else
if (!strncmp(bufPtr,"-cc",3))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
else
if (!strncmp(bufPtr,"-clamp",6))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
bufPtr = readBool(bufPtr, clamp, bufEnd);
else
if (!strncmp(bufPtr,"-texres",7))
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
else
if (!strncmp(bufPtr,"-mm",3))
{
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
}
if (!strncmp(bufPtr,"-o",2))
else
if (!strncmp(bufPtr,"-o",2)) // texture coord translation
{
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
// next parameters are optional, so skip rest of loop if no number is found
@ -422,7 +457,8 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
if (!core::isdigit(textureNameBuf[0]))
continue;
}
if (!strncmp(bufPtr,"-s",2))
else
if (!strncmp(bufPtr,"-s",2)) // texture coord scale
{
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
// next parameters are optional, so skip rest of loop if no number is found
@ -433,6 +469,7 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
if (!core::isdigit(textureNameBuf[0]))
continue;
}
else
if (!strncmp(bufPtr,"-t",2))
{
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
@ -452,22 +489,22 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, core::stringc relPath)
currMaterial->Meshbuffer->Material.MaterialTypeParam=core::fast_atof(textureNameBuf);
bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd);
}
if (clamp)
currMaterial->Meshbuffer->Material.setFlag(video::EMF_TEXTURE_WRAP, video::ETC_CLAMP);
video::ITexture * texture = 0;
core::stringc texname(textureNameBuf);
texname.replace('\\', '/');
if (FileSystem->existFile(texname.c_str()))
texture = Driver->getTexture(texname.c_str());
texture = SceneManager->getVideoDriver()->getTexture(texname.c_str());
else
// try to read in the relative path, the .obj is loaded from
texture = Driver->getTexture( (relPath + texname).c_str() );
texture = SceneManager->getVideoDriver()->getTexture( (relPath + texname).c_str() );
if ( texture )
{
if (type==0)
currMaterial->Meshbuffer->Material.setTexture(0, texture);
else if (type==1)
{
Driver->makeNormalMapTexture(texture);
SceneManager->getVideoDriver()->makeNormalMapTexture(texture, bumpiness);
currMaterial->Meshbuffer->Material.setTexture(1, texture);
currMaterial->Meshbuffer->Material.MaterialType=video::EMT_PARALLAX_MAP_SOLID;
}

View File

@ -7,7 +7,7 @@
#include "IMeshLoader.h"
#include "IFileSystem.h"
#include "IVideoDriver.h"
#include "ISceneManager.h"
#include "irrString.h"
#include "SMeshBuffer.h"
@ -22,7 +22,7 @@ class COBJMeshFileLoader : public IMeshLoader
public:
//! Constructor
COBJMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver);
COBJMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs);
//! destructor
virtual ~COBJMeshFileLoader();
@ -41,7 +41,8 @@ private:
struct SObjMtl
{
SObjMtl() : Meshbuffer(0), Illumination(0) {
SObjMtl() : Meshbuffer(0), Bumpiness (1.0f), Illumination(0)
{
Meshbuffer = new SMeshBuffer();
Meshbuffer->Material.Shininess = 0.0f;
Meshbuffer->Material.AmbientColor = video::SColorf(0.2f, 0.2f, 0.2f, 1.0f).toSColor();
@ -49,10 +50,14 @@ private:
Meshbuffer->Material.SpecularColor = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f).toSColor();
}
SObjMtl(SObjMtl& o) : Meshbuffer(o.Meshbuffer), Name(o.Name), Illumination(o.Illumination) { o.Meshbuffer->grab(); }
SObjMtl(SObjMtl& o)
: Meshbuffer(o.Meshbuffer), Name(o.Name),
Bumpiness(o.Bumpiness), Illumination(o.Illumination)
{ o.Meshbuffer->grab(); }
scene::SMeshBuffer *Meshbuffer;
core::stringc Name;
f32 Bumpiness;
c8 Illumination;
};
@ -90,8 +95,8 @@ private:
void cleanUp();
scene::ISceneManager* SceneManager;
io::IFileSystem* FileSystem;
video::IVideoDriver* Driver;
core::array<SObjMtl*> Materials;
};

View File

@ -231,7 +231,7 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
MeshLoaderList.push_back(new COgreMeshFileLoader(MeshManipulator, FileSystem, Driver));
#endif
#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_
MeshLoaderList.push_back(new COBJMeshFileLoader(FileSystem, Driver));
MeshLoaderList.push_back(new COBJMeshFileLoader(this, FileSystem));
#endif
#ifdef _IRR_COMPILE_WITH_MD3_LOADER_
MeshLoaderList.push_back(new CMD3MeshFileLoader(FileSystem, Driver));