XSF Skeleton format
Home Up XMF File format XSF Skeleton format XRF file format XAF file format XPF Morph format Rotations

 

XSF Skeleton file format

The skeleton file is tricky, on the one hand it is possible to hand-edit it to great effect, on the other hand it can go very wrong if it is inconsistent.

Note: regarding poses for furniture. If you want a custom seat pose you need an animation file (XAF) not a skeleton file (XSF). If its a static pose you just need one keyframe but it does need to be an animation not a skeleton.

Header record

a solitary tag (it ends in />), probably ignored:

<HEADER MAGIC="XSF" VERSION="910" />

Start of Skeleton block

The whole of the skeleton is stored between this tag and its closing tag

<SKELETON NUMBONES="6">

NUMBONES is the total bone count including bone "0" so it will be one larger than the final bone ID

Start of a bone or node (I use the two terms interchangeably), details of the bone are stored between this tag and its closing tag.

Depending on the type of object the skeleton may be used slightly differently, for instance in furniture I would typically locate the position of the end of the bone in the middle of the mesh or directly under it, whichever is convenient, whereas in an avatar bodypart the bodypart probably extends along the length of the bone with the end of  the bone serving as the "hinge" between two bodyparts.

Special Room Tag

<SKELETON NUMBONES="6" SCENEAMBIENTCOLOR="0.65098 0.65098 0.65098">

SCENEAMBIENTCOLOR: Probably a RGB color expressed as three values from 0 to 1.

Bone opening tag

There must be a corresponding closing tag

    <BONE ID="0" NAME="Root" NUMCHILDS="1">

Name is important. IMVU uses bone names when attaching skeletons, for example when an avatar enters a room its root node is attached to a seat. Other names have special meaning. So far I have always seen bone 0 called "Root".

NUMCHILDS is the number of bones that directly connect to this one. I suspect that it is ignored however try to keep it consistent in case a program does depend on it.

Special Lighting bone tag

    <BONE NAME="Omni01" NUMCHILDS="0" ID="220" LIGHTTYPE="1" 
LIGHTCOLOR="0.984314 0.909804 0.709804">

This is a special type of the bone tag used in room definitions. A BONE record could potentially contain LIGHTTYPE and LIGHTCOLOR records.

LIGHTTYPE: I have no information on the types allowed.

LIGHTCOLOR: Probably a RGB color expressed as three values from 0 to 1.

Translation

The position of this bone relative to the previous one

        <TRANSLATION>0 0 0</TRANSLATION>

For limbs the length of the translation is the length of the bone. If the parent bone is not rotated then this position is in regular X,Y,Z coordinates e.g. x is right, y is away and z is up.

Rotation

        <ROTATION>0 0 0 -1</ROTATION>

Rotations are tricky. Just note that "0 0 0 -1" is the default position and "0 0 0 1" is the same position.

Note that the Root bone should not be translated (moved) or rotated. This is because IMVU ignores these values for Root but a 3D editor will not, so a translation here will prevent your design from importing.

Local translation and rotation

        <LOCALTRANSLATION>0 0 0</LOCALTRANSLATION>
        <LOCALROTATION>0 0 0 -1</LOCALROTATION>

These are hard to explain but roughly speaking they represent the base position of the skeleton that the mesh was drawn around. Unlike the position attributes the local position is absolute so for a simple skeleton the values should look just like the position but backwards (negated). For a more complex skeleton the values are the result of applying all the translations and rotations leading to that point so they will not be so obviously related.

The local translation and rotation are only important on bones that have mesh parts weighted to them. On linking bones, seats etc. the local values serve no purpose.

Parent and Child IDs

        <PARENTID>-1</PARENTID>
        <CHILDID>1</CHILDID>

Bone 0 (Root) has a parent of -1, all others have as parent the ID of the bone they attach to. Based on my observations It seems likely that IMVU previewer only reads the parent ID.

Bone Closing tag

    </BONE>

Bone with a translation and localtranslation

    <BONE ID="1" NAME="Sphere" NUMCHILDS="4">
        <TRANSLATION>0 0 500</TRANSLATION>
        <ROTATION>0 0 0 1</ROTATION>
        <LOCALTRANSLATION>0 0 -500</LOCALTRANSLATION>
        <LOCALROTATION>0 0 0 -1</LOCALROTATION>
        <PARENTID>0</PARENTID>
        <CHILDID>2</CHILDID>
        <CHILDID>3</CHILDID>
        <CHILDID>4</CHILDID>
        <CHILDID>5</CHILDID>
    </BONE>

There would be a ball attached at this point, originally drawn standing on the ground. Transformations appear to be applied in the order:

  1. Localrotation (about the origin)
  2. Localtranslation
  3. Rotation (about the origin)
  4. Translation
  5. Any further translation and rotation pairs.

In this example the initial localtranslation moves the centre of the ball down to the origin so it can be rotated about its center. The rotation is given as 0 0 0 1 but this can be replaced by an animation. The translation moves it back to standing on the ground.

A Seat node

The seat node is the position where the avatar's root node is located when the avatar is in that seat.

    <BONE ID="2" NAME="Seat01.Standing" NUMCHILDS="0">
        <TRANSLATION>0 0 460</TRANSLATION>
        <ROTATION>0 0 0 -1</ROTATION>
        <LOCALTRANSLATION>0 0 -960</LOCALTRANSLATION>
        <LOCALROTATION>0 0 0 1</LOCALROTATION>
        <PARENTID>1</PARENTID>
    </BONE>

Handle node

The handle node is where the yellow dot and chair icon appear. It also appears to be the target for the camera, as furniture animations that move the avatar but not the handle can move the avatar out of view.

    <BONE ID="3" NAME="Handle01" NUMCHILDS="0">
        <TRANSLATION>0 0 600</TRANSLATION>
        <ROTATION>0 0 0 -1</ROTATION>
        <LOCALTRANSLATION>0 0 -1100</LOCALTRANSLATION>
        <LOCALROTATION>0 0 0 1</LOCALROTATION>
        <PARENTID>1</PARENTID>
    </BONE>

Catcher

The catcher and pitcher nodes are the locations that avatars move to when an action takes place. The avatar in the seat will move to the catcher location, perform the animation, and move back to the seat.

    <BONE ID="4" NAME="Catcher01.Standing" NUMCHILDS="0">
        <TRANSLATION>0 258 400</TRANSLATION>
        <ROTATION>0 0 0 -1</ROTATION>
        <LOCALTRANSLATION>0 -258 -750</LOCALTRANSLATION>
        <LOCALROTATION>0 0 0 1</LOCALROTATION>
        <PARENTID>1</PARENTID>
    </BONE>

Pitcher

The pitcher node is for the other avatar in a cooperative animation, such as a hug.

The pitcher must be a specific distance from the catcher and rotated 180 degrees.

    <BONE ID="5" NAME="Pitcher01.Standing" NUMCHILDS="0">
        <TRANSLATION>0 -258 400</TRANSLATION>
        <ROTATION>0 0 -1 0</ROTATION>
        <LOCALTRANSLATION>0 258 -750</LOCALTRANSLATION>
        <LOCALROTATION>0 0 1 0</LOCALROTATION>
        <PARENTID>1</PARENTID>
    </BONE>

Closing tag for the Skeleton

</SKELETON>