- Ogre Importer Beta

- Ogre Importer Documentation
- Extended the general documentation at some points

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@476 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
jonathanklein 2009-09-05 12:04:32 +00:00
parent a8ccd6fbd5
commit 8cfb2e26cf
9 changed files with 644 additions and 8 deletions

View File

@ -217,12 +217,8 @@ public:
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
* @param pImp Importer instance * @param pImp Importer instance
* @param ppFlags Post-processing steps to be executed on the data
* returned by the loaders. This value is provided to allow some
* internal optimizations.
*/ */
virtual void SetupProperties(const Importer* pImp /*, virtual void SetupProperties(const Importer* pImp);
unsigned int ppFlags*/);
protected: protected:

View File

@ -192,6 +192,11 @@ SOURCE_GROUP( Obj FILES
ObjTools.h ObjTools.h
) )
SOURCE_GROUP( Ogre FILES
OgreImporter.h
OgreImporter.cpp
)
SOURCE_GROUP( Ply FILES SOURCE_GROUP( Ply FILES
PlyLoader.cpp PlyLoader.cpp
PlyLoader.h PlyLoader.h
@ -472,6 +477,8 @@ ADD_LIBRARY( assimp SHARED
ObjFileParser.cpp ObjFileParser.cpp
ObjFileParser.h ObjFileParser.h
ObjTools.h ObjTools.h
OgreImporter.h
OgreImporter.cpp
OptimizeGraph.cpp OptimizeGraph.cpp
OptimizeGraph.h OptimizeGraph.h
OptimizeMeshes.cpp OptimizeMeshes.cpp

View File

@ -158,6 +158,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_BUILD_NO_LWS_IMPORTER #ifndef AI_BUILD_NO_LWS_IMPORTER
# include "LWSLoader.h" # include "LWSLoader.h"
#endif #endif
#ifndef AI_BUILD_NO_OGRE_IMPORTER
# include "OgreImporter.h"
#endif
// ....................................................................................... // .......................................................................................
// PostProcess-Steps // PostProcess-Steps
@ -360,6 +363,10 @@ Importer::Importer()
#if (!defined AI_BUILD_NO_LWS_IMPORTER) #if (!defined AI_BUILD_NO_LWS_IMPORTER)
pimpl->mImporter.push_back( new LWSImporter()); pimpl->mImporter.push_back( new LWSImporter());
#endif #endif
#if (!defined AI_BUILD_NO_OGRE_IMPORTER)
pimpl->mImporter.push_back( new Ogre::OgreImporter());
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Add an instance of each post processing step here in the order // Add an instance of each post processing step here in the order

View File

@ -0,0 +1,425 @@
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
#include <vector>
#include <sstream>
using namespace std;
#include "boost/format.hpp"
using namespace boost;
#include "OgreImporter.h"
#include "irrXMLWrapper.h"
namespace Assimp
{
namespace Ogre
{
bool OgreImporter::CanRead(const std::string &pFile, Assimp::IOSystem *pIOHandler, bool checkSig) const
{
if(!checkSig)//Check File Extension
{
std::string extension("mesh.xml");
int l=extension.length();
return pFile.substr(pFile.length()-l, l)==extension;
}
else//Check file Header
{
const char* tokens[] = {"<mesh>"};
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
}
void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Assimp::IOSystem *pIOHandler)
{
m_CurrentFilename=pFile;
m_CurrentIOHandler=pIOHandler;
m_CurrentScene=pScene;
//Open the File:
boost::scoped_ptr<IOStream> file(pIOHandler->Open(pFile));
if( file.get() == NULL)
throw new ImportErrorException("Failed to open file "+pFile+".");
//Read the Mesh File:
boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
XmlReader* MeshFile = irr::io::createIrrXMLReader(mIOWrapper.get());
if(!MeshFile)//parse the xml file
throw new ImportErrorException("Failed to create XML Reader for "+pFile);
DefaultLogger::get()->info("Mesh File opened");
//Read root Node:
if(!(XmlRead(MeshFile) && string(MeshFile->getNodeName())=="mesh"))
{
throw new ImportErrorException("Root Node is not <mesh>! "+pFile+" "+MeshFile->getNodeName());
}
//Go to the submeshs:
if(!(XmlRead(MeshFile) && string(MeshFile->getNodeName())=="submeshes"))
{
throw new ImportErrorException("No <submeshes> node in <mesh> node! "+pFile);
}
//-------------------Read all submeshs:-----------------------
XmlRead(MeshFile);
while(string(MeshFile->getNodeName())=="submesh")//read the index values (the faces):
{
SubMesh NewSubMesh;
NewSubMesh.MaterialName=GetAttribute<string>(MeshFile, "material");
DefaultLogger::get()->info("Loading Submehs with Material: "+NewSubMesh.MaterialName);
ReadSubMesh(NewSubMesh, MeshFile);
}
//_______________________________________________________________-
//-----------------Read the skeleton:----------------------
//Create the root node
pScene->mRootNode=new aiNode("root");
//link the mesh with the root node:
pScene->mRootNode->mMeshes=new unsigned int[1];
pScene->mRootNode->mMeshes[0]=0;
pScene->mRootNode->mNumMeshes=1;
//_________________________________________________________
}
void OgreImporter::GetExtensionList(std::string &append)
{
append+="*.mesh.xml";
}
void OgreImporter::SetupProperties(const Importer* pImp)
{
m_MaterialLibFilename=pImp->GetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "Scene.material");
}
void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader)
{
vector<Face> FaceList;
vector<aiVector3D> Positions; bool HasPositions=false;
vector<aiVector3D> Normals; bool HasNormals=false;
vector<aiVector3D> Uvs; unsigned int NumUvs=0;//nearly always 2d, but assimp has always 3d texcoords
XmlRead(Reader);
//TODO: maybe we have alsways just 1 faces and 1 geometry and always in this order. this loop will only work korrekt, wenn the order
//of faces and geometry changed, and not if we habe more than one of one
while(Reader->getNodeName()==string("faces") || string(Reader->getNodeName())=="geometry")
{
if(string(Reader->getNodeName())=="faces")//Read the face list
{
//some info logging:
unsigned int NumFaces=GetAttribute<int>(Reader, "count");
stringstream ss; ss <<"Submesh has " << NumFaces << " Faces.";
DefaultLogger::get()->info(ss.str());
while(XmlRead(Reader) && Reader->getNodeName()==string("face"))
{
Face NewFace;
NewFace.VertexIndices[0]=GetAttribute<int>(Reader, "v1");
NewFace.VertexIndices[1]=GetAttribute<int>(Reader, "v2");
NewFace.VertexIndices[2]=GetAttribute<int>(Reader, "v3");
if(Reader->getAttributeValue("v4"))//this should be supported in the future
{
throw new ImportErrorException("Submesh has quads, only traingles are supported!");
}
FaceList.push_back(NewFace);
}
}
else if(string(Reader->getNodeName())=="geometry")//Read the vertexdata
{
//some info logging:
unsigned int NumVertices=GetAttribute<int>(Reader, "vertexcount");
stringstream ss; ss<<"VertexCount: "<<NumVertices;
DefaultLogger::get()->info(ss.str());
//General Informations about vertices
XmlRead(Reader);
if(!(Reader->getNodeName()==string("vertexbuffer")))
{
throw new ImportErrorException("vertexbuffer node is not first in geometry node!");
}
HasPositions=GetAttribute<bool>(Reader, "positions");
HasNormals=GetAttribute<bool>(Reader, "normals");
NumUvs=GetAttribute<int>(Reader, "texture_coords");
if(NumUvs>1)
throw new ImportErrorException("too many texcoords (just 1 supported!)");
//read all the vertices:
XmlRead(Reader);
while(Reader->getNodeName()==string("vertex"))
{
//read all vertex attributes:
//Position
if(HasPositions)
{
XmlRead(Reader);
aiVector3D NewPos;
NewPos.x=GetAttribute<float>(Reader, "x");
NewPos.y=GetAttribute<float>(Reader, "y");
NewPos.z=GetAttribute<float>(Reader, "z");
Positions.push_back(NewPos);
}
//Normal
if(HasNormals)
{
XmlRead(Reader);
aiVector3D NewNormal;
NewNormal.x=GetAttribute<float>(Reader, "x");
NewNormal.y=GetAttribute<float>(Reader, "y");
NewNormal.z=GetAttribute<float>(Reader, "z");
Normals.push_back(NewNormal);
}
//Uv:
if(1==NumUvs)
{
XmlRead(Reader);
aiVector3D NewUv;
NewUv.x=GetAttribute<float>(Reader, "u");
NewUv.y=GetAttribute<float>(Reader, "v");
Uvs.push_back(NewUv);
}
XmlRead(Reader);
}
}
}
DefaultLogger::get()->info(str(format("Positionen: %1% Normale: %2% TexCoords: %3%") % Positions.size() % Normals.size() % Uvs.size()));
//Make all Vertexes unique: (this is required by assimp)
vector<Face> UniqueFaceList(FaceList.size());
vector<aiVector3D> UniquePositions(FaceList.size()*3);//*3 because each face consits of 3 vertexes, because we only support triangles^^
vector<aiVector3D> UniqueNormals(FaceList.size()*3);
vector<aiVector3D> UniqueUvs(FaceList.size()*3);
for(unsigned int i=0; i<FaceList.size(); ++i)
{
UniquePositions[3*i+0]=Positions[FaceList[i].VertexIndices[0]];
UniquePositions[3*i+1]=Positions[FaceList[i].VertexIndices[1]];
UniquePositions[3*i+2]=Positions[FaceList[i].VertexIndices[2]];
UniqueNormals[3*i+0]=Normals[FaceList[i].VertexIndices[0]];
UniqueNormals[3*i+1]=Normals[FaceList[i].VertexIndices[1]];
UniqueNormals[3*i+2]=Normals[FaceList[i].VertexIndices[2]];
UniqueUvs[3*i+0]=Uvs[FaceList[i].VertexIndices[0]];
UniqueUvs[3*i+1]=Uvs[FaceList[i].VertexIndices[1]];
UniqueUvs[3*i+2]=Uvs[FaceList[i].VertexIndices[2]];
UniqueFaceList[i].VertexIndices[0]=3*i+0;
UniqueFaceList[i].VertexIndices[1]=3*i+1;
UniqueFaceList[i].VertexIndices[2]=3*i+2;
}
//----------------Load the Material:-------------------------------
aiMaterial* MeshMat=LoadMaterial(theSubMesh.MaterialName);
//_________________________________________________________________
//Mesh is fully loaded, copy it into the aiScene:
if(m_CurrentScene->mNumMeshes!=0)
throw new ImportErrorException("Currently only one mesh per File is allowed!!");
//---------------------Create the aiMesh:-----------------------
aiMesh* NewAiMesh=new aiMesh();
//Positions
NewAiMesh->mVertices=new aiVector3D[UniquePositions.size()];
memcpy(NewAiMesh->mVertices, &UniquePositions[0], UniquePositions.size()*sizeof(aiVector3D));
NewAiMesh->mNumVertices=UniquePositions.size();
//Normals
NewAiMesh->mNormals=new aiVector3D[UniqueNormals.size()];
memcpy(NewAiMesh->mNormals, &UniqueNormals[0], UniqueNormals.size()*sizeof(aiVector3D));
//Uvs
NewAiMesh->mNumUVComponents[0]=2;
//NewAiMesh->mTextureCoords=new aiVector3D*[1];
NewAiMesh->mTextureCoords[0]= new aiVector3D[UniqueUvs.size()];
memcpy(NewAiMesh->mTextureCoords[0], &UniqueUvs[0], UniqueUvs.size()*sizeof(aiVector3D));
//Faces
NewAiMesh->mFaces=new aiFace[UniqueFaceList.size()];
for(unsigned int i=0; i<UniqueFaceList.size(); ++i)
{
NewAiMesh->mFaces[i].mNumIndices=3;
NewAiMesh->mFaces[i].mIndices=new unsigned int[3];
NewAiMesh->mFaces[i].mIndices[0]=UniqueFaceList[i].VertexIndices[0];
NewAiMesh->mFaces[i].mIndices[1]=UniqueFaceList[i].VertexIndices[1];
NewAiMesh->mFaces[i].mIndices[2]=UniqueFaceList[i].VertexIndices[2];
}
NewAiMesh->mNumFaces=UniqueFaceList.size();
//Set the Material:
NewAiMesh->mMaterialIndex=0;
if(m_CurrentScene->mMaterials)
throw new ImportErrorException("only 1 material supported at this time!");
m_CurrentScene->mMaterials=new aiMaterial*[1];
m_CurrentScene->mNumMaterials=1;
m_CurrentScene->mMaterials[0]=MeshMat;
//________________________________________________________________
//Attach the mesh to the scene:
m_CurrentScene->mNumMeshes=1;
m_CurrentScene->mMeshes=new aiMesh*;
m_CurrentScene->mMeshes[0]=NewAiMesh;
//stringstream ss; ss <<"Last Node: <" << Reader->getNodeName() << ">";
//throw new ImportErrorException(ss.str());
}
aiMaterial* OgreImporter::LoadMaterial(std::string MaterialName)
{
MaterialHelper *NewMaterial=new MaterialHelper();
NewMaterial->AddProperty(&aiString(MaterialName.c_str()), AI_MATKEY_NAME);
/*For bettetr understanding of the material parser, here is a material example file:
material Sarg
{
receive_shadows on
technique
{
pass
{
ambient 0.500000 0.500000 0.500000 1.000000
diffuse 0.640000 0.640000 0.640000 1.000000
specular 0.500000 0.500000 0.500000 1.000000 12.500000
emissive 0.000000 0.000000 0.000000 1.000000
texture_unit
{
texture SargTextur.tga
tex_address_mode wrap
filtering linear linear none
}
}
}
}
*/
string MaterialFileName=m_CurrentFilename.substr(0, m_CurrentFilename.find('.'))+".material";
DefaultLogger::get()->info(str(format("Trying to load %1%") % MaterialFileName));
//Read the file into memory and put it in a stringstream
stringstream ss;
{// after this block, the temporarly loaded data will be released
IOStream* MatFilePtr=m_CurrentIOHandler->Open(MaterialFileName);
if(NULL==MatFilePtr)
{
MatFilePtr=m_CurrentIOHandler->Open(m_MaterialLibFilename);
if(NULL==MatFilePtr)
{
DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opned, Material will not be loaded!");
return NewMaterial;
}
}
scoped_ptr<IOStream> MaterialFile(MatFilePtr);
vector<char> FileData(MaterialFile->FileSize());
MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1);
BaseImporter::ConvertToUTF8(FileData);
ss << &FileData[0];
}
string Line;
ss >> Line;
unsigned int Level=0;//Hierarchielevels in the material file, like { } blocks into another
while(!ss.eof())
{
if(Line=="material")
{
ss >> Line;
if(Line==MaterialName)//Load the next material
{
ss >> Line;
if(Line!="{")
throw new ImportErrorException("empty material!");
while(Line!="}")//read until the end of the material
{
//Proceed to the first technique
ss >> Line;
if(Line=="technique")
{
ss >> Line;
if(Line!="{")
throw new ImportErrorException("empty technique!");
while(Line!="}")//read until the end of the technique
{
ss >> Line;
if(Line=="pass")
{
ss >> Line;
if(Line!="{")
throw new ImportErrorException("empty pass!");
while(Line!="}")//read until the end of the pass
{
ss >> Line;
if(Line=="ambient")
{
//read the ambient light values:
}
else if(Line=="diffuse")
{
}
else if(Line=="specular")
{
}
else if(Line=="emmisive")
{
}
else if(Line=="texture_unit")
{
ss >> Line;
if(Line!="{")
throw new ImportErrorException("empty texture unit!");
while(Line!="}")//read until the end of the texture_unit
{
ss >> Line;
if(Line=="texture")
{
ss >> Line;
NewMaterial->AddProperty(&aiString(Line.c_str()), AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
}
}//end of texture unit
}
}
}
}//end of technique
}
}//end of material
}
else {} //this is the wrong material, proceed the file until we reach the next material
}
ss >> Line;
}
return NewMaterial;
}
}//namespace Ogre
}//namespace Assimp
#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER

122
code/OgreImporter.h 100644
View File

@ -0,0 +1,122 @@
#include "BaseImporter.h"
#include <vector>
#include "irrXMLWrapper.h"
#include "fast_atof.h"
namespace Assimp
{
namespace Ogre
{
typedef irr::io::IrrXMLReader XmlReader;
//Forward declarations:
struct Face;
struct SubMesh;
///The Main Ogre Importer Class
class OgreImporter : public BaseImporter
{
public:
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
virtual void GetExtensionList(std::string& append);
virtual void SetupProperties(const Importer* pImp);
private:
///Helper Functions to read parts of the XML File
/** @param Filename We need this to check for a material File with the same name.*/
void ReadSubMesh(SubMesh& theSubMesh, XmlReader* Reader);
aiMaterial* LoadMaterial(std::string MaterialName);
//Now we don't have to give theses parameters to all functions
std::string m_CurrentFilename;
std::string m_MaterialLibFilename;
IOSystem* m_CurrentIOHandler;
aiScene *m_CurrentScene;
};
//------------Helper Funktion to Get a Attribute Save---------------
template<typename t> inline t GetAttribute(XmlReader* Reader, std::string Name)
{
throw std::exception("unimplemented Funtcion used!");
return t();
}
template<> inline int GetAttribute<int>(XmlReader* Reader, std::string Name)
{
const char* Value=Reader->getAttributeValue(Name.c_str());
if(Value)
return atoi(Value);
else
throw ImportErrorException(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
}
template<> inline float GetAttribute<float>(XmlReader* Reader, std::string Name)
{
const char* Value=Reader->getAttributeValue(Name.c_str());
if(Value)
return fast_atof(Value);
else
throw ImportErrorException(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
}
template<> inline std::string GetAttribute<std::string>(XmlReader* Reader, std::string Name)
{
const char* Value=Reader->getAttributeValue(Name.c_str());
if(Value)
return std::string(Value);
else
throw new ImportErrorException(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
}
template<> inline bool GetAttribute<bool>(XmlReader* Reader, std::string Name)
{
const char* Value=Reader->getAttributeValue(Name.c_str());
if(Value)
{
if(Value==std::string("true"))
return true;
else if(Value==std::string("false"))
return false;
else
throw new ImportErrorException(std::string("Bool value has invalid value: "+Name+" / "+Value+" / "+Reader->getNodeName()));
}
else
throw new ImportErrorException(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str());
}
//__________________________________________________________________
inline bool XmlRead(XmlReader* Reader)
{
do
{
if(!Reader->read())
return false;
}
while(Reader->getNodeType()!=irr::io::EXN_ELEMENT);
return true;
}
///For the moment just triangles, no other polygon types!
struct Face
{
unsigned int VertexIndices[3];
};
/// Helper Class to describe a complete SubMesh
struct SubMesh
{
std::string Name;
std::string MaterialName;
std::vector<Face> Faces;
};
}//namespace Ogre
}//namespace Assimp

View File

@ -49,8 +49,11 @@ that it has not yet been implemented, and some formats have not completely been
<b>Object File Format </b> ( <i>*.off</i> ). <br> <b>Object File Format </b> ( <i>*.off</i> ). <br>
<b>Terragen Terrain </b> ( <i>*.ter</i> ) <br> <b>Terragen Terrain </b> ( <i>*.ter</i> ) <br>
<b>3D GameStudio Model </b> ( <i>*.mdl</i> ) <br> <b>3D GameStudio Model </b> ( <i>*.mdl</i> ) <br>
<b>3D GameStudio Terrain</b> ( <i>*.hmp</i> )<br><br><br> <b>3D GameStudio Terrain</b> ( <i>*.hmp</i> )<br>
<b>Ogre</b> (<i>.mesh.xml, .skeleton.xml, .material</i>)<br><br>
</tt> </tt>
See the @link importer_notes Importer Notes Page @endlink for informations, what a specific importer can do and what not.<br>
<sup>3</sup>: These formats support animations, but ASSIMP doesn't yet support them (or they're buggy) <sup>3</sup>: These formats support animations, but ASSIMP doesn't yet support them (or they're buggy)
<br> <br>
<hr> <hr>
@ -778,7 +781,8 @@ OK, that sounds too easy :-). The whole procedure for a new loader merely looks
<ul> <ul>
<li>Create a header (<tt><i>FormatName</i>Importer.h</tt>) and a unit (<tt><i>FormatName</i>Importer.cpp</tt>) in the <tt>&lt;root&gt;/code/</tt> directory</li> <li>Create a header (<tt><i>FormatName</i>Importer.h</tt>) and a unit (<tt><i>FormatName</i>Importer.cpp</tt>) in the <tt>&lt;root&gt;/code/</tt> directory</li>
<li>Add them to the following workspaces: vc8, vc9, CMAKE</li> <li>Add them to the following workspaces: vc8 and vc9 (the files are in the workspaces directory), CMAKE (code/CMakeLists.txt, create a new
source group for your importer and put them also to ADD_LIBRARY( assimp SHARED))</li>
<li>Include <i>AssimpPCH.h</i> - this is the PCH file, and it includes already most Assimp-internal stuff. </li> <li>Include <i>AssimpPCH.h</i> - this is the PCH file, and it includes already most Assimp-internal stuff. </li>
<li>Open Importer.cpp and include your header just below the <i>(include_new_importers_here)</i> line, <li>Open Importer.cpp and include your header just below the <i>(include_new_importers_here)</i> line,
guarded by a #define guarded by a #define
@ -789,7 +793,7 @@ guarded by a #define
@endcode @endcode
Wrap the same guard around your .cpp!</li> Wrap the same guard around your .cpp!</li>
<li>No advance to the <i>(register_new_importers_here)</i> line in the Importer.cpp and register your importer there - just like all the others do.</li> <li>Now advance to the <i>(register_new_importers_here)</i> line in the Importer.cpp and register your importer there - just like all the others do.</li>
<li>Setup a suitable test environment (i.e. use AssimpView or your own application), make sure to enable <li>Setup a suitable test environment (i.e. use AssimpView or your own application), make sure to enable
the #aiProcess_ValidateDataStructure flag and enable verbose logging. That is, simply call before you import anything: the #aiProcess_ValidateDataStructure flag and enable verbose logging. That is, simply call before you import anything:
@code @code
@ -814,6 +818,14 @@ Done! Please, share your loader that everyone can profit from it!
</li> </li>
</ul> </ul>
@section properties Properties
You can use properties to chance the behavior of you importer. In order to do so, you have to overide BaseImporter::SetupProperties, and specify
you custom properties in aiConfig.h. Just have a look to the other AI_CONFIG_IMPORT_* defines and you will understand, how it works.
The properties can be set with Importer::SetProperty***() and can be accessed in your SetupProperties function with Importer::GetProperty***(). You can
store the properties as a member variable of your importer, they are thread safe.
@section tnote Notes for text importers @section tnote Notes for text importers
<ul> <ul>
@ -865,6 +877,12 @@ MaterialHelper* mat = new MaterialHelper();
const float spec = 16.f; const float spec = 16.f;
mat->AddProperty(&spec, 1, AI_MATKEY_SHININESS); mat->AddProperty(&spec, 1, AI_MATKEY_SHININESS);
//set the name of the material:
NewMaterial->AddProperty(&aiString(MaterialName.c_str()), AI_MATKEY_NAME);//MaterialName is a std::string
//set the first diffuse texture
NewMaterial->AddProperty(&aiString(Texturename.c_str()), AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));//again, Texturename is a std::string
@endcode @endcode
@section boost Boost @section boost Boost
@ -1390,3 +1408,34 @@ Build: alles von CustomBuild + DirectX + MFC?
/**
@page importer_notes Importer Notes
@section ogre Ogre
Ogre importer is WIP and optimized for the Blender Ogre exporter!
XML Format: There is a binary and a XML mesh Format from Ogre. This loader can only
Handle xml files, but don't panic, there is a command line converter, which you can use
to create XML files from Binary Files. Just look on the Ogre page for it.
Currently you can only load meshes. So you will need to import the *.mesh.xml file, the loader will
try to find the appendant material and skeleton file.
The skeleton file must have the same name as the mesh file, e.g. fish.mesh.xml and fish.skeleton.xml.
The material file can have the same name as the mesh file, or you can use
Importer::Importer::SetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "materiafile.material") to specify
the name of the material file. This is especially usefull if multiply materials a stored in a single file.
The importer will first try to load the material with the same name as the mesh and only if this can't be open try
to load the alternate material file. The default material filename is "Scene.material".
What will be loaded?
Mesh: Faces, Positions, Normals and one Uv pair. The Materialname will be used to load the material
Material: The right material in the file will be searched, the importer should work with materials who
have 1 technique and 1 pass in this technique. From there, the texturename will be loaded. Also, the
materialname will be set.
Skeleton: Nothing, yet.
*/

View File

@ -552,6 +552,12 @@ enum aiComponent
#define AI_CONFIG_IMPORT_IRR_ANIM_FPS \ #define AI_CONFIG_IMPORT_IRR_ANIM_FPS \
"IMPORT_IRR_ANIM_FPS" "IMPORT_IRR_ANIM_FPS"
/// Ogre Importer will try to load this Materialfile
/**
Ogre Mehs contain only the MaterialName, not the MaterialFile. If there is no material file
with the same name as the material, Ogre Importer will try to load this file and search the material in it.
*/
#define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE "IMPORT_OGRE_MATERIAL_FILE"
#endif // !! AI_CONFIG_H_INC #endif // !! AI_CONFIG_H_INC

View File

@ -1935,6 +1935,18 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="ogre"
>
<File
RelativePath="..\..\code\OgreImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\OgreImporter.h"
>
</File>
</Filter>
<Filter <Filter
Name="collada" Name="collada"
> >

View File

@ -1943,6 +1943,18 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="ogre"
>
<File
RelativePath="..\..\code\OgreImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\OgreImporter.h"
>
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="process" Name="process"