Open Game Engine Exchange (OpenGEX)

Comparison of OpenGEX, Collada, and glTF

The following table compares many of the important capabilities and features of OpenGEX 2.0, Collada 1.5, and glTF 2.0 based on their official specifications without extensions. Many less important features, as well as any differences in the underlying data languages used by each format, have been omitted.

Note that although glTF is intended primarily to be a run-time format, whereas OpenGEX and Collada were designed primarily to be pipeline formats, it is included here because many people see glTF as a viable pipeline format.

The comments listed for each format are each preceded by a color-coded label indicating the severity of any problems that may exist. Green means that the feature is well supported and no significant problems are expected. Orange means that there are minor problems, but they are probably low impact and easy to handle. Red means that there are major problems that may prevent use of the format in some cases. Black is reserved for severe flaws that are very likely to make the format unusable in almost all cases that depend on the particular feature working correctly.

Capability / Feature OpenGEX 2.0 Collada 1.5 glTF 2.0 NIF Morrowind .osg 
Hierarchical node relationships
Supported
The node hierarchy is inherent in the scene data. Child nodes are contained within the data belonging to their parent nodes.
Supported
The node hierarchy is inherent in the scene data. Child nodes are contained within the data belonging to their parent nodes.
Minor problems
The data contains a flat list of nodes, and each one explicitly references its child nodes. It is possible for a file to be broken because it contains relationships that do not form strict tree structures. A reader must be able to detect the presence of illegal graph structures that may even include cycles.
Minor problems
The data contains a flat list of nodes, and each one explicitly references its child nodes. It is possible for a file to be broken because it contains relationships that do not form strict tree structures. A reader must be able to detect the presence of illegal graph structures that may even include cycles.
Supported
The node hierarchy is inherent in the scene data. Child nodes are contained within the data belonging to their parent nodes.
Object / pivot transforms
Supported
Node transforms are separated into distinct components, where one applies to the node and all of its child nodes, and the other applies only to the node's object, enabling local pivot transforms.
Not supported
Object-only transforms are not supported. Pivot transform can be implemented only through hacks, and they don't work very well. For example, many writers include pivot transforms by creating extra child nodes.
Not supported
Object-only transforms are not supported. Pivot transform can be implemented only through hacks, and they don't work very well.
Supported
Both object-only and node transforms are supported.
Supported
Both object-only and node transforms are supported.
Object instancing
Supported
The same object can be instanced by multiple nodes.
Supported
The same object can be instanced by multiple nodes.
Supported
The same object can be instanced by multiple nodes.
Supported
The same object can be instanced by multiple nodes, but the runtime loader does not currently take advantage of this.
Supported
The same object can be instanced by multiple nodes.
Per-instance material binding
Supported
Different sets of materials can be applied to separate instances of the same object.
Supported
Different sets of materials can be applied to separate instances of the same object.
Not supported
Because the materials are specified in the object data, every instance of an object must use the same set of materials.
Supported
Different sets of materials can be applied to separate instances of the same object.
Supported
Different sets of materials can be applied to separate instances of the same object.
Skinning
Supported
Skeletal hierarchies and skinned meshes are fully supported.
Supported
Skeletal hierarchies and skinned meshes are fully supported.
Minor problems
Skeletal hierarchies and skinned meshes are supported, but the number of bone influences per vertex is limited to four. Also, nodes composing a skeleton do not include an indication that they are bones/joints.
Supported
Skeletal hierarchies and skinned meshes are fully supported, but their structure resembles the runtime implementation details, making an import or conversion cumbersome. Unlike in most other packages, bind matrices are stored per mesh and bone rather than per bone. This has to be handled by the runtime implementation, making an import or conversion into a prebuilt animation engine difficult or not possible. Nodes composing a skeleton do not include an indication that they are bones/joints.
Supported
Skeletal hierarchies and skinned meshes are fully supported, but their structure resembles the runtime implementation details, making an import or conversion cumbersome. Due to this issue and the lack of a common interface, such animations are not currently used by OpenMW's character controller. Nodes composing a skeleton do not include an indication that they are bones/joints.
Morphing
Supported
Relative and absolute morph targets are fully supported, and morph weights can be animated.
Supported
Relative and absolute morph targets are fully supported, and morph weights can be animated.
Minor problems
Only relative morph targets are supported. Morph weights can be animated.
Minor problems
Only relative morph targets are supported. Morph weights can be animated.
Supported
Relative and absolute morph targets are fully supported, and morph weights can be animated. The structure of morphed meshes resembles their runtime implementation details, which may make an import or conversion cumbersome.
Level of detail (LOD)
Supported
Multiple levels of detail for the same mesh are supported.
Not supported
Each mesh can have only one level of detail.
Not supported
Each mesh can have only one level of detail.
Supported
Multiple levels of detail for a sub-graph are supported.
Supported
Multiple levels of detail for a sub-graph are supported.
Multiple vertex attribute sets
Supported
Every vertex attribute, such as position, normal, color, and texcoord, can have values specified for an unlimited number of distinct sets.
Supported
Every vertex attribute, such as position, normal, color, and texcoord, can have values specified for an unlimited number of distinct sets.
Very limited
Two sets of texcoords can be specified for each vertex, but every other attribute can have only one value.
Supported
Eight sets of texcoords can be specified for each vertex, but every other attribute can have only one value.
Supported
Eight sets of texcoords can be specified for each vertex, but every other attribute can have only one value.
Index array properties
Supported
Index arrays can specify either a clockwise or counterclockwise winding direction, and they can specify a primitive restart index.
Not supported
All primitives must be wound counterclockwise, and primitive restart is not supported.
Not supported
All primitives must be wound counterclockwise, and primitive restart is not supported.
Not supported
All primitives must be wound counterclockwise, and primitive restart is not supported.
Not supported
All primitives must be wound counterclockwise, and primitive restart is not supported.
Lights
Supported
Infinite, point, and spot light nodes are supported.
Supported
Infinite, point, spot, and ambient light nodes are supported.
Not supported
Light nodes are not supported.
Not supported
Light nodes are supported, but they only affect the file that includes them which makes them relatively pointless.
Not supported
Light nodes are supported, but they are raw GL Lights rather than an in-scene representation that can be enabled/disabled based on proximity to nearby objects. Due to this they are not useful in OpenMW.
Attenuation model
Extensive support
Multiple attenuation functions are defined, and they can be combined to capture the precise configuration specified in the modeling application.
Limited support
Only the 1 / (ax² + bx + c) model is supported, and this has little practical utility because it never falls off to zero.
Not supported
Because light nodes are not supported, there is no attenuation model.
Not supported
Because light nodes are not supported, there is no attenuation model.
Not supported
Because light nodes are not supported, there is no attenuation model.
Cameras
Supported
Camera nodes are supported.
Supported
Camera nodes are supported.
Supported
Camera nodes are supported.
Supported
Camera nodes are supported, but do not serve a practical use.
Supported
Camera nodes are supported, but do not serve a practical use.
Capability / Feature OpenGEX 2.0 Collada 1.5 glTF 2.0
Keyframe animation with cubic interpolation
Supported
Cubic interpolation of keyframe data is fully supported, and the proper interpolation calculations are specified completely and accurately.
Underspecified
Cubic interpolation of keyframe data is fully supported, but the proper interpolation calculations are not specified completely. This has created a great deal of confusion, and many reader implementations handle the interpolation incorrectly as a result.
Serious design flaw
The intention is that cubic interpolation of keyframe data be fully supported. However, the specified interpolation calculations are incorrect, and as a result, keyframe animations cannot be faithfully reproduced in most cases.

A possible workaround is to sample the animation tracks at a high frame rate in the modeling application to approximate the true curves.
Supported
Cubic interpolation of keyframe data is supported, but has not been extensively researched and is not currently implemented in the OpenMW runtime.
Supported
Cubic interpolation of keyframe data is supported. Due to the lack of a standard interface, such animations can not currently be controlled by the OpenMW runtime e.g. the character controller.
Animation of rotation angles
Supported
Animation of rotation angles about an arbitrary axis, as well as specifically about the x, y, and z axes, is supported.
Supported
Animation of rotation angles about an arbitrary axis is supported.
Minor problems
All rotations must be expressed as quaternions, and slerp is required to interpolate them linearly. The specification does not comment on how cubic animation curves targeting angles should be handled.
Supported
XYZ axis and Quaternion animations are supported.
Supported
Various animation types are supported.
Tension-continuity-bias (TCB) animation curves
Supported
TCB animation curves are fully supported and completely specified.
Not supported
TCB animation curves are not supported.
Not supported
TCB animation curves are not supported.
Supported
TCB animation curves are supported, but have not been extensively researched and are not currently implemented by OpenMW runtime.
Unknown
Unknown
Texture coordinate animation
Supported
Transforms applied to texture maps can be animated.
Supported
Transforms applied to texture maps can be animated.
Not supported
Texture coordinate animation is not supported.
Supported
Transforms applied to texture maps can be animated.
Supported
Transforms applied to texture maps can be animated.
Multiple animation clips
Supported
Multiple animations clips in the same file are supported.
Supported
Multiple animations clips in the same file are supported.
Supported
Multiple animations clips in the same file are supported.
Supported
Multiple animations clips in the same file are supported.
Supported
Multiple animations clips in the same file are supported.
Conventional materials
Supported
Colors and textures can be specified for common material attributes such as diffuse, specular, emission, and opacity. Normal maps are also supported.
Supported
Colors and textures can be specified for common material attributes such as diffuse, specular, emission, and opacity. Normal maps are also supported.
Indirectly supported
Conventional material attributes can usually be inferred from PBR properties.
Supported
Colors can be specified for common material attributes such as diffuse, specular, emission, and opacity. Normal maps and a number of other multitexturing features are supported.
Supported
Colors can be specified for common material attributes such as diffuse, specular, emission, and opacity. The interpretation of textures depends entirely on the runtime.
Physically based rendering (PBR) materials
Not supported
Properties of physically based materials cannot be specified.
Not supported
Properties of physically based materials cannot be specified.
Supported
Metalness and roughness can be specified as constant values or textures.
Not supported
Properties of physically based materials cannot be specified, although if a standard convention was established then the user data field could be used.
Not supported
Properties of physically based materials cannot be specified, although if a standard convention was established then the user data field or an extension to the format could be used.
Configurable distance, angle, and time units
Supported
Global scale factors can be specified for all distance values, angle values, and time values.
Partially supported
A global scale factor can be specified for all distance values, but not angle values or time values.
Not supported
Distance values, angle values, and time values must be specified as meters, radians, and seconds.
Not supported
Distance values, angle values, and time values must be specified as game units, radians, and seconds.
Not supported
Distance values, angle values, and time values must be specified as game units, radians, and seconds.
Configurable world-space up direction
Supported
The world-space up direction can be specified as +y or +z.
Supported
The world-space up direction can be specified as +y or +z.
Not supported
The world-space up direction can only be +y.
Not supported
The world-space up direction is entirely up to the conventions of the user and the runtime.
Not supported
The world-space up direction is entirely up to the conventions of the user and the runtime.
Forward direction specification
Supported
The forward direction for models such as characters or vehicles can be specified as ±x, ±y, or ±z.
Not supported
A forward direction cannot be specified.
Not supported
A forward direction cannot be specified.
Not supported
A forward direction cannot be specified.
Not supported
A forward direction cannot be specified.
Binary format
Not supported
Data is always stored in a text-only format.
Not supported
Data is always stored in a text-only format.
Supported
Data can be stored in a binary format for smaller size and faster processing.
Not supported
Data is stored in a record-based binary format for which the NifSkope editor exists.
Supported
Data can be stored in a binary format for smaller size and faster processing.
Export from Maya
Supported
There is an official OpenGEX exporter for Maya.
Supported
There is an official Collada exporter for Maya.
Not supported
No official exporter exists, and there is currently no way to directly export from Maya.
Not supported
Unknown.
Not supported
Unknown.
Export from 3ds max
Supported
There is an official OpenGEX exporter for 3ds max.
Supported
There is an official Collada exporter for 3ds max.
Not supported
No official exporter exists, and there is currently no way to directly export from 3ds max.
Not supported
Unknown.
Not supported
Unknown.
Export from Blender
Supported
There is an official OpenGEX exporter for Blender.
Supported
A Collada exporter is built into Blender.
Supported
There is an official glTF exporter for Blender. Note that cubic Bézier animation curves are not exported directly, but are sampled at the scene's frame rate.
Supported
A NIF exporter for Blender exists, but there is some work remaining to update it for wewer versions of Blender.

Many aspects of the NIF format are unknown, unused or heavily version-specific.
Supported
An OSG exporter for Blender exists. Given the immense amount of features inbuilt to the OSG format which basically match all the capabilities of the OSG runtime, many of which have no equivalent in Blender, the exporter can be considered incomplete and always in development.

Static scene comparison of OpenGEX and Collada

Below are two examples that show side-by-side comparisons of real OpenGEX and Collada files for a static scene and an animated scene.

In the first example, a simple scene containing two instances of the same box was created in 3D Studio Max 2014 and exported to the files shown below. The box has a simple material, and there is no animation.

OpenGEX

This is the file written by the OpenGEX export plugin. Most of the floating-point data is written as hex literals to ensure exact bit-for-bit reconstruction when the file is imported into another program. (Lossless data transmission is not guaranteed when floating-point data is converted to decimal.)

Collada

This is the same scene written to the Collada format. The Autodesk Collada exporter did not correctly export the boxes as two instances of the same object, but instead as two separate boxes with independent geometric data, so this file has been hand-edited to reflect the correct scene structure for an apples-to-apples comparison. Some extraneous information (such as a black emission color) has also been removed so that the data content is the same in both files.

Metric (key = "distance") {float {1}}
Metric (key = "angle") {float {1}}
Metric (key = "time") {float {1}}
Metric (key = "up") {string {"z"}}

GeometryNode $node1
{
	Name {string {"Box001"}}
	ObjectRef {ref {$geometry1}}
	MaterialRef {ref {$material1}}

	Transform
	{
		float[16]
		{
			{0x3F800000, 0x00000000, 0x00000000, 0x00000000,		// {1, 0, 0, 0
			 0x00000000, 0x3F800000, 0x00000000, 0x00000000,		//  0, 1, 0, 0
			 0x00000000, 0x00000000, 0x3F800000, 0x00000000,		//  0, 0, 1, 0
			 0xBEF33B00, 0x411804DE, 0x00000000, 0x3F800000}		//  -0.47506, 9.50119, 0, 1}
		}
	}
}

GeometryNode $node2
{
	Name {string {"Box002"}}
	ObjectRef {ref {$geometry1}}
	MaterialRef {ref {$material1}}

	Transform
	{
		float[16]
		{
			{0x3F800000, 0x00000000, 0x00000000, 0x00000000,		// {1, 0, 0, 0
			 0x00000000, 0x3F800000, 0x00000000, 0x00000000,		//  0, 1, 0, 0
			 0x00000000, 0x00000000, 0x3F800000, 0x00000000,		//  0, 0, 1, 0
			 0x43041438, 0x411804DE, 0x00000000, 0x3F800000}		//  132.079, 9.50119, 0, 1}
		}
	}
}

GeometryObject $geometry1		// Box001, Box002
{
	Mesh (primitive = "triangles")
	{
		VertexArray (attrib = "position")
		{
			float[3]		// 24
			{
				{0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928},
				{0xC2501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928},
				{0x42501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928}
			}
		}

		VertexArray (attrib = "normal")
		{
			float[3]		// 24
			{
				{0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000},
				{0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x80000000, 0xBF800000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000},
				{0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x80000000, 0x3F800000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}
			}
		}

		VertexArray (attrib = "texcoord")
		{
			float[2]		// 24
			{
				{0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000},
				{0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000},
				{0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}
			}
		}

		IndexArray
		{
			unsigned_int32[3]		// 12
			{
				{0, 1, 2}, {2, 3, 0}, {4, 5, 6}, {6, 7, 4}, {8, 9, 10}, {10, 11, 8}, {12, 13, 14}, {14, 15, 12}, {16, 17, 18}, {18, 19, 16}, {20, 21, 22}, {22, 23, 20}
			}
		}
	}
}

Material $material1
{
	Name {string {"03 - Default"}}

	Color (attrib = "diffuse") {float[3] {{0.588235, 0.588235, 0.588235}}}
	Texture (attrib = "diffuse")
	{
		string {"texture/Concrete.tga"}
	}
}
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
	<asset>
		<unit meter="1.000000" name="centimeter"></unit>
		<up_axis>Z_UP</up_axis>
	</asset>
	<library_images>
		<image id="Map #0-image" name="Map #0">
			<init_from>file://texture\Concrete.tga</init_from>
		</image>
	</library_images>
	<library_materials>
		<material id="_03 - Default" name="_03 - Default">
			<instance_effect url="#_03 - Default-fx"/>
		</material>
	</library_materials>
	<library_effects>
		<effect id="_03 - Default-fx" name="_03 - Default">
			<profile_COMMON>
				<technique sid="standard">
					<phong>
						<ambient>
							<color sid="ambient">0.588235 0.588235 0.588235 1.000000</color>
						</ambient>
						<diffuse>
							<texture texture="Map #0-image" texcoord="CHANNEL0"></texture>
						</diffuse>
					</phong>
				</technique>
			</profile_COMMON>
		</effect>
	</library_effects>
	<library_geometries>
		<geometry id="Box001-lib" name="Box001Mesh">
			<mesh>
				<source id="Box001-POSITION">
					<float_array id="Box001-POSITION-array" count="24">
						-52.019001 -51.068886 0.000000 52.019001 -51.068886 0.000000 -52.019001 51.068886 0.000000 52.019001 51.068886 0.000000
						-52.019001 -51.068886 93.111633 52.019001 -51.068886 93.111633 -52.019001 51.068886 93.111633 52.019001 51.068886 93.111633
					</float_array>
					<technique_common>
						<accessor source="#Box001-POSITION-array" count="8" stride="3">
							<param name="X" type="float"/>
							<param name="Y" type="float"/>
							<param name="Z" type="float"/>
						</accessor>
					</technique_common>
				</source>
				<source id="Box001-Normal0">
					<float_array id="Box001-Normal0-array" count="108">
						0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000
						0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000
						1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000
						0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000
						-1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000
					</float_array>
					<technique_common>
						<accessor source="#Box001-Normal0-array" count="36" stride="3">
							<param name="X" type="float"/>
							<param name="Y" type="float"/>
							<param name="Z" type="float"/>
						</accessor>
					</technique_common>
				</source>
				<source id="Box001-UV0">
					<float_array id="Box001-UV0-array" count="48">
						1.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000
					</float_array>
					<technique_common>
						<accessor source="#Box001-UV0-array" count="24" stride="2">
							<param name="S" type="float"/>
							<param name="T" type="float"/>
						</accessor>
					</technique_common>
				</source>
				<vertices id="Box001-VERTEX">
					<input semantic="POSITION" source="#Box001-POSITION"/>
				</vertices>
				<triangles count="12" material="_03 - Default">
					<input semantic="VERTEX" offset="0" source="#Box001-VERTEX"/>
					<input semantic="NORMAL" offset="1" source="#Box001-Normal0"/>
					<input semantic="TEXCOORD" offset="2" set="0" source="#Box001-UV0"/>
					<p>
						1 0 1 0 1 0 3 2 3 0 3 0 2 4 2 3 5 3 7 6 7 6 7 6 4 8 4 7 9 7 4 10 4 5 11 5 5 12 11 4 13 10 0 14 8 5 15 11 0 16 8 1 17 9 7 18 15 5 19 14
						1 20 12 7 21 15 1 22 12 3 23 13 6 24 19 7 25 18 3 26 16 6 27 19 3 28 16 2 29 17 4 30 23 6 31 22 2 32 20 4 33 23 2 34 20 0 35 21
					</p>
				</triangles>
			</mesh>
		</geometry>
	</library_geometries>
	<library_visual_scenes>
		<visual_scene id="Test" name="Test">
			<node name="Box001" id="Box001" sid="Box001">
				<matrix sid="matrix">
					1.000000 0.000000 0.000000 -0.475060
					0.000000 1.000000 0.000000 9.501188
					0.000000 0.000000 1.000000 0.000000
					0.000000 0.000000 0.000000 1.000000
				</matrix>
				<instance_geometry url="#Box001-lib">
					<bind_material>
						<technique_common>
							<instance_material symbol="_03 - Default" target="#_03 - Default"/>
						</technique_common>
					</bind_material>
				</instance_geometry>
			</node>
			<node name="Box002" id="Box002" sid="Box002">
				<matrix sid="matrix">
					1.000000 0.000000 0.000000 132.078979
					0.000000 1.000000 0.000000 9.501188
					0.000000 0.000000 1.000000 0.000000
					0.000000 0.000000 0.000000 1.000000
				</matrix>
				<instance_geometry url="#Box001-lib">
					<bind_material>
						<technique_common>
							<instance_material symbol="_03 - Default" target="#_03 - Default"/>
						</technique_common>
					</bind_material>
				</instance_geometry>
			</node>
		</visual_scene>
	</library_visual_scenes>
	<scene>
		<instance_visual_scene url="#Test"></instance_visual_scene>
	</scene>
</COLLADA>

Animated scene comparison of OpenGEX and Collada

In the second example, a scene containing a single animated box was created in 3D Studio Max 2014 and exported to the files shown below. The animation moves the box along the x axis while rotating it, and then moves the box along the z axis.

OpenGEX

This is the file written by the OpenGEX export plugin. Note that animation data is stored together with the items that are animated, as opposed to a separate location.

Collada

This is the same scene written to the Collada format. Even though it is considerably longer than the OpenGEX file, it contains exactly the same information. The Autodesk Collada exporter included several unnecessary animation tracks that contained no actual motion, and these have been removed to provide an apples-to-apples comparison.

Metric (key = "distance") {float {1}}
Metric (key = "angle") {float {1}}
Metric (key = "time") {float {1}}
Metric (key = "up") {string {"z"}}

GeometryNode $node1
{
	Name {string {"Box001"}}
	ObjectRef {ref {$geometry1}}
	MaterialRef {ref {$material1}}

	Translation %xpos (kind = "x")
	{
		float {0xBEF33B00}		// -0.47506
	}

	Translation %ypos (kind = "y")
	{
		float {0x41180000}		// 9.5
	}

	Translation %zpos (kind = "z")
	{
		float {0x00000000}		// 0
	}

	Rotation %zrot (kind = "z")
	{
		float {0x00000000}		// 0
	}

	Rotation %yrot (kind = "y")
	{
		float {0x80000000}		// -0
	}

	Rotation %xrot (kind = "x")
	{
		float {0x00000000}		// 0
	}

	Animation (begin = 0, end = 1)
	{
		Track (target = %xpos)
		{
			Time (curve = "bezier")
			{
				Key {float {0, 0.666667, 1}}
				Key (kind = "-control") {float {0, 0.444467, 0.8889}}
				Key (kind = "+control") {float {0.2222, 0.777767, 1}}
			}

			Value (curve = "bezier")
			{
				Key {float {-0.47506, 413.657, 413.657}}
				Key (kind = "-control") {float {-0.47506, 413.657, 413.657}}
				Key (kind = "+control") {float {-0.47506, 413.657, 413.657}}
			}
		}

		Track (target = %zpos)
		{
			Time (curve = "bezier")
			{
				Key {float {0, 0.666667, 1}}
				Key (kind = "-control") {float {0, 0.444467, 0.8889}}
				Key (kind = "+control") {float {0.2222, 0.777767, 1}}
			}

			Value (curve = "bezier")
			{
				Key {float {0, 0, 158.682}}
				Key (kind = "-control") {float {0, 0, 158.682}}
				Key (kind = "+control") {float {0, 0, 158.682}}
			}
		}

		Track (target = %zrot)
		{
			Time (curve = "bezier")
			{
				Key {float {0, 0.666667, 1}}
				Key (kind = "-control") {float {0, 0.444467, 0.8889}}
				Key (kind = "+control") {float {0.2222, 0.777767, 1}}
			}

			Value (curve = "bezier")
			{
				Key {float {0, 3.14582, 3.14582}}
				Key (kind = "-control") {float {0, 3.14582, 3.14582}}
				Key (kind = "+control") {float {0, 3.14582, 3.14582}}
			}
		}
	}
}

GeometryObject $geometry1		// Box001
{
	Mesh (primitive = "triangles")
	{
		VertexArray (attrib = "position")
		{
			float[3]		// 24
			{
				{0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928},
				{0xC2501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928},
				{0x42501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928}
			}
		}

		VertexArray (attrib = "normal")
		{
			float[3]		// 24
			{
				{0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000},
				{0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x80000000, 0xBF800000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000},
				{0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x80000000, 0x3F800000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}
			}
		}

		VertexArray (attrib = "texcoord")
		{
			float[2]		// 24
			{
				{0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000},
				{0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000},
				{0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}
			}
		}

		IndexArray
		{
			unsigned_int32[3]		// 12
			{
				{0, 1, 2}, {2, 3, 0}, {4, 5, 6}, {6, 7, 4}, {8, 9, 10}, {10, 11, 8}, {12, 13, 14}, {14, 15, 12}, {16, 17, 18}, {18, 19, 16}, {20, 21, 22}, {22, 23, 20}
			}
		}
	}
}

Material $material1
{
	Name {string {"03 - Default"}}

	Color (attrib = "diffuse") {float[3] {{0.588235, 0.588235, 0.588235}}}
	Texture (attrib = "diffuse")
	{
		string {"texture/Concrete.tga"}
	}
}
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
	<asset>
		<unit meter="1.000000" name="centimeter"></unit>
		<up_axis>Z_UP</up_axis>
	</asset>
	<library_images>
		<image id="Map #0-image" name="Map #0">
			<init_from>file://texture\Concrete.tga</init_from>
		</image>
	</library_images>
	<library_materials>
		<material id="_03 - Default" name="_03 - Default">
			<instance_effect url="#_03 - Default-fx"/>
		</material>
	</library_materials>
	<library_effects>
		<effect id="_03 - Default-fx" name="_03 - Default">
			<profile_COMMON>
				<technique sid="standard">
					<phong>
						<ambient>
							<color sid="ambient">0.588235 0.588235 0.588235 1.000000</color>
						</ambient>
						<diffuse>
							<texture texture="Map #0-image" texcoord="CHANNEL0"></texture>
						</diffuse>
					</phong>
				</technique>
			</profile_COMMON>
		</effect>
	</library_effects>
	<library_geometries>
		<geometry id="Box001-lib" name="Box001Mesh">
			<mesh>
				<source id="Box001-POSITION">
					<float_array id="Box001-POSITION-array" count="24">
						-52.019001 -51.068886 0.000000 52.019001 -51.068886 0.000000 -52.019001 51.068886 0.000000 52.019001 51.068886 0.000000
						-52.019001 -51.068886 93.111633 52.019001 -51.068886 93.111633 -52.019001 51.068886 93.111633 52.019001 51.068886 93.111633
					</float_array>
					<technique_common>
						<accessor source="#Box001-POSITION-array" count="8" stride="3">
							<param name="X" type="float"/>
							<param name="Y" type="float"/>
							<param name="Z" type="float"/>
						</accessor>
					</technique_common>
				</source>
				<source id="Box001-Normal0">
					<float_array id="Box001-Normal0-array" count="108">
						0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000
						0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000
						0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000
						0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000
						1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000
						0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000
						0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000
						-1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000
					</float_array>
					<technique_common>
						<accessor source="#Box001-Normal0-array" count="36" stride="3">
							<param name="X" type="float"/>
							<param name="Y" type="float"/>
							<param name="Z" type="float"/>
						</accessor>
					</technique_common>
				</source>
				<source id="Box001-UV0">
					<float_array id="Box001-UV0-array" count="48">
						1.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000
						0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000
					</float_array>
					<technique_common>
						<accessor source="#Box001-UV0-array" count="24" stride="2">
							<param name="S" type="float"/>
							<param name="T" type="float"/>
						</accessor>
					</technique_common>
				</source>
				<vertices id="Box001-VERTEX">
					<input semantic="POSITION" source="#Box001-POSITION"/>
				</vertices>
				<triangles count="12" material="_03 - Default">
					<input semantic="VERTEX" offset="0" source="#Box001-VERTEX"/>
					<input semantic="NORMAL" offset="1" source="#Box001-Normal0"/>
					<input semantic="TEXCOORD" offset="2" set="0" source="#Box001-UV0"/>
					<p>
						1 0 1 0 1 0 3 2 3 0 3 0 2 4 2 3 5 3 7 6 7 6 7 6 4 8 4 7 9 7 4 10 4 5 11 5 5 12 11 4 13 10 0 14 8 5 15 11 0 16 8 1 17 9 7
						18 15 5 19 14 1 20 12 7 21 15 1 22 12 3 23 13 6 24 19 7 25 18 3 26 16 6 27 19 3 28 16 2 29 17 4 30 23 6 31 22 2 32 20 4 33 23 2 34 20 0 35 21
					</p>
				</triangles>
			</mesh>
		</geometry>
	</library_geometries>
	<library_animations>
		<animation id="Box001-anim" name="Box001"></animation>
		<animation>
			<source id="Box001-translate.X-input">
				<float_array id="Box001-translate.X-input-array" count="3">0.000000 0.666667 1.000000</float_array>
				<technique_common>
					<accessor source="#Box001-translate.X-input-array" count="3" stride="1">
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-translate.X-output">
				<float_array id="Box001-translate.X-output-array" count="3">-0.475060 413.657227 413.657227</float_array>
				<technique_common>
					<accessor source="#Box001-translate.X-output-array" count="3" stride="1">
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-translate.X-interpolation">
				<Name_array id="Box001-translate.X-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
				<technique_common>
					<accessor source="#Box001-translate.X-interpolation-array" count="3" stride="1">
						<param type="name"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-translate.X-intan">
				<float_array id="Box001-translate.X-intan-array" count="6">0.000000 0.000000 0.444511 413.657227 0.888922 413.657227</float_array>
				<technique_common>
					<accessor source="#Box001-translate.X-intan-array" count="3" stride="2">
						<param type="float"></param>
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-translate.X-outtan">
				<float_array id="Box001-translate.X-outtan-array" count="6">0.222156 -0.475060 0.777744 413.657227 0.000000 0.000000</float_array>
				<technique_common>
					<accessor source="#Box001-translate.X-outtan-array" count="3" stride="2">
						<param type="float"></param>
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<sampler id="Box001-translate.X">
				<input semantic="INPUT" source="#Box001-translate.X-input"></input>
				<input semantic="OUTPUT" source="#Box001-translate.X-output"></input>
				<input semantic="INTERPOLATION" source="#Box001-translate.X-interpolation"></input>
				<input semantic="IN_TANGENT" source="#Box001-translate.X-intan"></input>
				<input semantic="OUT_TANGENT" source="#Box001-translate.X-outtan"></input>
			</sampler>
			<channel source="#Box001-translate.X" target="Box001/translate.X"></channel>
		</animation>
		<animation>
			<source id="Box001-translate.Z-input">
				<float_array id="Box001-translate.Z-input-array" count="3">0.000000 0.666667 1.000000</float_array>
				<technique_common>
					<accessor source="#Box001-translate.Z-input-array" count="3" stride="1">
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-translate.Z-output">
				<float_array id="Box001-translate.Z-output-array" count="3">0.000000 0.000000 158.681717</float_array>
				<technique_common>
					<accessor source="#Box001-translate.Z-output-array" count="3" stride="1">
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-translate.Z-interpolation">
				<Name_array id="Box001-translate.Z-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
				<technique_common>
					<accessor source="#Box001-translate.Z-interpolation-array" count="3" stride="1">
						<param type="name"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-translate.Z-intan">
				<float_array id="Box001-translate.Z-intan-array" count="6">0.000000 0.000000 0.444511 0.000000 0.888922 158.681717</float_array>
				<technique_common>
					<accessor source="#Box001-translate.Z-intan-array" count="3" stride="2">
						<param type="float"></param>
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-translate.Z-outtan">
				<float_array id="Box001-translate.Z-outtan-array" count="6">0.222156 0.000000 0.777744 0.000000 0.000000 0.000000</float_array>
				<technique_common>
					<accessor source="#Box001-translate.Z-outtan-array" count="3" stride="2">
						<param type="float"></param>
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<sampler id="Box001-translate.Z">
				<input semantic="INPUT" source="#Box001-translate.Z-input"></input>
				<input semantic="OUTPUT" source="#Box001-translate.Z-output"></input>
				<input semantic="INTERPOLATION" source="#Box001-translate.Z-interpolation"></input>
				<input semantic="IN_TANGENT" source="#Box001-translate.Z-intan"></input>
				<input semantic="OUT_TANGENT" source="#Box001-translate.Z-outtan"></input>
			</sampler>
			<channel source="#Box001-translate.Z" target="Box001/translate.Z"></channel>
		</animation>
		<animation>
			<source id="Box001-rotateZ.ANGLE-input">
				<float_array id="Box001-rotateZ.ANGLE-input-array" count="3">0.000000 0.666667 1.000000</float_array>
				<technique_common>
					<accessor source="#Box001-rotateZ.ANGLE-input-array" count="3" stride="1">
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-rotateZ.ANGLE-output">
				<float_array id="Box001-rotateZ.ANGLE-output-array" count="3">0.000000 180.242096 180.242096</float_array>
				<technique_common>
					<accessor source="#Box001-rotateZ.ANGLE-output-array" count="3" stride="1">
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-rotateZ.ANGLE-interpolation">
				<Name_array id="Box001-rotateZ.ANGLE-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
				<technique_common>
					<accessor source="#Box001-rotateZ.ANGLE-interpolation-array" count="3" stride="1">
						<param type="name"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-rotateZ.ANGLE-intan">
				<float_array id="Box001-rotateZ.ANGLE-intan-array" count="6">0.000000 0.000000 0.444511 180.242096 0.888922 180.242096</float_array>
				<technique_common>
					<accessor source="#Box001-rotateZ.ANGLE-intan-array" count="3" stride="2">
						<param type="float"></param>
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<source id="Box001-rotateZ.ANGLE-outtan">
				<float_array id="Box001-rotateZ.ANGLE-outtan-array" count="6">0.222156 0.000000 0.777744 180.242096 0.000000 0.000000</float_array>
				<technique_common>
					<accessor source="#Box001-rotateZ.ANGLE-outtan-array" count="3" stride="2">
						<param type="float"></param>
						<param type="float"></param>
					</accessor>
				</technique_common>
			</source>
			<sampler id="Box001-rotateZ.ANGLE">
				<input semantic="INPUT" source="#Box001-rotateZ.ANGLE-input"></input>
				<input semantic="OUTPUT" source="#Box001-rotateZ.ANGLE-output"></input>
				<input semantic="INTERPOLATION" source="#Box001-rotateZ.ANGLE-interpolation"></input>
				<input semantic="IN_TANGENT" source="#Box001-rotateZ.ANGLE-intan"></input>
				<input semantic="OUT_TANGENT" source="#Box001-rotateZ.ANGLE-outtan"></input>
			</sampler>
			<channel source="#Box001-rotateZ.ANGLE" target="Box001/rotateZ.ANGLE"></channel>
		</animation>
	</library_animations>
	<library_visual_scenes>
		<visual_scene id="Test" name="Test">
			<node name="Box001" id="Box001" sid="Box001">
				<translate sid="translate">
					-0.475060 9.501188 0.000000
				</translate>
				<rotate sid="rotateZ">
					0 0 1 0.000000
				</rotate>
				<rotate sid="rotateY">
					0 1 0 0.000000
				</rotate>
				<rotate sid="rotateX">
					1 0 0 0.000000
				</rotate>
				<instance_geometry url="#Box001-lib">
					<bind_material>
						<technique_common>
							<instance_material symbol="_03 - Default" target="#_03 - Default"/>
						</technique_common>
					</bind_material>
				</instance_geometry>
			</node>
		</visual_scene>
	</library_visual_scenes>
	<scene>
		<instance_visual_scene url="#Test"></instance_visual_scene>
	</scene>
</COLLADA>