Generating Vertex Data Buffers off of COLLADA Mesh Instances

I’m having trouble with associating data across multiple COLLADA ~source~ elements occuring under mesh instances in COLLADA instance documents. I have thoroughly read the the wiki documentation on “Using accessors” at: https://collada.org/mediawiki/index.php/Using_accessors but it does not seem to address the requirements of my application.

Given collada instance document test cases with ~source~ element instances exemplified as follows…


      <geometry id="mesh1-geometry" name="mesh1-geometry">
         <mesh>
            <source id="mesh1-geometry-position">
               <float_array id="mesh1-geometry-position-array" count="846">1.634429 51.875743 ... 28.753150 </float_array>
               <technique_common>
                  <accessor source="#mesh1-geometry-position-array" count="282" stride="3">
                     <param name="X" type="float"/>
                     <param name="Y" type="float"/>
                     <param name="Z" type="float"/>
                  </accessor>
               </technique_common>
            </source>
            <source id="mesh1-geometry-normal">
               <float_array id="mesh1-geometry-normal-array" count="606">0.0 0.0 -1.0 -0.0 -0.0 1.0 ... -0.4499 0.0 -0.8931 </float_array>
               <technique_common>
                  <accessor source="#mesh1-geometry-normal-array" count="202" stride="3">
                     <param name="X" type="float"/>
                     <param name="Y" type="float"/>
                     <param name="Z" type="float"/>
                  </accessor>
               </technique_common>
            </source>
            <source id="mesh1-geometry-uv">
               <float_array id="mesh1-geometry-uv-array" count="488">-0.893716 28.366001 -1.552262 27.707456 ... -18.082695 -14.795389 </float_array>
               <technique_common>
                  <accessor source="#mesh1-geometry-uv-array" count="244" stride="2">
                     <param name="S" type="float"/>
                     <param name="T" type="float"/>
                  </accessor>
               </technique_common>
            </source>
            <vertices id="mesh1-geometry-vertex">
               <input semantic="POSITION" source="#mesh1-geometry-position"/>
            </vertices>
            <triangles material="material_0_1_8" count="64">
               <input semantic="VERTEX" source="#mesh1-geometry-vertex" offset="0"/>
               <input semantic="NORMAL" source="#mesh1-geometry-normal" offset="1"/>
               <input semantic="TEXCOORD" source="#mesh1-geometry-uv" offset="2" set="0"/>
               

0 0 0 1 0 1 ... 130 26 101 </p>
            </triangles>
            <triangles material="material_1_24" count="542">
               <input semantic="VERTEX" source="#mesh1-geometry-vertex" offset="0"/>
               <input semantic="NORMAL" source="#mesh1-geometry-normal" offset="1"/>
               

2 1 1 1 ... 277 199 </p>
            </triangles>
            <triangles material="material_3_24" count="366">
               <input semantic="VERTEX" source="#mesh1-geometry-vertex" offset="0"/>
               <input semantic="NORMAL" source="#mesh1-geometry-normal" offset="1"/>
               

15 12 27 12 ... 276 167 </p>
            </triangles>
            <triangles material="material_2_2_8" count="80">
               <input semantic="VERTEX" source="#mesh1-geometry-vertex" offset="0"/>
               <input semantic="NORMAL" source="#mesh1-geometry-normal" offset="1"/>
               <input semantic="TEXCOORD" source="#mesh1-geometry-uv" offset="2" set="0"/>
               

61 40 75 84 40 76 ... 281 198 243 </p>
            </triangles>
            <triangles material="material_4_24" count="92">
               <input semantic="VERTEX" source="#mesh1-geometry-vertex" offset="0"/>
               <input semantic="NORMAL" source="#mesh1-geometry-normal" offset="1"/>
               

62 46 49 46 ... 258 187 </p>
            </triangles>
         </mesh>

My application needs to:

(1) Generate a vertex buffer with the following structure:


x1 y1 z1 nx1 ny1 nz1 tu1 tv1
x2 y2 z2 nx2 ny2 nz2 tu2 tv2
...
xN yN zN nxN nyN nzN tuN tvN

Where

  • xi, yi, and zi are position coordinates
  • nxi nyi nzi are normals, and
  • tui and tvi are texture coordinates on a UV coordinate system

and each position/normal/texture-coordinate tupple corresponds to a triangle vertex, and

(2) Generate a vertex index describing a set of triangles over the vertex buffer.

The “Using Accessors” wiki documentation describes how to create vertex data structures similar the one required by my application. However, the documentation shows how to create such structures only for cases where the position, normal and texture coordinate data are interleaved within a single source array. My problem is that all my test cases involve three sources corresponding to the position, normal and texture coordinate data respectively. My issue is that I can see no way of identifying which position, normal and texture coordinate tuples relate to one another across the disparate source elements based on the information explicit in the accessors associated with the sources. So, given the collada accessor arrangement described in my test cases, how would an application generate a vertex buffer as described above with the correct associations between position, normal and texture coordinate data points? And once the vertex buffer is generated, how might the vertices be indexed so as to correctly describe the triangles in the mesh?

Thank you in advance for any input you might be able to offer.

If you still haven’t figured this out…

it is the semantic in input which will help you connect the consumer(triangles/polylists etc) to the data in source.

As for indexing vertices, I do that by using a hash map < index, Vertex > once I have extracted all the vertex information.

Hope this helps some

Thanks for your reply. I do realize that the ~semantic~ attribute on the input nodes does provide a set of values to understand the class of input data (vertex, normal, texture coords, etc.). But my problem is starting with the accessors, how can you correlate which data points are associated with which in each of the input streams. So, given the example here, which position data points are associated with which texture coordinates. I can see no obvious way to correlate the data points working from the accessors. You can work backwards from the ~triangles~ indices to associate the data points, but this results in a less-than-optimal indexed face set.

Again thank you very much for your reply

:shock:

I am not 100% clear on your question. Are you saying that you cant figure out how can accessors be used in tandem with input tags?

One thing, I’d like to mention is…accessors only help in identifying a mechanism which enables you to access the source data. It is the consumer which chooses one of these sources. Thus the consumer like triangle would ch oose a source using input, given the semantics.

If you are having issues with trying to figure out indexing, let me know and I’ll try to post a more elaborate response here.

Thank you for your offer to shed more light on COLLADA indexing. Personally, I think I have good working sense of it, however, I had trouble with what I was able to find in the available documentation and had to achieve much of that understanding through careful analysis of a range of development and test cases. Of course, that approach always leads you to make numerous inferences and assumptions which require explicit confirmation. For, my part, I’m OK, but if you have time, an explicit explanation here about COLLADA indexing might benefit the community going forward (which is why I posted this topic).

To try to clarify my issue: If you look at the example above, you’ll see that there are three input streams: (1) vertex (position) data, (2) normals, and (3) texture mapping data (in the form of UV coordinates). My problem is that each vertex tuple must be associated with normals and UV coordinates (to create the vertex data buffer structure as shown above). In all of my test cases, the 3 inputs are represented in separate source streams. So, if I ~start~ with the vertex data source, how do I obtain the corresponding normal and texture coordinates to create a tuple on the vertex data buffer? The vertex data, normals and texture coordinates all occur in separate and corresponding source streams, and I can discern no obvious way to associate data points across each stream.

Cool! I’ll try to post what I have…

I have a question for you regarding your query and I think that should help us answer your question.

Given all these data sources and input streams, how do you populate the tuple of that vertex ?

(hint: The

tag)

Yeah, pretty much. I used the ~p~ element data, (which I inferred are indexes to the triangle inputs). One problem (that requires a little thought :wink: ) is how to stride that array. But the more severe issue is that that indexing scheme seems to result in a less-than-optimal vertex buffer with redundant occurrence of vertex position data…

I don’t quite see what your question is either :wink:

The VERTEX input requires a POSITION input, to establish mesh vertex identities, bit it can have other inputs and semantics as well.

It’s the job of the primitive elements to collate vertices (tuples) by sampling the inputs using the supplied indexes.

This is the job of the

element. Each integer value is an index that is used to sample the <input> according to the offset attribute value. A single point sample maps like this:


<triangles count="1">
<input semantic="VERTEX" source="#A" offset="0" />


 99 88 77 </p>

… meaning: for one sampling, take the value “99” from

and sample the 99th value from source “A”, etc. In other words the triangle is formed by:


struct {
 vertex V0:
 vertex V1;
 vertex V2;
} triangle = { A[ 99 ], A[ 88 ], A[ 77 ] };