Sign in to follow this  
Dragon_Strike

collada/xml structure loading [source]

Recommended Posts

well i just finished my collada/xml loader interface... it will create a close C++ copy of the structure in the file with the same names all u have to do is to define a nested structure for each element in the file and what kind of attributes/elements it has... and the rest will be done automaticly... hope it can be helpful for someone... it uses tinyxml so you have to download that to run it... an example loader... you have to be careful that the names of the variables correspond EXACTLY to those they represent in the file
#ifndef COLLADA_GEOMETRIES
#define COLLADA_GEOMETRIES

#include "ColladaTools.h"

namespace nbase{
namespace graphics{
namespace collada{

struct Input
{	
	explicit Input(TiXmlElement* node) 
	{
		LOAD_ITEM(node, semantic);
		LOAD_ITEM(node, source);		
	}

	std::string semantic;
	std::string source;
};

struct Vertices
{
	explicit Vertices(TiXmlElement* node) 
	{
		LOAD_ITEM(node, id);	
		LOAD_ITEM(node, input);		
	}

	std::string id;
	element<Input> input;
};

struct Triangles
{
	explicit Triangles(TiXmlElement* node) 
	{
		LOAD_ITEM(node, material);
		LOAD_ITEM(node, count);
		LOAD_ITEM(node, input);
		LOAD_ITEM(node, p);		
	}

	int count;
	std::string material;
	element<Input> input;
	element_text<unsigned short> p;
};

struct Source
{
	explicit Source(TiXmlElement* node)
	{
		LOAD_ITEM(node, id);
		LOAD_ITEM(node, name);
		LOAD_ITEM(node, float_array);		
	}

	std::string id;
	std::string name;
	element_text<float> float_array;
};

struct Mesh
{		
	explicit Mesh(TiXmlElement* node) 
	{
		LOAD_ITEM(node, source);
		LOAD_ITEM(node, vertices);
		LOAD_ITEM(node, triangles);		
	}

	element<Source> source;
	element<Vertices> vertices;
	element<Triangles> triangles;
};

struct Geometry
{
	explicit Geometry(TiXmlElement* node) 
	{		
		LOAD_ITEM(node, id);
		LOAD_ITEM(node, name);
		LOAD_ITEM(node, mesh);		
	}

	std::string id;
	std::string name;
	element<Mesh> mesh;
};

struct Library_Geometries
{
	explicit Library_Geometries(TiXmlElement* node) 
	{
		LOAD_ITEM(node, geometry);		
	}

	element<Geometry> geometry;
};


// and to start the loading

void Load(std::string filename)
{
        Library_Geometries library_geometries;

	TiXmlDocument XMLdoc(filename.data());

	if (!XMLdoc.LoadFile()) 
		assert("Failed to load xml file");

	TiXmlElement* node = XMLdoc.FirstChildElement("COLLADA");

	assert(node && "failed to load root");

	LOAD_ITEM(node, library_geometries);
}

}
}
}

#endif




for this file
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
   <library_geometries>
        <geometry id="box-lib" name="box">
            <mesh>
                <source id="box-lib-positions" name="position">
                    <float_array id="box-lib-positions-array" count="24">-50 50 50 50 50 50 -50 -50 50 50 -50 50 -50 50 -50 50 50 -50 -50 -50 -50 50 -50 -50</float_array>
                    <technique_common>
                        <accessor count="8" offset="0" source="#box-lib-positions-array" stride="3">
                            <param name="X" type="float"></param>
                            <param name="Y" type="float"></param>
                            <param name="Z" type="float"></param>
                        </accessor>
                    </technique_common>
                </source>
                <source id="box-lib-normals" name="normal">
                    <float_array id="box-lib-normals-array" count="72">0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1</float_array>
                    <technique_common>
                        <accessor count="24" offset="0" source="#box-lib-normals-array" stride="3">
                            <param name="X" type="float"></param>
                            <param name="Y" type="float"></param>
                            <param name="Z" type="float"></param>
                        </accessor>
                    </technique_common>
                </source>
                <vertices id="box-lib-vertices">
                    <input semantic="POSITION" source="#box-lib-positions"/>
                </vertices>
                <triangles count="12" material="BlueSG">
                    <input offset="0" semantic="VERTEX" source="#box-lib-vertices"/>
                    <input offset="1" semantic="NORMAL" source="#box-lib-normals"/>
                    <p>0 0 2 1 3 2 0 0 3 2 1 3 0 4 1 5 5 6 0 4 5 6 4 7 6 8 7 9 3 10 6 8 3 10 2 11 0 12 4 13 6 14 0 12 6 14 2 15 3 16 7 17 5 18 3 16 5 18 1 19 5 20 7 21 6 22 5 20 6 22 4 23</p>
                </triangles>
            </mesh>
        </geometry>
    </library_geometries>
</COLLADA>


there are four types... one where u just write the type for example int,std:.string etc... those are counted as attributes... element<> is a child type element_text<> will load the text of a child text<> will load the text as numbers of the currect element and here is where the work is done... nothing advanced..
#ifndef COLLADA_TOOLS
#define COLLADA_TOOLS

#include <XML/tinyXML.h>
#include <vector>

namespace nbase{
namespace graphics{
namespace collada{

template <class T> struct text : public std::vector<T> {};
template <class T> struct element : public std::vector<T> {};
template <class T> struct element_text : public std::vector<T> {};

template<typename T>
void GetValueArray(const std::string& data, std::vector<T>& dest)
{
	std::string curdata = "";
	for (int curindex = 0; curindex < data.size(); curindex++)
	{
		if (data[curindex] == ' ')
		{			
			dest.push_back((T)atof(curdata.c_str()));
			curdata = "";
		}
		curdata += data[curindex];
	}

	dest.push_back((T)atof(curdata.c_str()));
}

template<typename T>
void LoadItem(TiXmlElement* node, std::string name, text<T>& dest)
{
	if (node)
	{
		GetValueArray<T>(node->GetText(), dest);
	}
}

template<typename T>
void LoadItem(TiXmlElement* node, std::string name, element_text<T>& dest)
{
	if (node)
	{
		node = node->FirstChildElement(name.c_str());
		if (node)
			GetValueArray<T>(node->GetText(), dest);
	}
}

template <class T>
void LoadItem(TiXmlElement* node, std::string name, element<T>& dest)
{
	for (TiXmlElement* child = node->FirstChildElement(); child != NULL; child = child->NextSiblingElement())
	{
		if (child->ValueTStr() == name.c_str())
		{
			dest.push_back(T(child));
		}
	}	
}

inline void LoadItem(TiXmlElement* node, std::string name, int& value)
{
	if (node)
		node->QueryIntAttribute(name.c_str(), &value);		
}
inline void LoadItem(TiXmlElement* node, std::string name, float& value)
{
	if (node)
		node->QueryFloatAttribute(name.c_str(), &value);		
}
inline void LoadItem(TiXmlElement* node, std::string name, double& value)
{
	if (node)
		node->QueryDoubleAttribute(name.c_str(), &value);		
}
inline void LoadItem(TiXmlElement* node, std::string name, std::string& value)
{
	if (node)
		value = node->Attribute(name.c_str());		
}

#define STRINGIZE(text) #text
#define LOAD_ITEM(node, name) LoadItem(node, STRINGIZE(name), name);

}
}
}

#endif



Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this