Program that converts geometric and animation 3D scene data, from a COLLADA "*.dae" file to a binary file, with a custom format.
#include "./funcs.hpp"
int deal_with_seen(mesh_geometry& targetMesh, vertex* seenVert, unsigned int* checkIndices, const unsigned int indicesCount, int material_id)
{
//has already been seen
bool same= true;
for(uint32 si=1; si< indicesCount; si++){
if(seenVert->indices[si] != checkIndices[si]) { same= false; break; }
}
if(same){
targetMesh.indices.push_back(seenVert->indices[0]);
return seenVert->indices[0];
}
else{ //found twin (same vertex with different material attributes)
if(seenVert->twin_index != -1){
return deal_with_seen(targetMesh, &targetMesh.vertices[seenVert->twin_index], checkIndices, indicesCount, material_id);
}
else {
targetMesh.vertices.push_back(vertex());
unsigned int ps_= targetMesh.vertices.size()-1;
vertex& twv= targetMesh.vertices[ps_];
//assign new vertex properties
twv.material_id= material_id;
twv.indices.resize(indicesCount);
for(uint32 si= 0; si< indicesCount; si++) twv.indices[si]= checkIndices[si];
twv.seen= true;
twv.twin_index= -1;
seenVert->twin_index= ps_;
targetMesh.indices.push_back(ps_);
return ps_;
}
}
};
void construct_mesh_geometries(std::vector<mesh_geometry>& meshes)
{
for(uint32 mi= 0; mi< meshes.size(); mi++)
{
construct_mesh_geometry(meshes[mi]);
}
}
void construct_mesh_geometry(mesh_geometry& mesh)
{
raw_meshdata& rawMeshData= mesh.raw;
//material group vertices to geom mesh vertices
for(uint32 mgi= 0; mgi< rawMeshData.prim_groups.size(); mgi++)
{
raw_primitives_group& primGroup= rawMeshData.prim_groups[mgi];
unsigned int numSources= primGroup.inputs_count;
//TODO: Remove dd stuff, if possible!
num1D_data& dd= rawMeshData.sources[0];
int unitSize= (dd.gltype== GL_FLOAT)? sizeof(float): (dd.gltype== GL_INT)? sizeof(int): 1;
//push material group vertices
for(uint32 j= 0; j< (dd.size/unitSize)/dd.stride; j++){
mesh.vertices.push_back(vertex());
vertex& c= mesh.vertices.back();
//init vertex indices
c.indices.resize(numSources);
for(uint32 si= 0; si< numSources; si++){
c.indices[si]= 0;
}
c.material_id = primGroup.material_id;
c.indices[dd.semantic]= j;
c.seen= false;
c.twin_index= -1;
}
}
//material group indices to geom mesh indices
for(uint32 mgi= 0; mgi< rawMeshData.prim_groups.size(); mgi++)
{
raw_primitives_group& primGroup= rawMeshData.prim_groups[mgi];
unsigned int numSources= primGroup.inputs_count;
//scan through the indices and fill in the details
unsigned int extrIndices[numSources];
for(uint32 y= 0; y< primGroup.indices_count; y++){
for(uint32 si= 0; si< numSources; si++)
{
extrIndices[si]= primGroup.indices[y*primGroup.inputs_count+si];
}
int posi= extrIndices[0];//posi;
int ps= posi;
if(mesh.vertices[posi].seen == false)
{
mesh.indices.push_back(posi);
ps= posi;
//set ref indices
for(uint32 si= 0; si< numSources; si++) mesh.vertices[posi].indices[si]= extrIndices[si];
//init vertex properties
mesh.vertices[posi].seen= true;
mesh.vertices[posi].material_id= primGroup.material_id;
mesh.vertices[posi].twin_index= -1;
}
else {
ps= deal_with_seen(mesh, &mesh.vertices[posi], extrIndices, numSources, primGroup.material_id);
}
}
//extract triangles
for(uint32 y= 0; y< primGroup.indices_count; y+=3){
int posit[3];
int k= y;
for(uint32 m= 0; m< 3; m++)
{
for(uint32 si= 0; si< numSources; si++)
extrIndices[si]= primGroup.indices[k*primGroup.inputs_count+si];
posit[m]= extrIndices[0];
k++;
}
mesh.triangles.push_back(triangle(posit[0], posit[1], posit[2]));
}
}
//extract edges
std::map<std::pair<int,int>,int> edgesLookupMap;
for(uint32 ti= 0; ti< mesh.triangles.size(); ti++){
triangle& tl= mesh.triangles[ti];
for(uint32 pi=0; pi< 3; pi++)
{
int a= tl.posit[pi];
int b= tl.posit[pi+1>2 ? 0: pi+1];
int swap=-1;
if(a>b){ swap= a; a= b; b= swap; }//order
int edgei= -1;
auto itt= edgesLookupMap.find(std::pair<int,int>(a,b));
if(itt != edgesLookupMap.end())
{
edgei= itt->second;
}
else{
mesh.edges.push_back(edge(a,b));
edgei= mesh.edges.size()-1;
edgesLookupMap.insert(std::pair<std::pair<int,int>,int>(std::pair<int,int>(a,b), edgei));
}
tl.edges[pi]= edgei;
}
}
};
void find_mesh(const std::string& meshId, const bindoc& binDoc, int& index)
{
index= -1;
for(unsigned int mi= 0; mi< binDoc.meshes.size(); mi++)
{
const mesh_geometry& geom= binDoc.meshes[mi];
std::string geomid(geom.meshId);
geomid= "#" + geomid;
if(geomid.compare(meshId)==0) index= mi;
}
};