       height: region.options.bounds.height()
 
   {header, regions}
+
+humanSkeleton =
+  landmark: 'navel'
+  children:
+    "Lower Spine":
+      landmark: 'xiphoid'
+      part: 'Torso'
+      children:
+        "Upper Spine":
+          landmark: 'suprasternalNotch'
+          part: 'Torso'
+          children:
+            Neck:
+              landmark: 'atlas'
+              part: 'Torso'
+              children:
+                Head:
+                  landmark: 'headCenter'
+                  part: 'Head'
+            "Clavicle Left":
+              landmark: 'shoulderLeft'
+              part: 'Torso'
+              children:
+                "Upper Arm Left":
+                  landmark: 'elbowLeft'
+                  children:
+                    "Lower Arm Left":
+                      landmark: 'wrist'
+                      regionId: 'LeftHand'
+                      children:
+                        "Hand Left":
+                          landmark: 'fingertip'
+                          regionId: 'LeftHand'
+            "Clavicle Right":
+              landmark: 'shoulderRight'
+              part: 'Torso'
+              children:
+                "Upper Arm Right":
+                  landmark: 'elbowRight'
+                  children:
+                    "Lower Arm Right":
+                      landmark: 'wrist'
+                      regionId: 'RightHand'
+                      children:
+                        "Hand Right":
+                          landmark: 'fingertip'
+                          regionId: 'RightHand'
+        Pelvis:
+          landmark: 'hypogastrium'
+          parentLandmark: 'navel'
+          part: 'Torso'
+          children:
+            "Acetabulum Left":
+              landmark: 'acetabulumLeft'
+              part: 'Torso'
+              children:
+                "Upper Leg Left":
+                  landmark: 'kneeLeft'
+                  children:
+                    "Lower Leg Left":
+                      landmark: 'ankleLeft'
+                      children:
+                        "Foot Left":
+                          landmark: 'toeTip'
+                          regionId: 'LeftFoot'
+            "Acetabulum Right":
+              landmark: 'acetabulumRight'
+              part: 'Torso'
+              children:
+                "Upper Leg Right":
+                  landmark: 'kneeRight'
+                  children:
+                    "Lower Leg Right":
+                      landmark: 'ankleRight'
+                      children:
+                        "Foot Right":
+                          landmark: 'toeTip'
+                          regionId: 'RightFoot'
+                          
+createRigTemplate = (side, landmarks) ->
+  boneBodyMap = {}
+  allBones = {}
+  nextBoneId = 1
+
+  addBones = (parent, boneName, data, transform) ->
+    # Assign an ID to the bone.
+    data.id = nextBoneId
+    nextBoneId++
+
+    if parent
+      # Add bone spanning from child to parent landmark.
+      transformInverse = new THREE.Matrix4().getInverse transform
+
+      getLandmarkVector = (name, regionId) ->
+        if regionId
+          landmark = _.find landmarks, (landmark) -> landmark.name is name and landmark.regionId is regionId
+
+        else
+          landmark = _.find landmarks, (landmark) -> landmark.name is name
+
+        # Note: Creature coordinate space has positive Y pointing upwards.
+        vector = new THREE.Vector3 landmark.x, -landmark.y, 0
+
+        # Translate to local space.
+        vector.applyMatrix4 transformInverse
+
+        vector
+
+      startVector = getLandmarkVector data.parentLandmark or parent.landmark, parent.regionId
+      endVector = getLandmarkVector data.landmark, data.regionId
+
+      boneData =
+        id: data.id
+        name: boneName
+        localRestStartPt: [startVector.x, startVector.y]
+        localRestEndPt: [endVector.x, endVector.y]
+        restParentMat: transform.elements
+        children: []
+
+      allBones[data.id] = boneData
+
+      boneBodyMap[boneName] = data.part or boneName
+
+    # Traverse the children if the hierarchy continues.
+    return unless data.children
+
+    # Calculate the new transform.
+    if parent
+      rootVector = getLandmarkVector parent.landmark, parent.regionId
+      difference = new THREE.Vector3().subVectors endVector, rootVector
+      childrenTransform = new THREE.Matrix4().makeRotationZ Math.atan2 difference.y, difference.x
+      childrenTransform.setPosition difference
+
+      childrenTransform.premultiply transform
+
+    else
+      childrenTransform = transform
+
+    for boneName, child of data.children
+      addBones data, boneName, child, childrenTransform
+      boneData?.children.push child.id
+
+  addBones null, null, humanSkeleton, new THREE.Matrix4
+
+  bone_body_map: boneBodyMap
+  all_bones: allBones


  layoutContext.drawImage characterCanvas, 0, 0

  {layoutCanvas, characterCanvas}

createRigRegion = (side, landmarks) ->
  header =

    for side, key of LOI.Engine.RenderingSides.Keys
      landmarks = bodyRenderer.landmarks[key]()
      archive.append EJSON.stringify(createRigRegion(key, landmarks), indent: true), name: "rigregions/#{_.toLower key}.json"

    # Export rig templates.
    for side, key of LOI.Engine.RenderingSides.Keys
      landmarks = bodyRenderer.landmarks[key]()
      archive.append EJSON.stringify(createRigTemplate(key, landmarks), indent: true), name: "rigtemplates/#{_.toLower key}.creaRig"

    # Complete exporting.
    archive.finalize()
