accessor questions

Hi all, I’m having some problems with the language in the spec describing the accessor tag. Probably the best way to say it is with examples… can someone explain how to write accessors for the following situations?

say you have an array of positions like this: [x1 y1 z1 x2 y2 z2 … xn yn zn]. i assume that a stride of 3 and one param tag for each of x and y will give you only the x and y elements of each position, but how to access only the x and z elements? would this need two accessors? which brings up the question of whether vector-valued semantics in the common profile can resolve to multiple accessors…

now say you have the same array in a different format: [x1 x2…xn y1 y2…yn z1 z2…zn]. again, how to grab only the x and z elements?

also, there seems to be an implicit binding between the order in which child param tags come and the order of data in the array… guess I’d feel better if this were explicitly documented.

and another question: the spec says that “the stride attribute indicates the number of values that comprise each access.” does this imply that the stride is equal to the number of param elements? seems unlikely since it would be quite restrictive.

i suppose these are nit-picky, but i’m trying to write generally useful code in the hopes of collada’s success and of saving myself some work later on.

tyler

Hi Tyler,

Good questions.
The stride works just like in glVertexPointer and accessors work very similarly to OpenGL vertex-arrays.

Example (X,Y,Z and texcoords (S,T) inter-leaved in a single array):

<array id="Array" type="float" count="10">
-0.5  1  0.5 0.0 0.5
 0.5  1  0.5 0.5 1.0</array>

<!- offset missing defaults to "0"...-->
 <accessor source="#Array" count="2" stride="5">
  <param name="X" type="float"/>
  <param name="Y" type="float"/>
  <param name="Z" type="float"/>
 </accessor>

<accessor source="#Array" count="2" offset="3" stride="5">
 <param name="S" type="float"/>
 <param name="T" type="float"/>
</accessor>

To skip values and only pull out X and Z, we could allow for adding dummy params.
This should work (Marcus agrees):

<accessor source="#Array" count="2" stride="5">
  <param name="X" type="float"/>
  <param type="float"/>
  <param name="Z" type="float"/>
 </accessor>

To indicate skipping a float, the middle <param> has no name or id (it still needs a type).

About the order of <param>s. Yes, values are pulled out of the array in that order. It should be in the spec. Thanks for catching this.

G

The <accessor> was designed to assemble stream outputs for <source> elements. There is a constraint on <array> type attributes that limits them to scalar types. An <array> cannot contain a “float3” and so the <param> of an <accessor> cannot use such types in that case either. An <accessor> can assemble a “float3” from three <param> of type “float” however.

This constraint on <param> type in the scope of <accessor> has been under some discussion during the COLLADA 1.1 design meetings. There is a desire to allow the <param> type to be vector types as well, as you are indicating too.

Yes the output of the <accessor> is described by the number and order of the <param> child elements…

The stride indicates the number of values, determined by the <array> type attribute, to access per count iteration. This will include skipped values in some use cases. The stride will often equal the number of <param> elements, when they are scalar values themselves.

The stride means “fetch N values from the source array”. The <param> child elements say “assemble those values like so”.

Actually, no, stride has a different meaning than in ogl. In ogl a stride of 0 would indicate that all data in the array is used, ie it is tightly packed. This confused me at first, but I understand that similarity to ogl terminology is not a design goal.

I was hoping there was a better way, but I suppose it’s not so bad. It still seems a little weird though – the stride explicitly specifies the size of individual “units” in the array and the offsets of the params within each unit are given implicitly by the number of preceding params…

I’ll continue that thought in the next reply…

I think my wording was confusing… What I meant to say was that I can’t see anything preventing something like a POSITION reference from resolving to multiple accessors. For example, it might pick up the X and Y params from one accessor and Z from a second. I guess I have two questions: 1, is this indeed permitted and 2, is this a feature or more of an unintended side-effect?

The reason I brought it up is that it’s the only way I see to describe an access pattern into an array of the form [x1 x2 x3 … xn, y1 y2 y3 … yn, z1 z2 z3 … zn]. Unless of course you put in a potentially large number of dummy params. :slight_smile:

I do like that idea because it would make it a whole lot easier to parse common cases. As it is now (and correct me if I’m wrong) something like

<input semantic="POSITION" source="#someSource"/>

just says that there are 3 params named X, Y, and Z somewhere in “someSource.” They might be split across multiple accessors, in a different order within the same array, or in the same array but not contiguous. This flexibility is great, but it would be nice to have the ability to enforce a semantic that means “there’s a single accessor in some source that provides a 3-vector.”

I was kind of expecting an “offset” attribute or something for each param…

<snip>
The stride means “fetch N values from the source array”. The <param> child elements say “assemble those values like so”.[/quote]
In that case I suggest that the language in the spec could use some work, mostly because I wouldn’t say values that are skipped (stride - numParamTags) are “accessed.” And surely the param tags say more like “those values appear in the array like so.” In any case, thanks for the clarification.

oops, got that one totally wrong. you’re right, it is the same. that’ll teach me to only read the special case.

I think that’s a great idea!:

<accessor id="blah" count="2" stride="5">
 <param name="X" type="float" offset="0"/>
 <param name="Z" type="float" offset="2"/>
</accessor>

This is much cleaner than multiple <accessor>s.
Offset could be optional and the default would be the current number in the sequence.
The only thing we need to be careful about is that if we extend accessors to heterogeneous data, offset will become fuzzy (is it byte, or element?).
That was my only rationale for dummy params with a type, because that type tells you exactly what to skip.
<param> offset would work perfectly for <accessor>s to homogeneous data though.

Gabor

Are byte arrays that can be accessed as anything really under consideration for the next version? That sounds like a radical departure from the 1.0 spec… (and sounds kinda scary to me)

Are byte arrays that can be accessed as anything really under consideration for the next version?[/quote]
No, they’re not. And yes, you’re right, they are scary,
No "void*"s!
:slight_smile:
COLLADA doesn’t specify that an int for example has to be 32 bits. It can be 16 or 64.
The ‘skipping’ would be always by a know type. E.g.:

<mixed_array count="10">
0 1 3 TRUE Orange
1 3 4 FALSE Kiwi</mixed_array>

<accessor id="" count="2" stride="5">
 <param name="X" type="float"/>
 <param type="float"/>
 <param name="Z" type="int"/>
 <param name="selected" type="boolean"/>
 <param name="name" type="Name"/>

<mixed_array> is pure speculation, just like to think as far ahead as I can when designing.
The offset would still work. All the the typed dummy param would offer is a tiny bit more integrity check for the array.

It would catch this as an error:

<mixed_array count="10">
0 Apple 3 TRUE Orange
1 3 4 FALSE Kiwi<mixed_array/>

Of course if you’re skipping the “Y”, you might not care that the array is ‘polluted’, so this would still load fine:

<accessor...>
 <param name="X" type="float" offset="0"/>
 <param name="Z" type="int" offset="2"/>
 <param name="selected" type="boolean" offset="3"/>
 <param name="name" type="Name" offset="4"/>

Also, I DO think that your <param> offset is a bit more elegant and more compact than dummy params, so it’s a toss-up for me.

What do you think about the type-check?

Gabor

No, they’re not. And yes, you’re right, they are scary,
No "void*"s![/quote]
That’s good to hear.

I had been assuming that the type attribute of the param tag describes how you want to access the data, not the type of the source. So accessing a float array with three int params x, y, and z will implicitly convert to int (assuming that this is one of the “sensible” conversions mentioned in the spec). If it had to match the type of the source specifying it per-param now would be redundant…

I think there’s probably a more flexible and elegant solution than dummy params, but I’m not sure that adding an offset attribute is it. Maybe not appropriate for all the other uses for param?

I’m still curious about how to access a “struct of arrays” like [x1 x2 … xn, y1 y2 … yn, z1 z2 … zn]. The only two solutions I see are (n-1)*3 dummy params and a stride of 1, or 3 different accessors… Neither of those seems pretty to me. Not a big deal, just seems like there should be a prettier solution.

What do you think about the type-check?

I think the type-check is a good option. Maybe it should be able to be specified at the <accessor/> level for homogenous data sets so that it need not be redundant on each param. I also think the optional offset attribute is a good idea. Type-checking on dummies would be even more flexible with optional offsets because you could just check those offsets that matter. For example:

<param type=“float” offset=“2”/>

<param/> elements without a ‘name’ attribute would be type-checking dummies.

The offset should just be assumed to start at zero if omitted && increment for each new <param/> element encountered in document order.

-Pip

I have read through the post here and have gained more understanding of the COLLADA format but I still don’t understand how there can be mutiple <accessor> tags within a COMMON profile.

The input semantic for a POSITION in a <vertices> tag does not specify which accessor to use for the source data. So if I have for example (notice the different param order):


<technique profile="COMMON">
 <accessor source="#box-Pos-array" count="8" stride="3">
              <param name="X" type="float" flow="OUT"/>
              <param name="Y" type="float" flow="OUT"/>
              <param name="Z" type="float" flow="OUT"/>
 </accessor>
 <accessor source="#box-Pos-array" count="8" stride="3">
              <param name="Z" type="float" flow="OUT"/>
              <param name="Y" type="float" flow="OUT"/>
              <param name="X" type="float" flow="OUT"/>
 </accessor>
</technique>

… they are still both within the common profile. So which one should I use when reading a vertices semantic data? The first one? Or does the exporter always define a default order of X Y Z in a position array regardless of which DCC is used?

I guess I’m looking for something like <accesor type=“POSITION” … > which could tell me that the array is a position array and nothing else.
Any thoughts?

It happens when the <source> is a child element of the <combiner> element as one example. I’ve already added some examples to specification for 1.3.0 (planned release next week).

So there is some flexibility when describing source data streams in COLLADA.