diff --git a/binaries/data/mods/public/art/skeletons/ballista.xml b/binaries/data/mods/public/art/skeletons/ballista.xml
new file mode 100644
index 0000000000..e83553341f
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/ballista.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ballista
+
+ main
+ weapon
+ lever
+ arm_left
+ arm_right
+ sling_left
+ sling
+ sling_right
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/biped.xml b/binaries/data/mods/public/art/skeletons/biped.xml
new file mode 100644
index 0000000000..2abeded6e5
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/biped.xml
@@ -0,0 +1,186 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Bip01
+
+ root
+ pelvis
+ spine
+ spine1
+ neck
+ head
+
+ l_clavicle
+ l_upperarm
+ l_forearm
+ l_hand
+
+
+
+
+
+
+
+ r_clavicle
+ r_upperarm
+ r_forearm
+ r_hand
+
+
+
+
+
+
+
+
+
+
+ l_thigh
+ l_calf
+ l_foot
+
+
+
+
+
+
+ r_thigh
+ r_calf
+ r_foot
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Biped_GlobalSRT
+
+
+ root
+
+ pelvis
+
+ spine
+
+ spine1
+
+
+
+
+ l_clavicle
+
+
+ l_upperarm
+
+ l_forearm
+
+
+
+ r_clavicle
+
+
+ r_upperarm
+
+ r_forearm
+
+
+
+ neck
+
+ head
+
+
+
+ l_thigh
+
+ l_calf
+
+
+
+ r_thigh
+
+ r_calf
+
+
+
+ l_hand
+
+
+
+ l_foot
+
+
+
+ r_hand
+
+
+
+ r_foot
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/boar.xml b/binaries/data/mods/public/art/skeletons/boar.xml
new file mode 100644
index 0000000000..0bed9dd2d4
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/boar.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Armature
+ BoarArmature
+ Body
+ Body2
+ Rear
+ Tail
+ Hip_Left
+ Back_Leg_Left
+ Shin_Left
+ Back_Foot_Left
+
+
+
+ Hip_Right
+ Back_Leg_Right
+ Shin_Right
+ Back_Foot_Right
+
+
+
+
+
+
+ Neck
+ Head
+ Ear_Left
+ Ear_Right
+
+
+ Shoulder_Left
+ Front_Leg_Left
+ Forearm_Left
+ Front_Foot_Left
+
+
+
+ Shoulder_Right
+ Front_Leg_Right
+ Forearm_Right
+ Front_Foot_Right
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/chariot.xml b/binaries/data/mods/public/art/skeletons/chariot.xml
new file mode 100644
index 0000000000..35860fb878
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/chariot.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ base
+
+ base
+ chariot
+ left_wheel
+ right_wheel
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/chicken.xml b/binaries/data/mods/public/art/skeletons/chicken.xml
new file mode 100644
index 0000000000..2fde81b8b5
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/chicken.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ BlenderChicken
+
+ Body
+ Neck_Low
+ Neck_High
+ Head
+
+
+ Leg_L
+ Shin_L
+ Foot_L
+
+
+ Leg_R
+ Shin_R
+ Foot_R
+
+
+ Rear
+ Tail
+
+ Wing_R
+ WingTip_R
+
+ Wing_L
+ WingTip_L
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/deer.xml b/binaries/data/mods/public/art/skeletons/deer.xml
new file mode 100644
index 0000000000..fbefa52261
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/deer.xml
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Deer01
+
+ root
+ pelvis
+ spine
+ spine1
+ neck
+ neck1
+ head
+ r_ear
+
+ l_ear
+
+
+
+ l_clavicle
+ l_upperarm
+ l_forearm
+ l_hand
+ l_finger
+
+
+
+
+
+ r_clavicle
+ r_upperarm
+ r_forearm
+ r_hand
+ r_finger
+
+
+
+
+
+
+
+
+ l_thigh
+ l_calf
+ l_foot
+ l_toe
+
+
+
+
+ r_thigh
+ r_calf
+ r_foot
+ r_toe
+
+
+
+
+ tail
+ tail1
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/elephant_3ds.xml b/binaries/data/mods/public/art/skeletons/elephant_3ds.xml
new file mode 100644
index 0000000000..22201211b2
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/elephant_3ds.xml
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ele01
+
+ root
+ pelvis
+ spine
+ spine1
+ neck
+ neck1
+ head
+
+ trunk
+ trunk1
+ trunk2
+
+
+
+
+
+
+ l_clavicle
+ l_upperarm
+ l_forearm
+ l_hand
+ l_finger
+
+
+
+
+
+
+ r_clavicle
+ r_upperarm
+ r_forearm
+ r_hand
+ r_finger
+
+
+
+
+
+
+
+
+
+ l_thigh
+ l_calf
+ l_foot
+ l_toe
+
+
+
+
+
+ r_thigh
+ r_calf
+ r_foot
+ r_toe
+
+
+
+
+
+ tail
+ tail1
+ tail1
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/elephant_blender.xml b/binaries/data/mods/public/art/skeletons/elephant_blender.xml
new file mode 100644
index 0000000000..32327acc9c
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/elephant_blender.xml
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Elephant
+ Elephant
+ body_1
+ body_2
+ butt
+ tail_1
+ tail_2
+ tail_3
+ tail_4
+ tail_3_joint
+
+ tail_2_joint
+
+ tail_1_joint
+
+
+ pelvis
+ Bone_001
+ leg_right
+ shin_right
+ foot_right
+
+ leg_right_joint
+
+
+ Bone_002
+ leg_left
+ shin_left
+ foot_left
+
+ leg_left_joint
+
+
+
+ belly
+
+ shoulder_left
+ arm_left
+ forearm_left
+ hand_left
+
+ arm_left_joint_front
+ arm_left_joint_back
+
+
+
+ shoulder_right
+ arm_right
+ forearm_right
+ hand_right
+
+ arm_right_joint_front
+ arm_right_joint_back
+
+
+
+ neck
+ head
+ trunk_1
+ trunk_2
+ trunk_3
+ trunk_4
+ trunk_5
+ trunk_5_joint
+ trunk_6
+ trunk_7
+ trunk_8
+ trunk_9
+ trunk_10
+ trunk_11
+ trunk_10_joint
+
+ trunk_9_joint
+
+ trunk_8_joint
+
+ trunk_7_joint
+
+ trunk_6_joint
+
+
+ trunk_4_joint
+
+ trunk_3_joint
+
+ trunk_2_joint
+
+ trunk_1_joint
+
+ head_trunk_joint
+ ear_left
+ ear_right
+
+
+
+ arm_left_target
+ arm_right_target
+ leg_left_poletarget
+ leg_right_poletarget
+ leg_right_target
+ leg_left_target
+ arm_right_kneetarget
+ arm_left_kneetarget
+ tail_target
+ trunk_target
+
+
diff --git a/binaries/data/mods/public/art/skeletons/fish.xml b/binaries/data/mods/public/art/skeletons/fish.xml
new file mode 100644
index 0000000000..2331e0428e
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/fish.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ fish_shoal
+
+ main
+ motion_head
+ motion_mid
+ motion_back
+ jump_first
+ jump_second
+ jump_third
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/floating_barrels.xml b/binaries/data/mods/public/art/skeletons/floating_barrels.xml
new file mode 100644
index 0000000000..dd108ef5fe
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/floating_barrels.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Barrel_2
+ Barrel_2
+ Barrel_2_Controller
+
+ Barrel_3
+ Barrel_3_Controller
+
+ Barrel_1
+ Barrel_1_Controller
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/gate.xml b/binaries/data/mods/public/art/skeletons/gate.xml
new file mode 100644
index 0000000000..1cdb0ef501
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/gate.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ gate
+
+ origin
+ door_right
+ lock_right
+
+ door_left
+ lock_left
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/giraffe.xml b/binaries/data/mods/public/art/skeletons/giraffe.xml
new file mode 100644
index 0000000000..795c488a6c
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/giraffe.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ main_pelvis
+
+ main_pelvis
+ left_r_pelvis_upper
+ left_r_leg_top
+ left_r_leg_mid
+ left_r_leg_bottom
+ left_r_foot
+
+
+
+
+ right_r_pelvis_upper
+ right_r_leg_top
+ right_r_leg_mid
+ right_r_leg_bottom
+ right_r_foot
+
+
+
+
+ spine_01
+ spine_02
+ spine_neck
+ right_f_pelvis_upper
+ right_f_leg_top
+ right_f_leg_mid
+ right_f_leg_bottom
+ right_f_foot
+
+
+
+
+ left_f_pelvis_upper
+ left_f_leg_top
+ left_f_leg_mid
+ left_f_leg_bottom
+ left_f_foot
+
+
+
+
+ neck_01
+ neck_02
+ neck_03
+ head
+
+
+
+
+
+
+ tail_01
+ tail_02
+ tail_03
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/horse.xml b/binaries/data/mods/public/art/skeletons/horse.xml
new file mode 100644
index 0000000000..b2ff3d4263
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/horse.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Horse
+
+ root
+ pelvis
+ spine
+ spine1
+ neck
+ neck1
+ head
+
+ l_clavicle
+ l_upperarm
+ l_forearm
+ l_hand
+ l_finger
+
+
+
+
+ r_clavicle
+ r_upperarm
+ r_forearm
+ r_hand
+ r_finger
+
+
+
+
+
+
+
+ l_thigh
+ l_calf
+ l_foot
+ l_toe
+
+
+
+ r_thigh
+ r_calf
+ r_foot
+ r_toe
+
+
+
+ tail
+ tail1
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/peacock.xml b/binaries/data/mods/public/art/skeletons/peacock.xml
new file mode 100644
index 0000000000..2e72f6e77b
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/peacock.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PeacockArmature
+ PeacockArmature
+ Body
+ Neck1
+ Neck2
+ Neck3
+ Head
+ Mohawk
+
+
+ Neck2_Joint
+
+
+ tailHolder_Base
+ tailHolder_Middle
+ tailHolder_Top
+ tailFeather_Middle
+ tailFeather_Right
+ tailFeather_Rightmost
+ tailFeather_Left
+ tailFeather_Leftmost
+ tailFeather_Right45
+ tailFeather_Left45
+ tailFeather_Right60
+ tailFeather_Left60
+ tailHolder_Back
+ tailHolder_Back_Fluff
+
+ tailFeather_Right90
+ tailFeather_Left90
+
+
+
+ RightWing
+ LeftWing
+
+ LeftLeg
+ LeftShin
+ LeftFoot
+
+ LeftKnee
+
+ RightLeg
+ RightShin
+ RightFoot
+
+ RightKnee
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/readme.txt b/binaries/data/mods/public/art/skeletons/readme.txt
new file mode 100644
index 0000000000..ffed5eb4f6
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/readme.txt
@@ -0,0 +1,12 @@
+The s must specify all the bones that may influence vertexes of
+skinned meshes. The is the name of the bone in the relevant
+modelling/animation program. The name is used to determine
+whether this applies to the data found in a given model file.
+
+ must be the name of a bone in the standard_skeleton identified by
+.
+
+The hierarchy of bones is mostly irrelevant (though it makes sense to match
+the structure used by the modelling program) - the only effect is that
+the default (i.e. when none is specified for a given bone) is
+inherited from the parent node in this hierarchy.
diff --git a/binaries/data/mods/public/art/skeletons/rowing_boat.xml b/binaries/data/mods/public/art/skeletons/rowing_boat.xml
new file mode 100644
index 0000000000..04ecf1ea09
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/rowing_boat.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+ RowingBoat
+
+ RowingBoatBone
+ RightRow
+ LeftRow
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/shark.xml b/binaries/data/mods/public/art/skeletons/shark.xml
new file mode 100644
index 0000000000..2d4d330377
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/shark.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SHARK_
+ head
+ spine1
+ spine2
+ spine3
+ spine4
+ spine5
+ spine6
+ spine7
+ reartopfin1
+ reartopfin2
+ reartopfin3
+ reartopfin4
+ reartopfintip
+ reartopfin4back
+
+ reartopfin3back
+
+ reartopfin2back
+
+
+ rearbottomfin1
+ rearbottomfin2
+ rearbottomfin3
+ rearbottomfin4
+
+ rearbottomfin2back
+
+ rearbottomfin1back
+
+
+
+
+
+
+ leftfin
+ leftfintip
+ leftfintipback
+
+ leftfinback
+
+ topfin
+ topfintip
+ topfinback
+
+ rightfin
+ rightfintip
+ rightfintipback
+
+ rightfinback
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/sheep.xml b/binaries/data/mods/public/art/skeletons/sheep.xml
new file mode 100644
index 0000000000..42664a5b96
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/sheep.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ThreeBagsFull
+ ThreeBagsFull
+ Neck
+ Head
+
+ Body_Front
+ Body_Rear
+ Pelvis_Left
+ Leg_Left
+ Shin_Left
+ Foot_Left
+
+
+
+ Pelvis_Right
+ Leg_Right
+ Shin_Right
+ Foot_Right
+
+
+
+ Butt
+ Tail
+
+
+
+ Shoulder_Left
+ Arm_Left
+ Forearm_Left
+ Hand_Left
+
+
+
+ Shoulder_Right
+ Arm_Right
+ Forearm_Right
+ Hand_Right
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/ship_one_row.xml b/binaries/data/mods/public/art/skeletons/ship_one_row.xml
new file mode 100644
index 0000000000..a20383a71d
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/ship_one_row.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+ shiponerow
+
+ one_row_main
+ right_top_row
+ left_top_row
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/ship_three_row.xml b/binaries/data/mods/public/art/skeletons/ship_three_row.xml
new file mode 100644
index 0000000000..1132be7ae3
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/ship_three_row.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ shipthreerow
+
+ three_row_main
+ right_top_row
+ right_middle_row
+ right_bottom_row
+ left_top_row
+ left_middle_row
+ left_bottom_row
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/ship_two_row.xml b/binaries/data/mods/public/art/skeletons/ship_two_row.xml
new file mode 100644
index 0000000000..c58de8b973
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/ship_two_row.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ shiptworow
+
+ two_row_main
+ right_top_row
+ right_bottom_row
+ left_top_row
+ left_bottom_row
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/siege_onager.xml b/binaries/data/mods/public/art/skeletons/siege_onager.xml
new file mode 100644
index 0000000000..2f38c2361a
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/siege_onager.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ onager
+
+ onagermain
+ windlass
+ spoke
+ sling
+ rope_left
+ rope_right
+ rope_center
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/skeletons.xml b/binaries/data/mods/public/art/skeletons/skeletons.xml
deleted file mode 100644
index ecc9b19da4..0000000000
--- a/binaries/data/mods/public/art/skeletons/skeletons.xml
+++ /dev/null
@@ -1,1865 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Bip01
-
-
- root
- pelvis
- spine
- spine1
- neck
- head
-
- l_clavicle
- l_upperarm
- l_forearm
- l_hand
-
-
-
-
-
-
-
- r_clavicle
- r_upperarm
- r_forearm
- r_hand
-
-
-
-
-
-
-
-
-
-
- l_thigh
- l_calf
- l_foot
-
-
-
-
-
-
- r_thigh
- r_calf
- r_foot
-
-
-
-
-
-
-
-
-
-
-
-
-
- Biped_GlobalSRT
-
-
-
- root
-
-
- pelvis
-
-
- spine
-
-
- spine1
-
-
-
-
- l_clavicle
-
-
- l_upperarm
-
-
- l_forearm
-
-
-
- r_clavicle
-
-
- r_upperarm
-
-
- r_forearm
-
-
-
- neck
-
-
- head
-
-
-
- l_thigh
-
-
- l_calf
-
-
-
- r_thigh
-
-
- r_calf
-
-
-
- l_hand
-
-
-
- l_foot
-
-
-
- r_hand
-
-
-
- r_foot
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Deer01
-
- root
- pelvis
- spine
- spine1
- neck
- neck1
- head
- r_ear
-
- l_ear
-
-
-
- l_clavicle
- l_upperarm
- l_forearm
- l_hand
- l_finger
-
-
-
-
-
- r_clavicle
- r_upperarm
- r_forearm
- r_hand
- r_finger
-
-
-
-
-
-
-
-
- l_thigh
- l_calf
- l_foot
- l_toe
-
-
-
-
- r_thigh
- r_calf
- r_foot
- r_toe
-
-
-
-
- tail
- tail1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- base
-
- base
- chariot
- left_wheel
-
- right_wheel
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Horse
-
- root
- pelvis
- spine
- spine1
- neck
- neck1
- head
-
-
- l_clavicle
- l_upperarm
- l_forearm
- l_hand
- l_finger
-
-
-
-
-
- r_clavicle
- r_upperarm
- r_forearm
- r_hand
- r_finger
-
-
-
-
-
-
-
-
- l_thigh
- l_calf
- l_foot
- l_toe
-
-
-
-
- r_thigh
- r_calf
- r_foot
- r_toe
-
-
-
-
- tail
- tail1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ele01
-
- root
- pelvis
- spine
- spine1
- neck
- neck1
- head
-
- trunk
- trunk1
- trunk2
-
-
-
-
-
-
- l_clavicle
- l_upperarm
- l_forearm
- l_hand
- l_finger
-
-
-
-
-
-
- r_clavicle
- r_upperarm
- r_forearm
- r_hand
- r_finger
-
-
-
-
-
-
-
-
-
- l_thigh
- l_calf
- l_foot
- l_toe
-
-
-
-
-
- r_thigh
- r_calf
- r_foot
- r_toe
-
-
-
-
-
- tail
- tail1
- tail1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- FourWheelRam
-
- RamBone
- WheelLeftBack
- WheelLeftFront
- WheelRightBack
- WheelRightFront
- Weapon
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SixWheeler
-
- sixwheel
- l_back
- l_mid
- l_front
- r_back
- r_mid
- r_front
- weapon
-
-
-
-
-
-
-
-
-
-
-
-
-
- TwoWheeler
-
- twowheel
- l_wheel
- r_wheel
- weapon
-
-
-
-
-
-
-
-
-
-
-
-
- RowingBoat
-
- RowingBoatBone
- RightRow
- LeftRow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- main_pelvis
-
- main_pelvis
- left_r_pelvis_upper
- left_r_leg_top
- left_r_leg_mid
- left_r_leg_bottom
- left_r_foot
-
-
-
-
- right_r_pelvis_upper
- right_r_leg_top
- right_r_leg_mid
- right_r_leg_bottom
- right_r_foot
-
-
-
-
- spine_01
- spine_02
- spine_neck
- right_f_pelvis_upper
- right_f_leg_top
- right_f_leg_mid
- right_f_leg_bottom
- right_f_foot
-
-
-
-
- left_f_pelvis_upper
- left_f_leg_top
- left_f_leg_mid
- left_f_leg_bottom
- left_f_foot
-
-
-
-
- neck_01
- neck_02
- neck_03
- head
-
-
-
-
-
-
- tail_01
- tail_02
- tail_03
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- fish_shoal
-
- main
- motion_head
- motion_mid
- motion_back
- jump_first
- jump_second
- jump_third
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- whale_1
-
- main
- body
- head
- spine
- pelvis
- tail
-
-
- fin_r
- fin_l
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- BlenderChicken
-
- Body
- Neck_Low
- Neck_High
- Head
-
-
- Leg_L
- Shin_L
- Foot_L
-
-
- Leg_R
- Shin_R
- Foot_R
-
-
- Rear
- Tail
-
- Wing_R
- WingTip_R
-
- Wing_L
- WingTip_L
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Armature
- BoarArmature
- Body
- Body2
- Rear
- Tail
- Hip_Left
- Back_Leg_Left
- Shin_Left
- Back_Foot_Left
-
-
-
- Hip_Right
- Back_Leg_Right
- Shin_Right
- Back_Foot_Right
-
-
-
-
-
-
- Neck
- Head
- Ear_Left
- Ear_Right
-
-
- Shoulder_Left
- Front_Leg_Left
- Forearm_Left
- Front_Foot_Left
-
-
-
- Shoulder_Right
- Front_Leg_Right
- Forearm_Right
- Front_Foot_Right
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ThreeBagsFull
- ThreeBagsFull
- Neck
- Head
-
- Body_Front
- Body_Rear
- Pelvis_Left
- Leg_Left
- Shin_Left
- Foot_Left
-
-
-
- Pelvis_Right
- Leg_Right
- Shin_Right
- Foot_Right
-
-
-
- Butt
- Tail
-
-
-
- Shoulder_Left
- Arm_Left
- Forearm_Left
- Hand_Left
-
-
-
- Shoulder_Right
- Arm_Right
- Forearm_Right
- Hand_Right
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ZebraArmature
- ZebraArmature
- body
- rear_body
- left_pelvis
- rear_left_leg
- rear_left_shin
- rear_left_foot
-
- rear_left_knee
-
- left_pelvis_joint_front
- left_pelvis_joint_rear
-
-
- butt
- tail_start
- tail_middle
- tail_tip
-
-
-
- right_pelvis
- rear_right_leg
- rear_right_shin
- rear_right_foot
-
- rear_right_knee
-
- right_pelvis_joint_front
- right_pelvis_joint_rear
-
-
- rear_belly
-
- middle_belly
- front_belly
-
- left_shoulder
- left_leg
- left_shin
- left_foot
-
-
-
- neck1
- neck2
- head
- left_ear
- right_ear
-
-
-
- right_shoulder
- right_leg
- right_shin
- right_foot
-
-
-
-
- rear_right_leg-target
- rear_left_leg-target
- left_leg-target
- left_knee-target
- right_leg-target
- right_knee-target
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PeacockArmature
- PeacockArmature
- Body
- Neck1
- Neck2
- Neck3
- Head
- Mohawk
-
-
- Neck2_Joint
-
-
- tailHolder_Base
- tailHolder_Middle
- tailHolder_Top
- tailFeather_Middle
- tailFeather_Right
- tailFeather_Rightmost
- tailFeather_Left
- tailFeather_Leftmost
- tailFeather_Right45
- tailFeather_Left45
- tailFeather_Right60
- tailFeather_Left60
- tailHolder_Back
- tailHolder_Back_Fluff
-
- tailFeather_Right90
- tailFeather_Left90
-
-
-
- RightWing
- LeftWing
-
- LeftLeg
- LeftShin
- LeftFoot
-
- LeftKnee
-
- RightLeg
- RightShin
- RightFoot
-
- RightKnee
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SHARK_
- head
- spine1
- spine2
- spine3
- spine4
- spine5
- spine6
- spine7
- reartopfin1
- reartopfin2
- reartopfin3
- reartopfin4
- reartopfintip
- reartopfin4back
-
- reartopfin3back
-
- reartopfin2back
-
-
- rearbottomfin1
- rearbottomfin2
- rearbottomfin3
- rearbottomfin4
-
- rearbottomfin2back
-
- rearbottomfin1back
-
-
-
-
-
-
- leftfin
- leftfintip
- leftfintipback
-
- leftfinback
-
- topfin
- topfintip
- topfinback
-
- rightfin
- rightfintip
- rightfintipback
-
- rightfinback
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ballista
-
- main
- weapon
- lever
- arm_left
- arm_right
- sling_left
- sling
- sling_right
-
-
-
-
-
-
-
-
-
-
-
-
- shiponerow
-
- one_row_main
- right_top_row
- left_top_row
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- shiptworow
-
- two_row_main
- right_top_row
- right_bottom_row
- left_top_row
- left_bottom_row
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- shipthreerow
-
- three_row_main
- right_top_row
- right_middle_row
- right_bottom_row
- left_top_row
- left_middle_row
- left_bottom_row
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Elephant
- Elephant
- body_1
- body_2
- butt
- tail_1
- tail_2
- tail_3
- tail_4
- tail_3_joint
-
- tail_2_joint
-
- tail_1_joint
-
-
- pelvis
- Bone_001
- leg_right
- shin_right
- foot_right
-
- leg_right_joint
-
-
- Bone_002
- leg_left
- shin_left
- foot_left
-
- leg_left_joint
-
-
-
- belly
-
- shoulder_left
- arm_left
- forearm_left
- hand_left
-
- arm_left_joint_front
- arm_left_joint_back
-
-
-
- shoulder_right
- arm_right
- forearm_right
- hand_right
-
- arm_right_joint_front
- arm_right_joint_back
-
-
-
- neck
- head
- trunk_1
- trunk_2
- trunk_3
- trunk_4
- trunk_5
- trunk_5_joint
- trunk_6
- trunk_7
- trunk_8
- trunk_9
- trunk_10
- trunk_11
- trunk_10_joint
-
- trunk_9_joint
-
- trunk_8_joint
-
- trunk_7_joint
-
- trunk_6_joint
-
-
- trunk_4_joint
-
- trunk_3_joint
-
- trunk_2_joint
-
- trunk_1_joint
-
- head_trunk_joint
- ear_left
- ear_right
-
-
-
- arm_left_target
- arm_right_target
- leg_left_poletarget
- leg_right_poletarget
- leg_right_target
- leg_left_target
- arm_right_kneetarget
- arm_left_kneetarget
- tail_target
- trunk_target
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- gate
-
- origin
- door_right
- lock_right
-
- door_left
- lock_left
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Barrel_2
- Barrel_2
- Barrel_2_Controller
-
- Barrel_3
- Barrel_3_Controller
-
- Barrel_1
- Barrel_1_Controller
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- onager
-
- onagermain
- windlass
- spoke
- sling
- rope_left
- rope_right
- rope_center
-
-
-
-
-
\ No newline at end of file
diff --git a/binaries/data/mods/public/art/skeletons/vehicle_four_wheel.xml b/binaries/data/mods/public/art/skeletons/vehicle_four_wheel.xml
new file mode 100644
index 0000000000..1f87185f0c
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/vehicle_four_wheel.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ FourWheelRam
+
+ RamBone
+ WheelLeftBack
+ WheelLeftFront
+ WheelRightBack
+ WheelRightFront
+ Weapon
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/vehicle_six_wheel.xml b/binaries/data/mods/public/art/skeletons/vehicle_six_wheel.xml
new file mode 100644
index 0000000000..beee4305bd
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/vehicle_six_wheel.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SixWheeler
+
+ sixwheel
+ l_back
+ l_mid
+ l_front
+ r_back
+ r_mid
+ r_front
+ weapon
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/vehicle_two_wheel.xml b/binaries/data/mods/public/art/skeletons/vehicle_two_wheel.xml
new file mode 100644
index 0000000000..41936e0f1d
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/vehicle_two_wheel.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+ TwoWheeler
+
+ twowheel
+ l_wheel
+ r_wheel
+ weapon
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/whale.xml b/binaries/data/mods/public/art/skeletons/whale.xml
new file mode 100644
index 0000000000..745c27cec9
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/whale.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ whale_1
+
+ main
+ body
+ head
+ spine
+ pelvis
+ tail
+
+
+ fin_r
+ fin_l
+
+
+
+
diff --git a/binaries/data/mods/public/art/skeletons/zebra.xml b/binaries/data/mods/public/art/skeletons/zebra.xml
new file mode 100644
index 0000000000..3b46a99c95
--- /dev/null
+++ b/binaries/data/mods/public/art/skeletons/zebra.xml
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ZebraArmature
+ ZebraArmature
+ body
+ rear_body
+ left_pelvis
+ rear_left_leg
+ rear_left_shin
+ rear_left_foot
+
+ rear_left_knee
+
+ left_pelvis_joint_front
+ left_pelvis_joint_rear
+
+
+ butt
+ tail_start
+ tail_middle
+ tail_tip
+
+
+
+ right_pelvis
+ rear_right_leg
+ rear_right_shin
+ rear_right_foot
+
+ rear_right_knee
+
+ right_pelvis_joint_front
+ right_pelvis_joint_rear
+
+
+ rear_belly
+
+ middle_belly
+ front_belly
+
+ left_shoulder
+ left_leg
+ left_shin
+ left_foot
+
+
+
+ neck1
+ neck2
+ head
+ left_ear
+ right_ear
+
+
+
+ right_shoulder
+ right_leg
+ right_shin
+ right_foot
+
+
+
+
+ rear_right_leg-target
+ rear_left_leg-target
+ left_leg-target
+ left_knee-target
+ right_leg-target
+ right_knee-target
+
+
diff --git a/source/collada/StdSkeletons.h b/source/collada/StdSkeletons.h
index c8bbad339a..86c0bd9c26 100644
--- a/source/collada/StdSkeletons.h
+++ b/source/collada/StdSkeletons.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 Wildfire Games.
+/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -83,7 +83,7 @@ public:
/**
* Initialises the global state with skeleton data loaded from the
- * given XML data. Must only be called once.
+ * given XML data.
* @todo Stop using global state.
* @param xmlData
* @param xmlLength
diff --git a/source/graphics/ColladaManager.cpp b/source/graphics/ColladaManager.cpp
index 9cdc31b67e..412d40e234 100644
--- a/source/graphics/ColladaManager.cpp
+++ b/source/graphics/ColladaManager.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Wildfire Games.
+/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -19,6 +19,8 @@
#include "ColladaManager.h"
+#include
+
#include "graphics/ModelDef.h"
#include "lib/fnv_hash.h"
#include "maths/MD5.h"
@@ -65,14 +67,62 @@ class CColladaManagerImpl
public:
CColladaManagerImpl(const PIVFS& vfs)
- : dll("Collada"), m_VFS(vfs)
+ : dll("Collada"), m_VFS(vfs), m_skeletonHashInvalidated(false)
{
+ // Support hotloading
+ RegisterFileReloadFunc(ReloadChangedFileCB, this);
}
~CColladaManagerImpl()
{
if (dll.IsLoaded())
set_logger(NULL, NULL); // unregister the log handler
+ UnregisterFileReloadFunc(ReloadChangedFileCB, this);
+ }
+
+ Status ReloadChangedFile(const VfsPath& path)
+ {
+ // Ignore files that aren't in the right path
+ if (!boost::algorithm::starts_with(path.string(), L"art/skeletons/"))
+ return INFO::OK;
+
+ if (path.Extension() != L".xml")
+ return INFO::OK;
+
+ m_skeletonHashInvalidated = true;
+
+ // If the file doesn't exist (e.g. it was deleted), don't bother reloading
+ // or 'unloading' since that isn't possible
+ if (!VfsFileExists(path))
+ return INFO::OK;
+
+ if (!dll.IsLoaded() && !TryLoadDLL())
+ return ERR::FAIL;
+
+ LOGMESSAGE(L"Hotloading skeleton definitions from '%ls'", path.string().c_str());
+ // Set the filename for the logger to report
+ set_logger(ColladaLog, const_cast(static_cast(&path)));
+
+ CVFSFile skeletonFile;
+ if (skeletonFile.Load(m_VFS, path) != PSRETURN_OK)
+ {
+ LOGERROR(L"Failed to read skeleton defintions from '%ls'", path.string().c_str());
+ return ERR::FAIL;
+ }
+
+ int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize());
+ if (ok < 0)
+ {
+ LOGERROR(L"Failed to load skeleton definitions from '%ls'", path.string().c_str());
+ return ERR::FAIL;
+ }
+
+ return INFO::OK;
+ }
+
+ static Status ReloadChangedFileCB(void* param, const VfsPath& path)
+ {
+ return static_cast(param)->ReloadChangedFile(path);
}
bool Convert(const VfsPath& daeFilename, const VfsPath& pmdFilename, CColladaManager::FileType type)
@@ -83,46 +133,14 @@ public:
// to get all the right libraries to build the COLLADA DLL), we load
// it dynamically when it is required, instead of using the exported
// functions and binding at link-time.
- if (! dll.IsLoaded())
+ if (!dll.IsLoaded())
{
- if (! dll.LoadDLL())
- {
- LOGERROR(L"Failed to load COLLADA conversion DLL");
+ if (!TryLoadDLL())
return false;
- }
- try
+ if (!LoadSkeletonDefinitions())
{
- dll.LoadSymbol("set_logger", set_logger);
- dll.LoadSymbol("set_skeleton_definitions", set_skeleton_definitions);
- dll.LoadSymbol("convert_dae_to_pmd", convert_dae_to_pmd);
- dll.LoadSymbol("convert_dae_to_psa", convert_dae_to_psa);
- }
- catch (PSERROR_DllLoader&)
- {
- LOGERROR(L"Failed to load symbols from COLLADA conversion DLL");
- dll.Unload();
- return false;
- }
-
- VfsPath skeletonPath("art/skeletons/skeletons.xml");
-
- // Set the filename for the logger to report
- set_logger(ColladaLog, static_cast(&skeletonPath));
-
- CVFSFile skeletonFile;
- if (skeletonFile.Load(m_VFS, skeletonPath) != PSRETURN_OK)
- {
- LOGERROR(L"Failed to read skeleton definitions");
- dll.Unload();
- return false;
- }
-
- int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize());
- if (ok < 0)
- {
- LOGERROR(L"Failed to load skeleton definitions");
- dll.Unload();
+ dll.Unload(); // Error should have been logged already
return false;
}
}
@@ -167,8 +185,133 @@ public:
return (result == 0);
}
+ bool TryLoadDLL()
+ {
+ if (!dll.LoadDLL())
+ {
+ LOGERROR(L"Failed to load COLLADA conversion DLL");
+ return false;
+ }
+
+ try
+ {
+ dll.LoadSymbol("set_logger", set_logger);
+ dll.LoadSymbol("set_skeleton_definitions", set_skeleton_definitions);
+ dll.LoadSymbol("convert_dae_to_pmd", convert_dae_to_pmd);
+ dll.LoadSymbol("convert_dae_to_psa", convert_dae_to_psa);
+ }
+ catch (PSERROR_DllLoader&)
+ {
+ LOGERROR(L"Failed to load symbols from COLLADA conversion DLL");
+ dll.Unload();
+ return false;
+ }
+ return true;
+ }
+
+ bool LoadSkeletonDefinitions()
+ {
+ VfsPaths pathnames;
+ if (vfs::GetPathnames(m_VFS, L"art/skeletons/", L"*.xml", pathnames) < 0)
+ {
+ LOGERROR(L"No skeleton definition files present");
+ return false;
+ }
+
+ bool loaded = false;
+ for (VfsPaths::const_iterator it = pathnames.begin(); it != pathnames.end(); ++it)
+ {
+ LOGMESSAGE(L"Loading skeleton definitions from '%ls'", it->string().c_str());
+ // Set the filename for the logger to report
+ set_logger(ColladaLog, const_cast(static_cast(&(*it))));
+
+ CVFSFile skeletonFile;
+ if (skeletonFile.Load(m_VFS, *it) != PSRETURN_OK)
+ {
+ LOGERROR(L"Failed to read skeleton defintions from '%ls'", it->string().c_str());
+ continue;
+ }
+
+ int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize());
+ if (ok < 0)
+ {
+ LOGERROR(L"Failed to load skeleton definitions from '%ls'", it->string().c_str());
+ continue;
+ }
+
+ loaded = true;
+ }
+
+ if (!loaded)
+ LOGERROR(L"Failed to load any skeleton definitions");
+
+ return loaded;
+ }
+
+ /**
+ * Creates MD5 hash key from skeletons.xml info and COLLADA converter version,
+ * used to invalidate cached .pmd/psas
+ *
+ * @param[out] hash resulting MD5 hash
+ * @param[out] version version passed to CCacheLoader, used if code change should force
+ * cache invalidation
+ */
+ void PrepareCacheKey(MD5& hash, u32& version)
+ {
+ // Add converter version to the hash
+ version = COLLADA_CONVERTER_VERSION;
+
+ // Cache the skeleton files hash data
+ if (m_skeletonHashInvalidated)
+ {
+ VfsPaths paths;
+ if (vfs::GetPathnames(m_VFS, L"art/skeletons/", L".xml", paths) != INFO::OK)
+ {
+ LOGWARNING(L"Failed to load skeleton definitions");
+ return;
+ }
+
+ // Sort the paths to not invalidate the cache if mods are mounted in different order
+ // (No need to stable_sort as the VFS gurantees that we have no duplicates)
+ std::sort(paths.begin(), paths.end());
+
+ // We need two u64s per file
+ m_skeletonHashes.clear();
+ m_skeletonHashes.resize(paths.size()*2);
+
+ FileInfo fileInfo;
+ for (VfsPaths::const_iterator it = paths.begin(); it != paths.end(); ++it)
+ {
+ // This will cause an assertion failure if *it doesn't exist,
+ // because fileinfo is not a NULL pointer, which is annoying but that
+ // should never happen, unless there really is a problem
+ if (m_VFS->GetFileInfo(*it, &fileInfo) != INFO::OK)
+ {
+ LOGERROR(L"Failed to stat '%ls' for DAE caching", it->string().c_str());
+ }
+ else
+ {
+ m_skeletonHashes.push_back((u64)fileInfo.MTime() & ~1); //skip lowest bit, since zip and FAT don't preserve it
+ m_skeletonHashes.push_back((u64)fileInfo.Size());
+ }
+ }
+
+ // Check if we were able to load any skeleton files
+ if (m_skeletonHashes.empty())
+ LOGERROR(L"Failed to stat any skeleton definitions for DAE caching");
+ // We can continue, something else will break if we try loading a skeletal model
+
+ m_skeletonHashInvalidated = false;
+ }
+
+ for (std::vector::const_iterator it = m_skeletonHashes.begin(); it != m_skeletonHashes.end(); ++it)
+ hash.Update((const u8*)&(*it), sizeof(*it));
+ }
+
private:
PIVFS m_VFS;
+ bool m_skeletonHashInvalidated;
+ std::vector m_skeletonHashes;
};
CColladaManager::CColladaManager(const PIVFS& vfs)
@@ -181,32 +324,6 @@ CColladaManager::~CColladaManager()
delete m;
}
-void CColladaManager::PrepareCacheKey(MD5& hash, u32& version)
-{
- // Include skeletons.xml file info in the hash
- VfsPath skeletonPath("art/skeletons/skeletons.xml");
- FileInfo fileInfo;
-
- // This will cause an assertion failure if skeletons.xml doesn't exist,
- // because fileinfo is not a NULL pointer, which is annoying but that
- // should never happen, unless there really is a problem
- if (m_VFS->GetFileInfo(skeletonPath, &fileInfo) != INFO::OK)
- {
- LOGERROR(L"Failed to stat '%ls' for DAE caching", skeletonPath.string().c_str());
- // We can continue, something else will break if we try loading a skeletal model
- }
- else
- {
- u64 skeletonsModifyTime = (u64)fileInfo.MTime() & ~1; // skip lowest bit, since zip and FAT don't preserve it
- u64 skeletonsSize = (u64)fileInfo.Size();
- hash.Update((const u8*)&skeletonsModifyTime, sizeof(skeletonsModifyTime));
- hash.Update((const u8*)&skeletonsSize, sizeof(skeletonsSize));
- }
-
- // Add converter version to the hash
- version = COLLADA_CONVERTER_VERSION;
-}
-
VfsPath CColladaManager::GetLoadablePath(const VfsPath& pathnameNoExtension, FileType type)
{
std::wstring extn;
@@ -255,22 +372,18 @@ VfsPath CColladaManager::GetLoadablePath(const VfsPath& pathnameNoExtension, Fil
CCacheLoader cacheLoader(m_VFS, extn);
MD5 hash;
u32 version;
- PrepareCacheKey(hash, version);
+ m->PrepareCacheKey(hash, version);
VfsPath cachePath;
VfsPath sourcePath = pathnameNoExtension.ChangeExtension(L".dae");
Status ret = cacheLoader.TryLoadingCached(sourcePath, hash, version, cachePath);
+
if (ret == INFO::OK)
- {
// Found a valid cached version
return cachePath;
- }
- else if (ret == INFO::SKIPPED)
- {
- // No valid cached version was found - but source .dae exists
- // We'll try converting it
- }
- else
+
+ // No valid cached version, check if we have a source .dae
+ if (ret != INFO::SKIPPED)
{
// No valid cached version was found, and no source .dae exists
ENSURE(ret < 0);
@@ -288,6 +401,9 @@ VfsPath CColladaManager::GetLoadablePath(const VfsPath& pathnameNoExtension, Fil
}
}
+ // No valid cached version was found - but source .dae exists
+ // We'll try converting it
+
// We have a source .dae and invalid cached version, so regenerate cached version
if (! m->Convert(sourcePath, cachePath, type))
{
diff --git a/source/graphics/ColladaManager.h b/source/graphics/ColladaManager.h
index 38cc8f8e6b..9995ddb044 100644
--- a/source/graphics/ColladaManager.h
+++ b/source/graphics/ColladaManager.h
@@ -61,16 +61,6 @@ public:
bool GenerateCachedFile(const VfsPath& sourcePath, FileType type, VfsPath& archiveCachePath);
private:
- /**
- * Creates MD5 hash key from skeletons.xml info and COLLADA converter version,
- * used to invalidate cached .pmd/psas
- *
- * @param[out] hash resulting MD5 hash
- * @param[out] version version passed to CCacheLoader, used if code change should force
- * cache invalidation
- */
- void PrepareCacheKey(MD5& hash, u32& version);
-
CColladaManagerImpl* m;
PIVFS m_VFS;
};