(C++) Load TREEmagik 1.0 Free Trees

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

(C++) Load TREEmagik 1.0 Free Trees

Post by bitplane »

First download the old free version of treemagk, here:
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;
  
}
oh yeah, make sure "export media" and "B3D export" are ticked when you save your tree
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
sdi2000
Posts: 130
Joined: Thu Aug 25, 2005 12:19 pm
Location: Berlin, DE
Contact:

Post by sdi2000 »

with the xml reader... :shock:
realy cool :D
Guest

Post by Guest »

thanks man
ur knowledge of XML is gr8
keep up the good work
Xaron
Posts: 310
Joined: Sun Oct 16, 2005 7:39 am
Location: Germany
Contact:

Post by Xaron »

Thanks bitplane, this is great! :)

Regards - Xaron
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

Anonymous wrote:ur knowledge of XML is gr8
haha i hope thats sarcasm not ignorace :lol:
if it parsed the xml properly i'd have called it an "a3d loader" :P
i think i'm going to use klasker's trees instead, freemagik trees arern't so good.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

bitplane wrote:i think i'm going to use klasker's trees instead, freemagik trees arern't so good.
what are klasker's trees?
Image
jam
Posts: 409
Joined: Fri Nov 04, 2005 3:52 am

Post by jam »

paooolino
Posts: 50
Joined: Wed Dec 21, 2005 12:17 pm
Location: Brescia, Italy
Contact:

Post by paooolino »

Hello,
I'm using bitplane's loader,

I'm wondering if anyone modified that function so it can load materials. My trees are loading well, but they lacks trunk texture. My trunks are all black.

thanks guys :wink:
Post Reply