I'm going to try and summarize where I think we're at at the moment.
Totally ignore running unpacked for this. Assume everything gets repacked.
(1) First is .cas file format. This is what GOM posted:
Code:
Cas Anim format
Short - Num_Frame
short - Num_bone
num_frame * num_bone * float*4 (Quaternion rotations)
num_frame * num_bone * float*3 (local positon data - Pelvis in relation to Root Node ie height off ground, others unchanged from rest positions)
num_frame * float*2 (x and incremental z movement for Root Node)
2 * float (0?)
num_frame * float (approximate absolute z position of Root Node but in reverse order compared to animation ??)
num_frame * float *3 (absolute position of root node and pelvis height)
What works for me in doing animations in Milkshape is the following slightly different format:
Let FLOATBYTES = 4
Code:
5 byte header
short - num_frame
short - num_bone
byte - num_bone
quats:
num_frame * num_bone * 4 * FLOATBYTES
pose data:
num_frame * num_bone * 3 * FLOATBYTES
[Except for the bone_pelvis the data just repeats the skeleton pose over and over
for each frame. Isn't this the skeleton information, we don't need anything from
skeleton.dat to augment the cas files.]
global data:
num_frame * 3 * FLOATBYTES
[Don't know what this is for.]
relative data:
num_frame * 3 * FLOATBYTES
[This moves the guy forward in the z direction, i.e. out of the screen when
animating in Milkshape. I'll show a snippet in a moment.]
8 mystery floats data:
8 * FLOATBYTES
[The first entry is 0.05 * (num_frames-1), the animation time length in seconds.
Other seven floats I don't know.]
8 end bytes:
8
[These end the file, usually with the signature 255 255 15 0 0 0 0 0
or in hex FF FF 0F 00 00 00 00 00. This changes when the header bytes
change but that's for other anims like stratmap, legion_pole, etc.
Ignore other types of animation for right now and just do regular units.]
I use the utility casconverter.py to convert binary .cas files to a nice
ASCII format. Here's the relative data section for MTW2_Spear_run_to_charge.cas
Code:
+0.042779121548 +0.896650791168 +0.098638139665
+0.047644473612 +0.889466941357 +0.294535070658
+0.050987910479 +0.860747575760 +0.501587986946
+0.056217838079 +0.848554611206 +0.638711512089
+0.056164205074 +0.854174494743 +0.813530683517
+0.040740031749 +0.880190908909 +1.022136569023
+0.013633596711 +0.912660479546 +1.232632160187
-0.006605490111 +0.932232141495 +1.441531062126
-0.015281273983 +0.917331397533 +1.674659252167
-0.015948355198 +0.892094254494 +1.860179424286
-0.013512277976 +0.877519905567 +2.033008575439
-0.010928579606 +0.880254864693 +2.241550683975
-0.008396276273 +0.890842974186 +2.443597793579
-0.005408636294 +0.901573657990 +2.646682977676
-0.002154623857 +0.905263364315 +2.854587554932
+0.003916638903 +0.902066648006 +3.076904058456
+0.015629388392 +0.900002896786 +3.317394733429
+0.029411721975 +0.898095548153 +3.564741373062
+0.042934946716 +0.896170377731 +3.811233997345
Note how the z-component moves the animation forward out of the screen.
That's what I think the .cas format is. The animations work beautifully
in Milkshape using the quats converted to Mete's x, y, z euler rotations,
and the relative data put into bone_pelvis's position animation frames and
zeros for all the other bones.
(2) .skel file format
If you use skeletons.idx with its offset and length values you can
unpack skeletons.dat into 112 files. I put the .skel extension on
just to assign an editor to that extension. I hated having to use
open with on files with no extension.
Each one of these files defines the animation name, like
MTW2_Spear.skel is the definition for MTW2_Spear that you use
in the modeldb file.
I wrote a skelconverter.py just like the casconverter.py to pull this data
out and format it to understand what's there. These are sorta big files
so let's do this in sections. First is the header and bone data.
I'll show MTW2_Spear.skel converted to MTW2_Spear.txt.
The header is always a float 1.0 followed in this case by 20, the
number of bones, a byte 0, and a byte 63.
Each bone has 19 floats or ints defining it before the bone name occurs.
The second, third, and fourth entries are the bone pose data, the same
as in the .cas files. Remember the bone name FOLLOWS the data.
Code:
1.0 20 0 63
9 0.0 0.0 0.0 -1 9.63913977252e-036 -1
1.0 0 0 0.0
0 1.0 0 0.0
0 0 1.0 0.0
bone_pelvis
0 0.0952388122678 0.000752284366172 -7.68995533917e-009 0 0.0 -1
1.0 0 0 -0.0952388122678
0 1.0 0 -0.000752284366172
0 0 1.0 7.68995533917e-009
bone_RThigh
0 0.0225613098592 -0.464448839426 0.0143959810957 1 0.0 -1
1.0 0 0 -0.11780012399
0 1.0 0 0.463696569204
0 0 1.0 -0.0143959736452
bone_Rlowerleg
0 0.0241626594216 -0.399506568909 -0.0316339097917 2 0.0 -1
1.0 0 0 -0.141962781549
0 1.0 0 0.863203167915
0 0 1.0 0.0172379352152
bone_Rfoot
8 -6.93664681251e-009 0.212462007999 7.65448815443e-010 0 3.58732406867e-043 0
1.0 0 0 6.93664681251e-009
0 1.0 0 -0.212462007999
0 0 1.0 -7.65448815443e-010
bone_abs
7 -0.000294532976113 0.211557745934 2.989176906e-008 4 3.58732406867e-043 1
1.0 0 0 0.000294539902825
0 1.0 0 -0.424019753933
0 0 1.0 -3.06572189857e-008
bone_torso
6 -6.17081896053e-005 0.234973058105 6.67517667807e-008 5 0.0 2
1.0 0 0 0.000356248085154
0 1.0 0 -0.658992826939
0 0 1.0 -9.74089857664e-008
bone_head
0 0.000356251257472 0.0108101442456 -0.00344702485017 6 0.0 -1
1.0 0 0 -3.17231751978e-009
0 1.0 0 -0.669802963734
0 0 1.0 0.00344692752697
bone_jaw
0 0.0016836974537 0.117848232388 -0.0744606256485 6 0.0 -1
1.0 0 0 -0.00132744933944
0 1.0 0 -0.776841044426
0 0 1.0 0.074460528791
bone_eyebrow
0 0.0132546443492 0.130011349916 -0.0273839179426 5 0.0 -1
1.0 0 0 -0.0129601042718
0 1.0 0 -0.554031133652
0 0 1.0 0.0273838881403
bone_Rclavical
0 0.165358901024 -0.0517836585641 0.0034832842648 9 0.0 -1
1.0 0 0 -0.178319007158
0 1.0 0 -0.502247452736
0 0 1.0 0.0239006038755
bone_Rupperarm
0 0.302206397057 0.0111386608332 -0.0137691963464 10 0.0 -1
1.0 0 0 -0.480525404215
0 1.0 0 -0.513386130333
0 0 1.0 0.0376698002219
bone_Relbow
5 0.283836990595 -0.00305567588657 0.0263375118375 11 0.0 -1
1.0 0 0 -0.76436239481
0 1.0 0 -0.510330438614
0 0 1.0 0.0113322883844
bone_Rhand
0 -0.0102220894769 0.130011349916 -0.0273839179426 5 0.0 -1
1.0 0 0 0.0105166295543
0 1.0 0 -0.554031133652
0 0 1.0 0.0273838881403
bone_Lclavical
0 -0.167802318931 -0.0517838038504 0.00348335830495 13 0.0 -1
1.0 0 0 0.178318947554
0 1.0 0 -0.502247333527
0 0 1.0 0.0239005293697
bone_Lupperarm
0 -0.302173316479 0.0111954407766 -0.0144314421341 14 0.0 -1
1.0 0 0 0.480492264032
0 1.0 0 -0.513442754745
0 0 1.0 0.0383319705725
bone_Lelbow
4 -0.283801227808 -0.00320043438114 0.0267044473439 15 0.0 -1
1.0 0 0 0.76429349184
0 1.0 0 -0.510242342949
0 0 1.0 0.0116275232285
bone_Lhand
0 -0.0952387824655 0.000752363703214 2.19979003901e-008 0 0.0 -1
1.0 0 0 0.0952387824655
0 1.0 0 -0.000752363703214
0 0 1.0 -2.19979003901e-008
bone_LThigh
0 -0.0216093510389 -0.464143753052 0.0230784993619 17 0.0 -1
1.0 0 0 0.116848133504
0 1.0 0 0.463391393423
0 0 1.0 -0.0230785217136
bone_Llowerleg
0 -0.0250775031745 -0.398637682199 -0.0406115166843 18 0.0 -1
1.0 0 0 0.141925632954
0 1.0 0 0.862029075623
0 0 1.0 0.0175329949707
bone_Lfoot
Looks like an identity matrix with an augmented column for part of this,
rotation and translation?
After the bone data comes the cas file names and the sound event records that you
can use to extract the evt files if desired. This is pretty big, I'll only post
the first 20 entries. There's actually like 180 entries in all. I don't think
there's any information here at all other than the sound records for the
evt files. There's one int that changes from .cas to .cas file but I don't
know what it means.
Code:
data/animations/MTW2_Spear/MTW2_Spear_Stand_A_idle.cas
0 0 0 1.60000002384 0 0 20 0 2.68540969134e+038 0 0 1.0
1
SOUND_AMBIENT 0 0 human_whistle 0
data/animations/MTW2_Spear/MTW2_Spear_walk.cas
0 0 0 1.60000002384 0 0 9 0 2.68540969134e+038 0 0 1.0
4
SOUND_AMBIENT 5 7 human_armour_walk 0
SOUND_BANK 5 7 unit_march 0
SOUND_AMBIENT 15 17 human_armour_walk 0
SOUND_BANK 15 17 unit_march 0
data/animations/MTW2_Spear/MTW2_Spear_walk_to_stand_A.cas
0 0 0 1.60000002384 0 0 22 0 2.68540969134e+038 0 0 1.0
4
SOUND_BANK 7 9 unit_march 0
SOUND_BANK 19 21 unit_march 0
SOUND_BANK 31 33 unit_march 0
SOUND_BANK 40 42 unit_march 0
data/animations/MTW2_Spear/MTW2_Spear_stealthy_walk.cas
0 0 0 1.60000002384 0 0 20 0 2.68540969134e+038 0 0 1.0
0
data/animations/MTW2_Spear/MTW2_Spear_stealthy_walk_to_stand_A.cas
0 0 0 1.60000002384 0 0 12 0 2.68540969134e+038 0 0 1.0
1
SOUND_BANK 20 22 unit_march 0
data/animations/MTW2_Spear/MTW2_Spear_stealthy_walk_to_hide.cas
0 0 0 1.60000002384 0 0 20 0 2.68540969134e+038 0 0 1.0
0
data/animations/MTW2_Spear/MTW2_Spear_stealthy_walk_to_walk.cas
0 0 0 1.60000002384 0 0 17 0 2.68540969134e+038 0 0 1.0
1
SOUND_BANK 34 34 unit_march 0
data/animations/MTW2_Spear/MTW2_Spear_run.cas
0 0 0 1.60000002384 0 0 7 0 2.68540969134e+038 0 0 1.0
4
SOUND_AMBIENT 2 4 human_armour_run 0
SOUND_BANK 2 4 unit_run 0
SOUND_AMBIENT 10 12 human_armour_run 0
SOUND_BANK 10 12 unit_run 0
data/animations/MTW2_Spear/MTW2_Spear_run_to_stand_A.cas
0 0 0 1.60000002384 0 0 17 0 2.68540969134e+038 0 0 1.0
4
SOUND_BANK 2 3 unit_march 0
SOUND_BANK 10 11 unit_march 0
SOUND_BANK 17 18 unit_march 0
SOUND_BANK 29 30 unit_march 0
data/animations/MTW2_Spear/MTW2_Spear_run_to_walk.cas
0 0 0 1.60000002384 0 0 13 0 2.68540969134e+038 0 0 1.0
3
SOUND_BANK 2 4 unit_march 0
SOUND_BANK 13 15 unit_march 0
SOUND_BANK 22 24 unit_march 0
data/animations/MTW2_Spear/MTW2_Spear_walk_to_run.cas
0 0 0 1.60000002384 0 0 8 0 2.68540969134e+038 0 0 1.0
1
SOUND_BANK 8 10 unit_march 0
data/animations/MTW2_Spear/MTW2_Spear_ready_to_stand_A.cas
0 0 0 1.60000002384 0 0 12 0 2.68540969134e+038 0 0 1.0
1
SOUND_BANK 18 20 unit_march 0
data/animations/MTW2_Spear/MTW2_Spear_ready_idle.cas
0 0 0 1.60000002384 0 0 14 0 2.68540969134e+038 0 0 1.0
1
SOUND 0 0 ANIM_Human_ready 0
data/animations/MTW2_Spear/MTW2_Spear_ready_hf_idle_1.cas
0 0 0 1.60000002384 0 0 15 0 2.68540969134e+038 0 0 1.0
0
data/animations/MTW2_Spear/MTW2_Spear_ready_hf_idle_2.cas
0 0 0 1.60000002384 0 0 22 0 2.68540969134e+038 0 0 1.0
1
SOUND_BANK 30 30 unit_march 0
EDIT: There's some more stuff at the bottom of the file.
Don't know what it is.
This is what we know so far.
(3) Thought experiment of making a dwarf unit.
Decide on a reduced skeleton but still with the 20 bones. Make a
.skems3d file for my mesh converter or a similar binary one for GOM's
converter. Take an 2HAxe unit mesh and convert to Milkshape using
the new skeleton. Do that modeller magic to make a dwarf out of it
and convert back and call it dwarfwarrior_lod0.mesh and the higher lods.
Hard part. Since a dwarf they have to be 2H Axe guys so copy
the unpacked cas files in MTW2_2H_Axe into a new directory
MTW2_2H_Dwarf and then rename the animations in some automated way.
Write a script to edit each cas file and replace the pose data
for each frame with the new skeleton values. Ok, cas's are done.
Unpack skeleton.dat and copy MTW2_2H_Axe.skel to MTW2_2H_Dwarf.skel.
Convert it to ASCII using skelconverter.py and change the skeleton
data at the top to the new bones.
Big question here is what are those other floats used for.
(Good thing this is only a thought experiment.)
Convert MTW2_2H_Dwarf.txt back to binary MTW2_2H_Dwarf.skel.
Add it to the repackingdata.txt file to append it to the end
of skeletons.dat. Now repack skeletons.dat.
Also repack pack.dat again adding the units to the repacking list
for this. (Just copy the MTW2_2H_Axe section and put Dwarf on them.)
Put it in EDU and modeldb, unit cards, all that stuff. The animation
name at the end of the modeldb entry would be MTW2_2H_Dwarf.
Voila! MAYBE this would work.
So my question is: is this what we are trying to do or have I missed
the point completely?
Bookmarks