Reading Multiple UV inside DAE File

Started by
10 comments, last by Medo Mex 8 years, 3 months ago

Hi Guys,

I'm able to load COLLADA DAE file and the mesh appear on the screen correctly if I only have one UV array in the .DAE file

But, sometimes when I export a mesh from 3Ds Max, I get more than one UV array inside the .dae file as the following:


<float_array id="Mesh29-UV0-array" count="24046">...
<float_array id="Mesh29-UV1-array" count="24046">...
<float_array id="Mesh29-UV2-array" count="24046">...
<float_array id="Mesh29-UV3-array" count="24046">...
<float_array id="Mesh29-UV4-array" count="24046">...
<float_array id="Mesh29-UV5-array" count="24046">...
<float_array id="Mesh29-UV6-array" count="24046">...
<float_array id="Mesh29-UV7-array" count="24046">...

If I have more than one UV array as the above, how do I load that into the vertex buffer?

In C++, my vertex structure look as the following:


struct VertexStruct
{
        D3DXVECTOR3 pos;
        D3DXVECTOR2 uv;
        D3DXVECTOR3 normal;
}

Note that I only have one texture assigned to the mesh in 3Ds Max.

Advertisement

Still having the same problem...


If I have more than one UV array as the above,

See triangles/polygons/polylist tag. It defines input semantics, pointing to exact uv source.

If you have multiple inputs with TEXCOORD semantic on same triangles, that means you have multiple uv channels on model.

You can just take first uv and ignore the rest if you don't need it.

@vstrakh: I tried to use the first UV from Mesh29-UV0-array, but the texture appear on the mesh incorrectly.


but the texture appear on the mesh incorrectly.

It would help if you upload that dae file and texture.

@vstrakh: I'm having the problem with this model, it's a vehicle chassis only (no wheels):

[attachment=30263:vehicle.rar]

I appreciate your help.

UV channel 0 has correct data.

UV channels 1/2/3 has something that looks like projection to sphere.

UV channels 4/5/6/7 has texture coords grouped in 1 or 2 points.

File itself feels malformed. Scene id was empty, so couldn't be instantiated.

Texture in material is pointing directly to image, while by spec it should point to sampler.

After manually fixing that, I can see your model correctly.

[attachment=30265:apc.jpeg]

If you see texture incorrectly, that means your loader is incorrect, or you didn't select first uv channel.

Typically when geometry instantiated, <instance_material> tag has also <bind_vertex_input> that specifies exact uv channel to be used with texture sampler. But your file didn't use that, and also violated spec by linking image directly to material, without sampler.

As simplest solution you should check scene file in Max, and remove all unneded uv channels.

@vstrakh: I guess that I'm doing something wrong, here is what I'm doing (correct me if I'm wrong):

1. Reading all the data inside <float_array id="Mesh29-UV0-array" count="24046"> in char*

2. Convert it to D3DXVECTOR2* by using strtok()

3. Read the indices from <p> inside char*

4. I do the following:


// indicesStr = char* contains all the data between <p></p>
// numOfOffsets = Last input semantic offset attribute (in this mesh it's 9)
// So numOfOffsets = 9
// Final results: pIndices.x = POSITION Index, pIndices.y = NORMAL Index, pIndices.z = UV Index

D3DXVECTOR3* indices = new D3DXVECTOR3[indicesCount];
char* tok = strtok(indicesString, " ");
for(UINT i = 0; i < indicesCount; i++)
{
     for(UINT j = 0; j < numOfOffsets + 1; j++)
     {
         if (j == 0)
         {
               // offset 0 POSITION
               pIndices[i].x = (float)atoi(tok);
         } else if (j == 1) {
               // offset 1 NORMAL
               pIndices[i].y = (float)atoi(tok);
         } else if (j == 2) {
               // offset 2 UV0
               pIndices[i].z = (float)atoi(tok);
         }

         tok = strtok(NULL, " ");
     }
}

Then I fill the vertex buffer like this:


// I got UV[] array from step one and two above
VERTEX* vertices = new VERTEX[IndicesCount];
for(UINT j = 0; j < indicesCount; j++)
{
    vertices[j].position = Position[(int)pIndices[j].x];
    vertices[j].normal = Normal[(int)pIndices[j].y];
    vertices[j].uv = UV[(int)pIndices[j].z];
}

// Code here to create vertex buffer based on "vertices"...


D3DXVECTOR3* indices = new D3DXVECTOR3[indicesCount];

What's that 'indicesCount' ? If it's attribute 'count' taken from <triangles> tag (<triangles count="8047"...), then you should multiply it by 3, since that's triangles count, and not vertex/indices count.


// numOfOffsets = Last input semantic offset attribute (in this mesh it's 9)

Carefully here, inputs can go in any order. You should use number of inputs, since 'offset' attribute of last input might be any number, not necessarily max of all.


if (j == 0)
{
// offset 0 POSITION
pIndices.x = (float)atoi(tok);

You're hardcoding input positions. While it might look like all your files follows same order, that order is not fixed by spec. Inputs might come in any order.

What's that 'indicesCount' ? If it's attribute 'count' taken from <triangles> tag (<triangles count="8047"...), then you should multiply it by 3, since that's triangles count, and not vertex/indices count.

I'm already multiplying it by 3, so in this case I get indicesCount = 24141

Carefully here, inputs can go in any order. You should use number of inputs, since 'offset' attribute of last input might be any number, not necessarily max of all.

I fixed this by getting the number of children - 1 instead of the last offset.

You're hardcoding input positions. While it might look like all your files follows same order, that order is not fixed by spec. Inputs might come in any order.

The mesh geometry appears correctly, only the texture appears incorrectly, according to this file, the UV offset is 2 so I guess what I'm doing in the above code should load the UV correctly.

I'm trying to load this file and display the model on the screen correctly and then I can optimize the code later.

Here is a screenshot of how the mesh appear now with Invalid texture coordinates:

[attachment=30276:Model.png]

If you need any other information please let me know.

This topic is closed to new replies.

Advertisement