Hi. I’m in a pinch and I could really use some help or any insight you would care to offer.
I need to write a rather rudimentary Collada importer for an old game engine. I thought it would be easier and faster to parse the file myself in one pass, disregarding the xml tree like structure, and going straight to the data I want from inside the .dae file.
The loader is meant for simple objects to be used as props and populate the landscape with. Trees, etc.
For now I’m not bothering with multimaterial meshes, multi geometry meshes, etc.
I managed to load the vertex coordinates and the triangle indices so the geometry loads fine (again, for simple objects, single material meshes). This is fine for now.
I ignore the normal altogether. I disregard both the normal coordinates and the normal indices. After I load the vertex coordinates and the triangle (tip) indices i compute the normals from these and everything is fine here as well.
The problem I have is with the texture coordinates.
When I encounter the texture coordinate array
<float_array id="LOD3spShape-lib-map1-array" count="4554">0.245158 0.423975 0.25011 0.468112 0.150442 0.543685 etc. etc. etc.</float_array>
I allocate memory :
// texture coordinates
seektoken ("count");//look for the "count" token
texcornumber = atoi( readtoken () ) ;// reading number of texture coordinates - in this case it is 4554
// allocating memory for of texture coordinates intermediary storage
float* intertexcord = (float*)aMemAlloc(texcornumber*sizeof(float), "intertexcord"); // A_ASSERT(a_script_mesh->vert)
And I read the 4554 floats which I store inside intertexcord:
for (int i = 0; i <= texcornumber-1; i++)
{
intertexcord[i] = atof(readtoken("< >\"")); //aConOut("Intertexcord[%5i] : %5f
", i,intertexcord[i]);
};
seektoken ("stride");
texcorstride = atoi( readtoken () ) ;// reading the stride, how many texture coordinates per triangle tip
I have checked and I read all the floats ok. No problems whatsoever. I’ve checked with aConOut() a lot of times and all the texture coordinates load ok.
Next, I skip to where the triangle strips are and read the number of triangles for the first triangle strip encountered. Again, I’m only dealing with single material meshes for now. For proof of concept and to get it working and have something to evolve from:
// triangle indices
seektoken ("count");
triangnumber = atoi( readtoken () ) ; // reading number of triangles
Now I know the number of triangles.
indicenumber = triangnumber * 3; // computing the number of indices from the number of triangles
a_script_mesh->ind_no = indicenumber; // committing indices number to the mesh
I allocate memory for storing the triangle indices, which will tell me for each triangle which 3 vertices define it:
// allocating memory for storing the triangle indices of the mesh - they define the actual triangles
a_script_mesh->ind = (uint*)aMemAlloc(a_script_mesh->ind_no * sizeof(uint), "aReadFloatVect::d"); A_ASSERT(a_script_mesh->ind)
I have allocated memory for the triangle indices. Now I allocate memory for the texture coordinates:
// allocating memory for storing the actual texture coordinates
a_script_mesh->tex_maps_2d[0] = (a2DCoord*)/*(float*)*/aMemAlloc(a_script_mesh->ind_no*sizeof(float)*2, "aReadFloatVect::d"); A_ASSERT(a_script_mesh->tex_maps_2d)
a2DCoord :
typedef struct a2DCoord {
float u, v;
} a2DCoord;
Ok. Now I parse the file and actually read the vertex indices and, the texture coordinates indices :
// reading the triangle indices from the .dae file
for (int i = 0; i <= a_script_mesh->ind_no-1; i++)
{
a_script_mesh->ind[i] = atoi( readtoken("< >\"")); //aConOut("Index[%i] : %d
", i, a_script_mesh->ind[i]);
readtoken("< >\"") ; // normal index, disregarding
tempint = atoi( readtoken("< >\"")); //aConOut("Tempint : %i
", tempint);
a_script_mesh->tex_maps_2d[0][i].u = intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].v = intertexcord[tempint * texcorstride + 1];
//aConOut("a_script_mesh->tex_maps_2d[0][%5i].u : %5f == intertexcord[%5i] : %5f
", i, a_script_mesh->tex_maps_2d[0][i].u, tempint * texcorstride ,intertexcord[tempint * texcorstride ]);
//aConOut("a_script_mesh->tex_maps_2d[0][%5i].v : %5f == 1-intertexcord[%5i] : %5f
", i, a_script_mesh->tex_maps_2d[0][i].v, tempint * texcorstride+1,intertexcord[tempint * texcorstride+1]);
//aConOut("
");
}
As you can see, I all had to aConOut() to check that everything is read ok. And everything is as it seems it should be.
a_script_mesh->tex_maps_2d[0][i] is the array that contains the texture coordinates for texture number 0. i is the array index. It is an array of a2DCoord so it has
a_script_mesh->tex_maps_2d[0][i].u
and
a_script_mesh->tex_maps_2d[0][i].v
After all that, this is how the triangulated duck from the collada-dom-2.2 looks like:
I thought it might be that the texture coordinates are inverted or switched among themselves so I tried various combinations:
a_script_mesh->tex_maps_2d[0][i].u = intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].v = intertexcord[tempint * texcorstride + 1];
a_script_mesh->tex_maps_2d[0][i].u = 1-intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].v = intertexcord[tempint * texcorstride + 1];
a_script_mesh->tex_maps_2d[0][i].u = 1-intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].v = 1-intertexcord[tempint * texcorstride + 1];
a_script_mesh->tex_maps_2d[0][i].u = intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].v = 1-intertexcord[tempint * texcorstride + 1];
And with the U and the V coordinates interchanged :
a_script_mesh->tex_maps_2d[0][i].v = intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].u = intertexcord[tempint * texcorstride + 1];
a_script_mesh->tex_maps_2d[0][i].v = 1-intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].u = intertexcord[tempint * texcorstride + 1];
a_script_mesh->tex_maps_2d[0][i].v = 1-intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].u = 1-intertexcord[tempint * texcorstride + 1];
a_script_mesh->tex_maps_2d[0][i].v = intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].u = 1-intertexcord[tempint * texcorstride + 1];
No textured model looks right, except for two simple tile models, each consisting of 2 triangles forming a rectangle face.
I will attach the models and textures used for testing.
The models :
1.dae
2.dae
bila.dae
duck.dae
The textures, respectively:
domUVcheck.tga
reftext.tga
MetalBare0099_2_S.tga
duckCM.tga
If I use
a_script_mesh->tex_maps_2d[0][i].v = 1-intertexcord[tempint * texcorstride];
a_script_mesh->tex_maps_2d[0][i].u = 1-intertexcord[tempint * texcorstride + 1];
then 1.dae and 2.dae have the textures applied correctly but the more complex models still don’t.
Thank you for your time and trouble as well as any insight you may provide.
Best regards,
Laur.