Status: Draft William Denniss Version: 1.0 Tank Software Revision: 22 March 2004 XML ODE Data Interchange Format - XODE Status of this Memo This document specifies a proposed standard for the ODE community. Distribution of this memo is unlimited. Copyright Notice Copyright (C) William Denniss (2004). Abstract This document describes an XML format which can be used as a common ODE storage and interchange format. 1 Introduction 1.1 About ODE Open Dynamics Engine (ODE) is a "free, industrial quality library for simulating articulated rigid body dynamics - for example ground vehicles, legged creatures, and moving objects in VR environments. It is fast, flexible, robust and platform independent, with advanced joints, contact with friction, and built-in collision detection". A typical ODE scene hierarchy consists of physics, collision and display objects. Physics and collision is typically handled by ODE with the graphics potentially using any number of display libraries (three dimensional or otherwise). This scene structure is commonly used in both graphical ODE editing applications, and software using ODE. 1.2 Purpose The goal of this standard is to provide a method of storing an ODE scene, representing the physics, collision objects and to do so in a generic, interoperable and extensible manner. It is not a generic physics scene notation, but rather is ODE specific so as to fully represent an ODE scene without compromise or addition. Like ODE, there is no binding to a particular display library, although it is possible to store display-specific (and any other) information though the use of extensions. 1.3 Requirements The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. An implementation is not compliant if it fails to satisfy one or more of the MUST or REQUIRED level requirements for the protocols it implements. An implementation that satisfies all the MUST or REQUIRED level and all the SHOULD level requirements for its protocols is said to be "unconditionally compliant"; one that satisfies all the MUST level requirements but not all the SHOULD level requirements for its protocols is said to be "conditionally compliant." 1.4 Terminology importer/parser/reader Code which can read the XODE format into some internal representation for manipulation, display or otherwise. exporter/writer Code that can write an XODE formatted file from some internal representation. collision system A mathematical engine which detects when two objects intersect and generates an appropriate response physics engine A mathematical engine that has set of physical rules for example gravity or friction that it applies to objects in it's system graphical engine A programming library used to display objects to the user, for example a 3D OpenGL scenegraph. world A container for physics body objects body A physics object with such properties as mass collision geom A geometry describing a shape that is used for collision group A collection of objects organised into a bag for organisational reasons. joint A relationship between two bodies that connects them together in some way. ODE object an object which exits in ode. For example body and geom container a collection of ODE objects element an identified component of a document, consisting of a start-tag, content and an end-tag attribute an element parameter consisting of a name and value. parent the containing container of an object child the contained object in a container ancestor a parent or parent of that parent (and so on) decendant a child or child of a child (and so on) 2 Elements The main elements of XODE share common properties (such as a name attribute) and are named XODE Objects. A subset of XODE Objects are XODE Containers which can contain other objects. All Objects may have a name attribute, which if present MUST be unique. They can also contain extension elements. 2.1 ODE Objects ODE objects are entities which have a direct meaning in ODE. These are: All ODE objects may contain a attribute which. If this attribute is not present, the transform of the objects parent is used. 2.1.1 Representation for the ODE body object (used in the physics engine). It is also added to its only ancestor on creation. ancestor on creation. It has the following properties (with examples): Attributes: enabled="false" gravitymode="1" Elements: (see below) The Mass element contains the bodies mass data. This data can consist of mass matricies, mass shapes, translations, rotations, total mass adjustments, and child mass objects (which are added to the parent). The order is important as the operations are applied in the same order they appear in the file. Note: If you combind several structs and/or shapes, the earlier ones may be overwritten by ODE and thus have no effect. Using a nested element ensures that they are added together. Listed below are the valid child elements of , can only appear in the order listed: 1. The mass 'struct'. All attributes and child elements are required. This data is typically fed into ODE's dMassSetParameters method. If the element is present, then the element can not be used for that mass. 2. Mass shapes Valid shapes are cylinder, sphere, box and cappedCylinder whose attributes are specified in section 2.1.2 The mass element can either have a 'density' or 'total' attribute which determines the relevent ODE method to use (if both are present, the 'density' is used in preference). The element is optional. If the element is present, then the element can not be used for that mass. 3. Used to rotate and translate the mass. See section 2.3 for more information on the transform element. 4. Sets the total mass. Typically ODE's dMassAdjust method is used for this operation 5. Child elements Lists mass data which will be added to this mass. Typically ODE's dMassAdd method is used for this operation. 2.1.2 Representation for geometry objects (used in the collision detection engine). It is usually attached to a body (as a child node) but this doesn't have to be the case if representing a static - immovable object (such as a wall). If has as an ancestor a , then it is added to its closest ancestor on creation. It is also added to its closest ancestor on creation. Geometry objects must contain an element that represents the shape of the geom and contains its values. Listed below are those elements and their expected attributes. In each case, the data type for values is a float with the exception of 'trimesh': sizex, sizey, sizez radius, length radius, length radius, length a, b, c, d length radius vertices, indices Examples: Geom Box: ... Geom Cylinder: ... The 'trimesh' shape is unique as a 3D mesh must be defined. The mesh is an indexed triangle array. The vertex data is stored as 'x', 'y', and 'z' attributes of the vertex '' element. The indicies of the triangles are stored as 'ia', 'ib', and 'ic' attributes of the element. Example: The vertex 'v' element may also contain a fourth attribute 'e' (short for extension). That element can contain any data. Unlike support of the element, support of this element is OPTIONAL and it should be used carefully. 2.1.3 Represents a joint in ODE. If a has as an ancestor a container then it is added to its closest ancestor on creation. Else, it is added to a joint group consisting of only itself. Joint objects must contain an element which represents the type of joint and stores the properties specific to that joint (such as the axes). Below is a list of valid joint types: "amotor" "ball" "fixed" "hinge" "hinge2" "slider" "universal" Joints link two bodies together. These body links can are defined by the and elements. Typically, a element will be a decendant of a . In such cases, that body can be linked simply by omitting the relevent link element. For example, if is the nearest ancestor, only needs to be defined. eg. Several joints may also define an anchor vector. These are ball, hinge, and hinge2. The ancor element has x, y and z attributes which is the vector, and 'absolute' which determines if this vector is relitive to the joint's parent node. Exmaple of the anchor vector element: Some joints have one or more axes which is defined like so: The number of axes per joint type is fixed at the following numbers: amotor 3 ball 0 fixed 0 hinge 1 hinge2 2 slider 1 universal 2 A joint MUST have the exact number of required axes. 2.2 Containers Containers are groups of ODE objects. Some of the containers have a representation within ODE itself, but not all. The containers are: Containers can store other containers and ODE objects. However there are restrictions on which containers can store what. For example, can only contain and it is the only container which can contain them. The legal content of each container is defined in it's subsection below. All containers (including ) can have the transform attribute. If they do not, then the transform object of that containers parent is used (in the case of , this is the origin). This transform is relative to its parent transform unless otherwise indicated (see section 2.3 for more information on the element) 2.2.1 The root node of the file of which there can only be one. It is both the only container for nodes and can contain nothing else. The version of XODE that is being used MUST be specified using the 'version' attribute. 2.2.2 In addition to its properties as a container, the element has a meaning in ODE. It must contain at least one element and can only contain elements. It is OPTIONAL that parsers actually create seperate World instances in ODE for each they encounter. Regardless, the XODE relationships including transforms MUST be adhered to. 2.2.3 Unlike the other containers, group has no actual meaning in ODE. This is also part of its usefulness as it can be used to structure data in a way which does not directly affect the ODE representation. Like all containers - child objects are transformed relitive to their parents. See section 2.3 for more details on transforms and which cases ODE handles the relationship. 2.2.3 Space acts similarly to except that it has a meaning in ODE for the storage of child containers and objects. It is OPTIONAL that parsers actually create seperate Space instances in ODE for each they encounter. Regardless, the XODE relationships including transforms MUST be adhered to. 2.2.4 Acts like except that it has a meaning in ODE for the storage of objects which are added to their closest joint group. 2.2.4 as a container acts similary to as it also has no meaning in ODE (that is as a container - it does have meaning as an object. 2.2.5 as a container acts similarly to except in the case of child elements as this relationship is defined by ODE. 2.3 Transform Attribute Transform are always relitive to the transform of the parent XODE object unless otherwise specified by setting the "absolute" attribute to 'true'. Some relationships in XODE do not exist in ODE itself, such as a Geom containing another Geom, or the Group construct altogether. In such cases - the importer must perform the matrix multipliucation manually. For example, if a world has a group and that group specifies a transform, and also contains a body - when that body is added to the ODE world - it must be multiplied by the transform of the group. Some relationships in XODE do however exist in ODE, for example a Body containing a child Geom. In these cases, ODE will maintain the transform, so they must not be multiplied by it's transform as well. In some complex cases - a Body may contain a group, which contains the geom. What happens in all cases is that the transforms must be calcuated manually from the last ODE relationship. In this case, to get the resulting transform of the Geom, the transform of its parent group would be multiplied by that of the Geom. All parent nodes of Body can be ignored as ODE will maintain this relationship. There are two ways of speficying the transform matrix. As the pure matrix or as a composition of translation, rotation and scale components. These styles can be used interchangably. Most importers will calculate the matrix from the composition vectors behind the scenes. Matrix Transform Style: The 4x4 transform matrix is represented by a . It contains sixteen attributes numbered m00 to m33. Example: Vector Transform Style: Three components representing the position, rotation and scale. The rotation component can be specified in euler's (a.k.a yaw, pitch, roll), as an axis & angle or as a quaternion. Examples for each rotation method: The format of the angles is radians unless explicitly set (using the 'aformat="degrees"' attribute and value). 2.4 Extension Mechanism For extensibility reasons - all XODE objects and containers may contain multiple "" elements. This element is provided so that extensions can be added to the format by applications. This element MUST contain a name attribute so importers can recognise the extension. Any time an XODE file is imported with the intention of being altered and exported, the importer is recommended to read this element and retain it's data for exporting even if they are not using any extensions themselves. This is so that an XODE file with such extension data can be opened in an editor which, regardless of whether if supports the extensions will not discard their data. While desirable, this behaviour is OPTIONAL. Applications using the element of XODE SHOULD attempt to do so in a way that multiple extensions can co-exist in a file. Thus, each extension should have a unique name. Eg: ... ... The ename attribute is to identify which extension it is. It is the only allowable attribute of . In the above example, and application not supporting the extension "foo" can still preserve its data when exporting. 3 Compliancy Levels Some XODE features are complex, have implementation barriers or might not be nessesary for a particular application. The following is a list of the more complex XODE features and their indentifying code: 1. Body Geom in a Group (bgig) When a Geom is added to a Body in ODE, it needs to be added relitive to the bodies transform. During the simulation, ODE retains this relationship. Transforms in XODE however are relitive to the parent node. Thus, if a has a ancestor which is not its direct parent, a transform needs to be calcualted which is relitive to said ancestor. This transform is typically calculated by recursing up the tree multiplying the transforms until the is reached. This is slightly complicated to implement, and can slow the parsing due to the recursive calculations 2. Joint links a not yet defined body (postlink) It is possible to link to a body which is defined later in the file. This means a second parse of the structure may be needed to resolve this links. This may be undesirable for complexity or speed reasons. 3. Retaining the XODE structure (retain) Retaining the original strucutre, including data for unknown extensions usually requires that the XODE data be retained in memory as not all structures (such as ) are defined in ODE. This is usually only applicable to applications where the XODE file will be written out for example as with editors. It is a highly desirable feature for an editor to have as it means no data is lost. It is expected that all XODE implementation support 'bbig' and 'postlink'. Thus, if they don't - they need warn about this by adding '-bgig' and/or '-postlink' to their version compatability string depending on which of the two features they dont' support. It isn't expected that XODE implementations support 'retain' as it means the original XODE strucutre needs to be kept in memory. Thus, implementations which do support it can advertise this by adding '+retain' to their version comatability string. All public XODE implementations (importers, exporters, editors or other) MUST advertise their XODE version and the compatabilities. For example: XODE 1.0r22 -bgig -postlink XODE 1.0r22 +retain XODE 1.0r22 For 100% compatability of your XODE files, it is recommended to place Body Geoms directly as child elemnts of , link only to bodies in joints which are defined first in the file. However, this isn't always possible due to the various needs people have (hence the reason why such features are defined for XODE). 4 XML Schema Valid XODE files MUST conform to this XML Schema TODO: Insert Schema here 5 Example File TODO: Insert example here 5 References ODE: http://ode.org/ 6 Acknowledgements Shaul Kedem for creating the XML Schema. The ODE mailing list for their helpful comments. 7 Full Copyright Statement Copyright (C) 2004 William Denniss. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.