Scoped-Identifier (SID) Addressing clarification

Hi,

For increased flexibility and concision, the SID addressing mechanism allows for skipping XML elements. It
is not necessary to assign id or sid attributes to all in-between elements.

this is ok:


 <channel source="#YFOVSampler" target="Camera01/YFOV"/>
      ...
      <camera id="#Camera01">
        <optics>
          <technique_common>
            <perspective>
              <yfov sid="YFOV">45.0</yfov>
              <aspect_ratio>1.33333</aspect_ratio>
              <znear>1.0</znear>
              <zfar>1000.0</zfar>
            </perspective>
          </technique_common>
          <technique profile="OTHER">
            <param sid="YFOV" type="float">45.0</param>
            <otherStuff type="MySpecialCamera">DATA</otherStuff>
          </technique>
        </optics>
      </camera>

but I’m confused a bit, for instance;

if we try to resolve “node1/camera/…” then which “camera” node should be selected?


<node id="node1">
  <node sid="skip_if_you_want">
    <node>
      <node sid="camera">
         ...
      </node>
    </node>
  </node>
  <node>
    <node sid="camera">
       ...
    </node>
  </node>
  <node sid="camera">
       ...
  </node>
<node>

The third camera. That’s what the “breadth-first” part is getting at. I agree it’s not very clear. There’s a lot of room for improvement in the documentation, and parts of it are just plain wrong. Especially in the 1.5.0 PDF, because it was largely only copy/pasted.

Two things about the SIDREFs that are bad and should be revoked I think, is the notion that a . is a valid SIDREF. That’s basically a degenerate case that runs into all kinds of problems. I’m told relatives refs aren’t really used, so I suppose no part of the schema calls for them. The other thing is the double [][] subscript member selector. That’s pretty much an impossibly tall-order since there’s no way to determine the “width” of the 2D array, except to go by the schema types, which don’t exist in documents, or to examine the name of the element, which seems like a lot of work for not much, and can only get uglier as more names are added to the list. The current names are <matrix> and <lookat> and the latter I’m not sure if it’s even a matrix or not (I’ve noticed it says it’s 3 coordinates, which may or may not be a decomposed affine matrix; I’d have to check.)

I should implement breadth-first search, thanks, I’ve created sid-tree so it seems it does not fit to breadth-first search. Traversing/Walking through this tree would be more cheaper than traversing through all parent-child elements :confused: Maybe I should add a level (integer) to specify sid-node depth then I can skip all elements (when resolving) which don’t have sid attr, otherwise I should check all child elements and test all elements one by one for sid existence… Any better idea (maybe algorithm)?

Good point, I think specs scheme should prevent . (relative addressing) inside SIDREF or SIDREF_array or maybe all elements with no child
In my implementation there is no prob with [][] or ()() because all arrays e.g. matrices, rotate, trans, scale, indices, normals… are continuous array so implementing ()() is not hard in this case:

if matrix is:

1 0 0 0
0 1 0 0
0 0 1 5
0 0 0 1

then


float z;

z = *(float *)ak_sid_resolve(doc, "node1/translate(3)(2)");

/* inside resolve I just need cast found mem-ptr to two-demiansinal array, e.g. return ((float **)ptr)[3][2]
    or move pointer directly ptr += (3 + 1) * (2 + 1) - 1 ...
 */

Hope ()() is column major I mean first index is row in mathematical sense but the matrix is transposed :confused:
COLLADA keeps column matrices as row major layout but I’m transposing them during parsing, another question occurs: should I change ()() orders in sid/target?

One more question, can we skip prent’s sid to access child sid node? node1/camera_parent/camera gives the camera node but should node1/camera give the camera node or NULL?


<node id="node1">
  <node sid="camera_parent">
    <node>
      <node sid="camera">
         ...
      </node>
    </node>
  </node>
<node>

node1/camera does get the node. The () notation (I said [] before) relates to <xs:list> in the schema. The matrix conventions are probably the same as OpenGL but I don’t know. It might depend on the <asset>.

Relative SIDREFs are not the problem. It’s the difference between a . and a ./ that is the problem. The specification is written as if the slash is optional. I don’t believe myself that a SIDREF should be able to access an element without a scoped “sid” attribute. Things like .() and …ANGLE are weird to parse. I think that’s a mistake.

()() is not feasible because the 2-D array can be anything, 1x1, 3x2, 3x1, 5x4. It was a bad idea. A mistake. The <xs:list> is 1-D. XML Schema doesn’t allow for 2-D lists.

The COLLADA-DOM library keeps a multimap of “sid” IDs for resolving SIDREFs. The elements are looked up in the map and traced back to their parents to see if they fit or not. It’s a legacy feature. Anyway, it doesn’t involve any trees or traversals that way.

BTW: Don’t forget if you do work on SIDs that the “profile” attribute is all important, and the main reason for SIDs to begin with. It’s because software doesn’t implement COLLADA correctly that it cannot get a foothold. It doesn’t help if there are 50 implementations, if they are all less than half complete and none can transform a document losslessly, it’s all just wasted effort and can do nothing to forward COLLADA’s mission statement. It’s probably better if there is just one implementation. It’s hard to get everything correct. It’s a very tall order.

Yep, it is really weird,

In XSD matrix seems a separate type rather than <xs:list> also PDF says it is float4x4_type so dimensions of type are known?

Last night I thought I found an algorithm/data structure to store sids (breadth-first search), walking/traversing on sid nodes and their children is cheaper; still seems nice (maybe until new one :slight_smile: ) but it has a big flaw: swithing from memory tree to sid tree is too expensive (I have to search first-top sid node in children) but finding other sids are cheaper. The problem is that using only one sid is common (I think) :slight_smile: e.g #camera/xfov. I tried to find new structure because every level of tree, I dont want to use malloc/free to create new list/queue; it is too expensive even trying to cache malloc-ed memory, maybe there are better implementation of breadth-first search without queue-ing child elements, I’ll take a look at acm dl

BTW: Don’t forget if you do work on SIDs that the “profile” attribute is all important, and the main reason for SIDs to begin with.

I’ll back to profiles after implemented sid addresing, thanks

Maybe it is tooooo early to speak but it seems like I found an easy way to find child sid node of memory node, great! No recursive, no queue, no stacks, no malloc-s, I’ll share it if I can implement it successfully otherwise probably I may prefer to remain quiet about this :confused:

To know the type is “float4x4_type” you have to A) have a schema, and B) assume the name of the type is something like NxN and C) search through the types name for NxN and parse that, which is D) not how things should ever be done in computer science. That’s a classical “hack” scenario IOW. Reflecting on the schema and the name of the element or type in the schema are all very expensive to compute just for the convenience of writing (2)(1) instead of (9). That’s a problem for authoring software, not a URI resolution algorithm. URI resolution is something that has to be done in order to read the document complex. Reading is the more performance critical pathway.

Just FYI I filed an issue relating to SIDREF just now:

I have my original concerns, but also a new one where I noticed the manual using a SIDREF to address a SID as if it is an ID. That’s not part of the guidelines in the manual. I think it’s useful, but the syntax of a SIDREF should be extended to let it begin with a / character in order to select the root/top fragment as the ID, as if using # in a URL.

EDITED: I’ve actually about had enough with SIDREFs. The schemas are so inconsistent about them apparently.

In the <texture texture> use case, the type of the attribute is xs:NCName in both versions. That means it cannot even be a SIDREF! But yet it references <newparam sid> and there are no guidelines whatsoever about how to locate that reference or if it is a SIDREF. It cannot be because it cannot contain a / and so I don’t know if what I am seeing is a malformed SIDREF or if it’s just a mystery addressing scheme.

The same thing goes in <bind target>. In this case the type of target is xs:token in both schema. This type can even contain spaces. And its annotations and the manual say refer to “Addressing Syntax” section, which doesn’t exist in any documents. But if you look in the provided example in the manual it uses a / so it must be a SIDREF.

I know it was really big and a lot of work, but it seems like COLLADA schemas could be 10 times more shipshape and they’d still not be up to the level that inspires confidence.