Texture coordinates

Hi,

I created one simple cube in GoogleSketchup and exported it to Collada (dae) without any textures.

Now I want to texture this cube with my own texture:
.

I know the texture coordinates (from 0 to 1) of the green(!) area. So, the question is: How can I texture my cube only with “green” color/area and put manually this coordinates to my dae code? something like this>

I just want to understand how the texture coordinates work.
Thx!

Hi,

Let’s assume we have the following image with the co-ordinates shown below. (These are not the actual texture coords!!)

I’m then going to make a few assumptions. To keep this simple I’m going to just show you a quad, rendered using triangles and I’m assuming you want all of the green area from the texture to be represented. (From top-left to bottom right.)

The quad I’m drawing will be based on this high quality paint drawing :o).

The points not shown in the collada code below would be your positional values represented by p1 to p4.

Here’s the code to map the texture coordinates to the quad mesh:
Collada stuffs:

<COLLADA version="1.5.0">
...
<library_geometries>
  <geometry id="Quad-mesh" name="Quad">
    <source id="Quad-mesh-positions">...</source>

      <source id="Quad-mesh-texcoords">
        <float_array id="Quad-mesh-texcoords-array" count="8">0.5 0.3 0.8 0.3 0.5 0.45 0.8 0.45</float_array>
        <technique_common>
          <accessor source="#Quad-mesh-texcoords-array" count="4" stride="2">
            <param name="S" type="float"/>
            <param name="T" type="float"/>
          </accessor>
        </technique_common>
      </source>

      <vertices id="Quad-mesh-vertices">
        <input semantic="POSITION" source="#Quad-mesh-positions"/>
      </vertices>

      <triangles material="ColorMaterial" count="2">
        <input semantic="VERTEX" source="#Quad-mesh-vertices" offset="0"/>
        <input semantic="TEXCOORD" source="#Quad-mesh-texcoords" offset="1"/>

        


            0 0 3 3 1 1 
            0 0 2 2 3 3 
        </p>
      </triangles>

    </mesh>
  </geometry>
</library_geometries>
...
</COLLADA>

If the texture coordinates were already generated by your exporter all you should have to do is change the array values within the tag I’ve called “Quad-mesh-texcoords-array”.

I hope I haven’t missed anything?

All the best,
Adam

Hi Adam,

I thank you sooooooooo much ,) Its really a good example for understanding how do the coordinates work!!! This comment is very important for me too!

Thx again!

Best regards,
doc33

You’re most welcome, pleased I could help.

Adam

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.

Duck model texture:
http://www.c3dl.org/wp-content/blog_dem … t/duck.jpg

Please save as targa .tga.

I realised what the problem is.

The engine expects texture coordinates per vertex, like in the DirectX .X format.

Any suggestion / advice how to accomplish this?

Anyone know of an opensource Collada to .X converter?