http://gdlib.net/index.php?name=Downloa ... ails&id=29
DirectX export doesnt work with irrlicht. Apparently you can run the exported X files through MilkShape (here) but i made an A3D tree loader using the xml reader anyway! enjoy
Code: Select all
/*
this is an ugly hack to load treemagik 1.0 exported A3D trees:
assumes leaf textures are used more than once
relies on the order of the tags in the file
ignores materials
texture path is relative to the exe
and there is no error checking
if optimize is true, anything with the same texture will share a
mesh buffer
*/
#include <irrlicht.h>
#include <string.h>
//! loads a mesh from a a3d file (made by TreeMagik 1.0b free edition)
scene::IMesh* createA3DTree(c8* file, IrrlichtDevice *device, bool optimize=true)
{
// create the mesh.
// this is a create function, so we dont drop() it
scene::SMesh *Mesh = new scene::SMesh();
// open the xml reader and the file
io::IXMLReaderUTF8* xml = device->getFileSystem()->createXMLReaderUTF8(file);
// merge materials of same texture into one meshbuffer
core::array<video::ITexture*> Textures;
core::array<s32> MatMap;
scene::SMeshBuffer *cbuf=0;
s16 firstVertex=0;
bool toggle = false; // node/mesh toggle. true if in a mesh
// offsets for branches
core::vector3df pos, rot, scale;
while(xml && xml->read())
{
if (xml->getNodeType() == io::EXN_ELEMENT) // we ignore text
{
if (core::string<c8>("TEXTURE") == xml->getNodeName())
{
/*
new texture. we'll use minimal textures and buffers.
*/
// id number of this texture
s32 idno = xml->getAttributeValueAsInt("id");
video::ITexture *tex = device->getVideoDriver()->getTexture(xml->getAttributeValue("name"));
// is this texture already loaded?
u32 f = Textures.linear_search(tex);
if ( f == -1 || !optimize)
{
// not found in texture list, we add it.
MatMap.push_back(Textures.size());
Textures.push_back(tex);
// then we make a mesh buffer
cbuf = new scene::SMeshBuffer();
Mesh->addMeshBuffer(cbuf);
cbuf->Material.Textures[0] = tex;
cbuf->Material.AmbientColor = video::SColor(255,255,255,255);
cbuf->Material.DiffuseColor = video::SColor(255,255,255,255);
cbuf->Material.EmissiveColor= video::SColor(160,160,160,160);
cbuf->Material.MaterialType = video::EMT_SOLID;
cbuf->drop();
}
else
{
// was found in the texture list, join mesh buffers
MatMap.push_back(f);
}
if (f != -1)
{
// this can't be a stump. it must be leaves
cbuf->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
cbuf->Material.MaterialTypeParam = 0.01f;
device->getVideoDriver()->makeColorKeyTexture( tex,core::position2d<s32>(0,0) );
// same goes for the node we found it at
scene::SMeshBuffer* b = (scene::SMeshBuffer*)Mesh->getMeshBuffer(f);
b->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
b->Material.MaterialTypeParam = 0.1f;
}
}
if (core::string<c8>("NODE") == xml->getNodeName())
{
toggle = false;
}
if (core::string<c8>("POS") == xml->getNodeName() && toggle == false)
{
pos.X = xml->getAttributeValueAsFloat("x");
pos.Y = xml->getAttributeValueAsFloat("y");
pos.Z = xml->getAttributeValueAsFloat("z");
}
if (core::string<c8>("SCALE") == xml->getNodeName())
{
scale.X = xml->getAttributeValueAsFloat("x");
scale.Y = xml->getAttributeValueAsFloat("y");
scale.Z = xml->getAttributeValueAsFloat("z");
}
if (core::string<c8>("ROT") == xml->getNodeName())
{
rot.X = xml->getAttributeValueAsFloat("x");
rot.Y = xml->getAttributeValueAsFloat("y");
rot.Z = xml->getAttributeValueAsFloat("z");
}
if (core::string<c8>("MESH") == xml->getNodeName())
{
s32 currentBuffer = MatMap[xml->getAttributeValueAsInt("brush")];
cbuf = (scene::SMeshBuffer*)Mesh->getMeshBuffer(currentBuffer);
firstVertex = cbuf->getVertexCount();
toggle = true;
}
if (core::string<c8>("VERTEX") == xml->getNodeName())
{
cbuf->Vertices.set_used( 1 + cbuf->Vertices.size() );
}
if (core::string<c8>("POS") == xml->getNodeName() && toggle == true)
{
// set the position of this vertex
core::vector3df tmpvect;
tmpvect.X = xml->getAttributeValueAsFloat("x");
tmpvect.Y = xml->getAttributeValueAsFloat("y");
tmpvect.Z = xml->getAttributeValueAsFloat("z");
// rotate it
core::matrix4 m;
m.makeIdentity();
m.setRotationDegrees(rot);
m.rotateVect(tmpvect);
// scale it
tmpvect *= scale;
// position it
tmpvect += pos;
// set vertex data
s32 i = cbuf->Vertices.size()-1;
cbuf->Vertices[i].Pos = tmpvect;
cbuf->BoundingBox.addInternalPoint(tmpvect);
}
else if (core::string<c8>("NORMAL") == xml->getNodeName())
{
// vertex normal
core::vector3df tmpvect;
tmpvect.X = xml->getAttributeValueAsFloat("x");
tmpvect.Y = xml->getAttributeValueAsFloat("y");
tmpvect.Z = xml->getAttributeValueAsFloat("z");
// rotate it
core::matrix4 m;
m.makeIdentity();
m.setRotationDegrees(-rot);
m.rotateVect(tmpvect);
// set vertex normal
s32 i = cbuf->Vertices.size()-1;
cbuf->Vertices[i].Normal = tmpvect;
}
else if (core::string<c8>("RGBS") == xml->getNodeName())
{
// vertex colours
core::vector3df tmpvect;
s32 r = (s32)xml->getAttributeValueAsFloat("red");
s32 g = (s32)xml->getAttributeValueAsFloat("green");
s32 b = (s32)xml->getAttributeValueAsFloat("blue");
s32 a = (s32) (xml->getAttributeValueAsFloat("alpha") * 255.0f);
// set vertex colours
s32 i = cbuf->Vertices.size()-1;
cbuf->Vertices[i].Color = video::SColor(a,r,g,b);
}
else if (core::string<c8>("UVW") == xml->getNodeName())
{
// set the vertex uv (ignore w)
s32 i = cbuf->Vertices.size()-1;
cbuf->Vertices[i].TCoords.X = xml->getAttributeValueAsFloat("u");
cbuf->Vertices[i].TCoords.Y = xml->getAttributeValueAsFloat("v");
}
else if (core::string<c8>("TRI") == xml->getNodeName())
{
// increase index list by 3
s16 i = cbuf->Indices.size();
cbuf->Indices.set_used(i+3);
cbuf->Indices[i+0] = xml->getAttributeValueAsInt("v0") + firstVertex;
cbuf->Indices[i+1] = xml->getAttributeValueAsInt("v1") + firstVertex;
cbuf->Indices[i+2] = xml->getAttributeValueAsInt("v2") + firstVertex;
}
}
}
if (xml)
xml->drop(); // don't forget to delete the xml reader
Mesh->recalculateBoundingBox();
return (scene::IMesh*)Mesh;
}
