KhronosGroup / OpenCOLLADA

653 stars 252 forks source link

UP Axis clarification #517

Closed recp closed 7 years ago

recp commented 7 years ago

Hi,

Is it valid to any parent element of <asset> (e.g. geometry, node) can have different up_axis in a COLLADA document?

For instance if document is Z_UP then can any specific child node have Y_UP becase of <asset> ?

<COLLADA xmlns="http://www.collada.org/2008/03/COLLADASchema" version="1.5.0">
    <asset>
        <up_axis>Y_UP</up_axis>
    </asset>
...
<library_geometries>
     <geometry>
          <!-- Does this affect the node's transform ? -->
          <asset>
               <up_axis>Z_UP</up_axis>
          </asset>
...
<library_visual_scenes>
     <visual_scene>
          <node>
              <!-- Does this affect the node's transform ? -->
               <asset>
            <up_axis>X_UP</up_axis>
               </asset>
               <translate sid="translate">0 199.871 -0</translate>
               <rotate sid="rotateY">0 1 0 -0</rotate>
               <rotate sid="rotateX">1 0 0 0</rotate>
               <scale sid="scale">1 1 1</scale>
               <node>
                 <!-- Also this and so on? -->
                 <asset>
              <up_axis>Z_UP</up_axis>
                 </asset>
                  ...

If it is so, then this would make geometry element have extra transforms outside of scene element.

Thanks for clarification

RemiArnaud commented 7 years ago

its not valid, up_axis is for the document only.

On Mon, May 15, 2017 at 1:42 PM, Recep Aslantas notifications@github.com wrote:

Hi,

Is it valid to any parent element of (e.g. geometry, node) can have different up_axis in a COLLADA document?

For instance if document is Z_UP then can any specific child node have Y_UP becase of ?

Y_UP ... Z_UP ... X_UP 0 199.871 -0 0 1 0 -0 1 0 0 0 1 1 1 Z_UP ... If it is so, then this would make geometry element have extra transforms outside of scene element. Thanks for clarification — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub , or mute the thread .
mbarnes-sb commented 7 years ago

Actually it's valid for each asset element to declare it's own up-axis and unit. A conforming implementation needs to handle them. The spec says:

In the case of hierarchical <asset> elements, where both the parent and child assets supply a value for the same metadata, such as for <unit>, the child asset’s value supersedes the parent’s value within the scope of the child element. This applies recursively.

m-7761 commented 7 years ago

I prefer mbarnes-sb's answer and have implemented it. (So COLLADA can be more like a WWW technology.)

But I think <up_axis> is not well fit to some element types, take <source> for example.

RemiArnaud commented 7 years ago

IMHO it does not make much sense to have more than one up-axis. But if we insist then let's define precisely what it means for the scene to have a up-axis, especially if different than the animation up axis, and in particular when the animation is going to target the 'rot_Y' which is only define by sid, and thus has no real meaning for an implementation to handle.

m-7761 commented 7 years ago

<animation> (or its data) is probably a very good candidate for not having meaningful application of its <up_axis> because like <source> it is an unworkable burden. And it seems reasonable to think that if the animation is driving the animated data that it must work in the same sense of the data it targets.

That is to say that animation data is mixed data, or it doesn't have an implied "sense" apart from what it augments.

The scene doesn't really have an up_axis, it just inherits from the document and so on. The application may have its own space that is separate from the documents' or what a document can express.

I find the math around coordinate system management very vexing. I cannot find resources on it online and have not taken the time to analyze it my own way. I only found a working system for changing the up_axis of a <matrix> the other day. I truly think it's one of those things that could've had a math subsection in the manuals.

(What works is doing two multiplies against a simple 1/-1 matrix that would convert a vector, that must cancel out on an identity matrix, except the -1 in COLLADA's matrices cause it to swing back and forth with respect to its signs when multiplied--introducing negative scaling behavior--and so I played around with it and found swapping the signs between the two multiplies cause the -1s to cancel out. You look at it and think it's just flipping/swapping the basis vectors and translation component, but it seems to be more than that. I intend to analyze it and document it.)

Most everything that is geometric in nature, with length based figures, has logical applications of the up_axis and units. Sometimes it's not obvious. Like in <skin> it only applies to the binding matrices. You might think it shouldn't, but conceptually they are length/coordinate-frame based data inside of it, and it can be implemented independent of the <geometry> referenced by the <skin>.

recp commented 7 years ago

Actually it's valid for each asset element to declare it's own up-axis and unit. A conforming implementation needs to handle them

@mbarnes-sb I will implement it in AssetKit if I can understand the meaning of multiple up_axis. AssetKit must guarantee that all document uses ONE and same (e.g. Y_UP) up_axis before sending it to renderer or to another data structure

Does up_axis in geometry change X, Y, Z order (or add extra transform)? If so, <asset> is hierarchical so if document is Z_UP then all geometries will be Z_UP, also all nodes in scene will be Z_UP, also cameras and lights

so if we need to extra work because of up_axis in geometry and node we would do it recursively

for external geometries we have to reference document file, right? e.g. <instance_geometry url="another.dae#duck"> The referenced document have it's own UP axis so we know external duck.dae's up_axis

Also why camera has up_axis? What is the meaning of up_axis in camera or maybe in light? Transforms of camera (matrix, lookat) already specifies the up axis, am I right? if document is Z_UP then camera must be Z_UP then :-S

RemiArnaud commented 7 years ago

Up-axis was intended ton reflect that various tools work in different up-axis, and rather than forcing the exporter to change axis on export, we put the information in the document. When an element is referenced from an external document, it is important to check the up-axis of the imported document and make changes as appropriate since external referenced document may have been stored from a different tool

Otherwise it has never been the intent to use up-axis everywhere in the document. There is no information in the specification as what it means. Inferring meaning is going to be your interpretation of the spec I am afraid. Marc mention the spec language and answered your question literally regarding what the spec says. But the right course of action is to recognize up-axis has a bug in the spec, and use it for entire documents only. This said, other than making your code more complex, this is going to be a futile effort, because you won't find any document with up-axis other than in the header, and if you export those, they'll be ignored by everybody else.

recp commented 7 years ago

@RemiArnaud thank you, this is what I wanted to hear! 👍

I've already implemented it for entire document, it can convert any up axis to another using document's up axis value

Checking up_axis in every element (except external documents) would make things very difficult and more complex

m-7761 commented 7 years ago

An easy way to test correctness is to change the document's up_axis and see if it comes out the same. You'll see that the cameras and lights will depend on the up_axis then.

Strikeout: It matters, but come to think of it, the actual <camera> and <light> elements may not define anything in terms of "up" but relative to the instancing node the math changes; especially if you intend make the camera or light interactive. (The manual says something about scaling the light, but I'm not sure if attenuation works like that.)

EDITED: Actually <xmag> <ymag> <znear> and <zfar> are unit dependent. The CTS gets this wrong: https://github.com/KhronosGroup/COLLADA-CTS/issues/16 (Maybe not technically "up_axis" related.)

Perhaps having up_axis or units at all is a "bug" in the specification! But you need units to deal with precision, and up_axis I think lets authors work as they like. If an application distinguishes between external referencing and internal referencing it's bound to be difficult to maintain and full of mistakes (or more likely just not implement external referencing and so hold the entire ecosystem back) so at the end of the day everything-is-external and up_axis matters, and it's better in <asset> than if it only appeared as a child of <COLLADA>.

There are 3 layers of convenience:

1) The resource supplier's layer. Here up_axis is for them. And it's not just dinky applications. This can be a big database like Wikipedia that generates documents like dynamic HTML. Having up_axis only at the document level would make their task a 3-D management one instead of simply text-substitution.

2) The visual "engine" layer. Here clients have to actually crunch the content of the documents. This should not be an impossible task for them, or it will be difficult to implement. So let's not make this too inconvenient, but it's secondary to layer 1.

3) The content developer layer. Here clients provide editing facilities to end-users. It would be nice if their job could be made easier, but they have to get in line behind layers 2 and 1.

The up_axis and units specification is for 1 to use. For 2 to consume. And for 3 to undo the work of 2 if it does not work directly with the document model.

mbarnes-sb commented 7 years ago

I disagree that it's a bug in the data model. The spec is clear that unit applies to all spatial measurements and up_axis applies to all geometric data in scope.

I agree that not all asset child elements make sense to all elements that can parent an asset element. Consider that extra can have an asset element too, making the asset data model very extensible, by design.

Imagine a purely asset-centric database, and supporting this schema, from which a client can retrieve only assets and retrieve them directly (e.g. geometry, camera, light). The asset metadata that may be present applies to each of them in isolation, if meaningful, and a client must compose them to suit its purpose ... i.e. to compose a visual scene.

Imagine another client that composes many disparate assets into a single XML document and bakes all the different asset units and orientations into a single unit and up_axis associated with that document's COLLADA element. Imagine too that the client doesn't bake that asset metadata while still producing a single document. Both are valid and equal.

The XML document is merely an artifact of the solution domain, a container of one or more assets. The COLLADA element is isomorphic with the XML document, as an asset, but otherwise has no special place in the asset data model.

The design intention is that all assets are treated uniformly and lending themselves to recursive solutions (implementations).

I won't argue that existing implementations only support this at the COLLADA (i.e. document) asset level and that it's most noticeable in support of external references (instances). Single document (file) 3D tools are what we've been trying to evolve away from (for decades) with limited success.

recp commented 7 years ago

Imagine a purely asset-centric database, and supporting this schema, from which a client can retrieve only assets and retrieve them directly (e.g. geometry, camera, light). The asset metadata that may be present applies to each of them in isolation, if meaningful, and a client must compose them to suit its purpose ... i.e. to compose a visual scene.

Imagine another client that composes many disparate assets into a single XML document and bakes all the different asset units and orientations into a single unit and up_axis associated with that document's COLLADA element. Imagine too that the client doesn't bake that asset metadata while still producing a single document. Both are valid and equal.

Actually I'm working on asset-database and AssetKit is one of sub module/library to load/export 3D assets (full document or partial maybe), some other tools e.g. Blender may use AssetKit to full support COLLADA 1.4, 1.5+ and glTF after I finished initial version.

It seems I have to (because AssetKit will full support COLLADA) process up_axis when it present, okay, I'm considering to add extra rotation when current element->up_axis != asset(instance, node, geometry, or external...)->up_Axis. if processing asset metadata is not required and it is valid then this should be optional, if users want to change the default behavior then it's up to them, I'll add options here: https://github.com/recp/assetkit/blob/master/include/ak-options.h#L15

I may add this rotation to <extra> or new element (at runtime), this will separate fixup rotation and original node transforms, but I'm not sure for now

RemiArnaud commented 7 years ago

A Collada document has to be compliant, and therefore has a COLLADA container that has an asset and an optional unit and up-axis. So there is no problem for referencing external assets that have a different up-axis.

You can reference an element inside another collada document, and that document would be valid and have a up-axis in the COLLADA container.

I can imagine an application that returns elements from a collada document, that's a simple Xquery. But that would not be a valid Collada documents, and therefore not covered in the spec discussed here.

m-7761 commented 7 years ago

I don't understand Remi. An "element returned from a document" is a window into a document. And documents can be composites generated on the fly, like this webpage we are using right now.

You wouldn't tell this webpage that every subsection must hold to something about the topmost parent container, and the entire idea of "assets" is that they are modular and distinct from their context. That's what makes them an asset and not the document itself the asset-or-only-asset.

RemiArnaud commented 7 years ago

What you are describing here is outside the realm of the specification, which describes a collada document. Nothing prevent you from creating a document on the fly, but it has to be a complete valid collada document If you are concerned by the specification.

Taking elements outside of this context is an interresting concept, but it is not covered by the collada specification. It's a nice discussion to have, but wanting to validate this usage with the specification is not super relevant.

m-7761 commented 7 years ago

@Remi I think there may be a misunderstanding. You suggested XQuery which I'm unfamiliar with. It may only be a database draped over an XML file. But in the normal context of processing HTML like documents, there are many queries, like a search for an xs:ID that are context aware, and those are materially the same as something that might return a snippet (whether the client has the full context or is decomposing elements) and it does not change the dynamic. (Document aware queries do the same things.)

recp commented 7 years ago

I've implemented <asset> and it's members e.g. <up_axis> existence as recursively in elements, now up_axis in a <node> or <geometry> or other instances causes extra rotation if the up_axes are not same. Maybe no-one implemented this or uses up_axis like this, it is up to user, DCC tools now.

<!-- the document is Z_UP -->
<node> 
    <!-- the document is Y_UP -->
    <instance_geometry url="http://127.0.0.1/duck.dae#duckMesh" />
</node>

I wish I had not worked on this but I had to for external documents which may have different up_axis. I can't modify the external document because some other dae may use it, and I don't want to duplicate it. It loads external document as COLLADA document, it is not actually just an xquery, but it is still need to be fixed because they have different up axis

Let me give another situation that makes up_axis meaningful in <geometry> :

I'll implement glTF too and will create an extension for COLLADA (if khronos will not do it before me), I like the <technique> element which makes COLLADA powerful, extensible and generic container of anything

<geometry id="Suzanne-mesh" name="Suzanne">
    <asset>
        <up_axis>Y_UP</up_axis>
    </asset>
    <mesh>
         <source id="mesh-data">
            <technique profile="gltf">
                <gltf type="binary" url="gtlf-mesh.bin" />
            </technique>
        </source>
        <vertices id="mesh-vertices">
            <input semantic="POSITION" source="#mesh-data"/>
        </vertices>
        <triangles count="...">
            <input semantic="VERTEX" source="#mesh-vertices" offset="0"/>
            <input semantic="NORMAL" source="#mesh-data"     offset="0"/>
            <p></p>
        </triangles>
    </mesh>
</geometry>

AFAIK, glTF uses Y_UP and meters only. A <node> doesn't has to know it is glTF or other format. up_axis in geometry will allow us to identify actual UP axis of the specific technique.

I hope I'm not in wrong path, if I'm then any advices are welcome!

Otherwise everything looks fine for now (probably with some bugs) and we can close this issue

mbarnes-sb commented 7 years ago

@recp Nice work. There are some required elements missing in order to pass schema validation e.g. created and modified. Check with a validating XML parser to catch any oversights.

recp commented 7 years ago

@mbarnes-sb thanks! I have just realized that created and modified are required. Actually it is good for me because if user tries to fix up_axis again for same asset, I can ignore it if modified datetimes are same, that is good! In my asset type, all members are pointer except these dates. If the asset don't have a member it inherits from parent asset. Now created and modified are not inheritable between asset[s], actually it is true for up_axis too because it has default value.

I may add validation utils after full implementation

Thank you for your help and valuable comments, I think it is time to close this