Ok, here's how to do keyframing work without a keyframer. You run the
GameObjectApplicationToolbox.py script by double-clicking on it in explorer.
Choose the "Convertcastotxt" button (third button down on the right
side). In the File Chooser select the .cas file to convert, in this
case
MTW2_Pike_advance_level.cas
This will produce a .txt file of the same name in the same directory
MTW2_Pike_advance_level.txt
This can be opened in any text editor like Notepad. Here's the top part:
Code:
3.210000 38 9 0 1.04999995232 1 0 0 0 0 1 0 102 102 102
13060 0
21 0 0 1 2 3 1 5 6 7 7 6 10 11 12 6 14 15 16 1 18 19
21 0.00000 0.05000 0.10000 0.15000 0.20000 0.25000 0.30000 0.35000 0.40000 0.45000 0.50000 0.55000 0.60000 0.65000 0.70000 0.75000 0.80000 0.85000 0.90000 0.95000 1.00000
Scene_Root 0 0 0 6720 0 1 0
bone_pelvis 21 21 0 6720 0 1 0
bone_RThigh 21 21 336 6972 0 1 0
bone_Rlowerleg 21 21 672 7224 0 1 0
bone_Rfoot 21 21 1008 7476 0 1 0
bone_abs 21 21 1344 7728 0 1 0
bone_torso 21 21 1680 7980 0 1 0
bone_head 21 21 2016 8232 0 1 0
bone_jaw 21 21 2352 8484 0 1 0
bone_eyebrow 21 21 2688 8736 0 1 0
bone_Rclavical 21 21 3024 8988 0 1 0
bone_Rupperarm 21 21 3360 9240 0 1 0
bone_Relbow 21 21 3696 9492 0 1 0
bone_Rhand 21 21 4032 9744 0 1 0
bone_Lclavical 21 21 4368 9996 0 1 0
bone_Lupperarm 21 21 4704 10248 0 1 0
bone_Lelbow 21 21 5040 10500 0 1 0
bone_Lhand 21 21 5376 10752 0 1 0
bone_LThigh 21 21 5712 11004 0 1 0
bone_Llowerleg 21 21 6048 11256 0 1 0
bone_Lfoot 21 21 6384 11508 0 1 0
I won't spend too much time here because we don't want to modify any of this.
The top line is the header of a .cas file. The first float, 3.21000, is the version
number. The 1.04999 is really 1.05, the length of the animation in seconds.
(21 frames time 0.05 seconds per frame is 1.05.) The second line with the 13060
is the chunk size in bytes of the file, basically the file size minus the size
of the header and footer. The third line is the bone hierarchy for 21 bones, the
20 usual bones plus 1 for Scene_Root, the root bone found in .cas files.
The fourth line are the time ticks of the animation going from 0.0 to 1.0.
Next come the bone names and several columns of data. First column are names,
second column the number of rotation frames, third is number of position frames,
fourth and fifth are offsets in bytes to where the data is, and then some more columns
which we'll skip.
On to the rotation keyframes. Below the bit I showed above is the actual data
for the rotation keyframes. .cas files store this as quaternions but that's a little
hard for most of us to visualize so I convert the quats to Milkshape Euler angles
in degrees and write out both. Here's the keyframes for bone_pelvis:
Code:
0 bone_pelvis quaternion data and Milkshape euler angles
+0.0359911174 +0.1861125529 +0.0129105933 +0.9817841053 +4.6491146807 -21.3777595644 -2.3847970475
+0.0452478752 +0.1842074990 +0.0366826244 +0.9811598063 +6.2907651619 -20.9868917438 -5.4485520377
+0.0422854945 +0.1819241792 +0.0395931974 +0.9816047549 +5.9786758895 -20.7203367813 -5.7135223964
+0.0189136527 +0.1653417349 +0.0077497289 +0.9860244989 +2.4163796288 -19.0121628189 -1.3053071003
+0.0129362186 +0.1500629038 -0.0063095223 +0.9885717034 +1.4211447607 -17.2690524389 +0.5155516965
+0.0159254130 +0.1302146614 -0.0177047625 +0.9911997914 +1.5993224115 -14.9930216716 +1.8361420388
+0.0239474047 +0.1168485656 -0.0183651950 +0.9926910996 +2.5491034379 -13.4660210383 +1.8187604880
+0.0341287106 +0.1089670956 -0.0024901116 +0.9934561849 +3.9510992297 -12.5139925595 -0.1461489594
+0.0421253070 +0.0961932912 +0.0235358328 +0.9941923022 +5.1587044226 -10.9111392604 -3.2052756560
+0.0453248061 +0.0934590176 +0.0289297961 +0.9941700697 +5.5764212898 -10.5565465746 -3.8491898190
+0.0441512577 +0.0962586179 +0.0138846142 +0.9942797422 +5.2874487927 -10.9638691746 -2.1079071550
+0.0410093963 +0.0985871479 -0.0067886035 +0.9942598939 +4.6923817947 -11.3381643949 +0.3163328743
+0.0448558517 +0.0958925188 -0.0055649662 +0.9943649173 +5.1518473395 -11.0230305656 +0.1438616865
+0.0524983667 +0.1139110848 +0.0320142135 +0.9915862679 +6.5616666861 -12.8584953484 -4.4386018472
+0.0526245795 +0.1174385622 +0.0349323936 +0.9910693765 +6.6375663095 -13.2442627252 -4.8087989540
+0.0510141067 +0.1293480545 +0.0355125479 +0.9896491766 +6.5370054343 -14.6192873806 -4.9496609335
+0.0461298786 +0.1382496357 +0.0264909398 +0.9889677763 +5.8773103327 -15.7240687713 -3.8810415524
+0.0355201550 +0.1435534060 +0.0095693376 +0.9889586568 +4.3656323750 -16.4546872767 -1.7402967689
+0.0212689433 +0.1711403877 -0.0070993681 +0.9849914908 +2.4030483802 -19.7213242850 +0.4081507071
+0.0237362534 +0.1794726700 -0.0048454227 +0.9834645987 +2.7538737899 -20.6856206373 +0.0618923461
+0.0359911174 +0.1861125529 +0.0129105933 +0.9817841053 +4.6491146807 -21.3777595644 -2.3847970475
The first four columns are the quaternions, last three are Euler angles in x, y, and z order, in degrees.
The way it works is you modify the angles and when back converting the script ignores the
quaternions and converts the Milkshape angles back to new quaternions and writes those
into the new .cas file. This is how you can modify the keyframes.
Now bone_pelvis looks fine, no glitches here. In fact, page down through bone_RThigh,
bone_Rlowerleg, bone_Rfoot, bone_abs, bone_torso, bone_head, bone_jaw, bone_eyebrow,
bone_Rclavical, and bone_Rupperarm. They all look fine so I won't show them here.
Now look at bone_Relbow, just the first few keyframes:
Code:
11 bone_Relbow quaternion data and Milkshape euler angles
+0.0027312329 -0.2731546164 +0.0214967914 +0.9617260695 -0.4371054265 +31.7030709383 -2.6850724406
-0.0711576417 -0.7427593470 +0.0818803832 +0.6607123017 -117.7589909519 +75.8942685098 -118.6344709393
-0.0711576343 -0.7427592874 +0.0818803757 +0.6607123613 -117.7589636311 +75.8942753400 -118.6344436185
-0.0711576343 -0.7427592874 +0.0818803757 +0.6607123613 -117.7589636311 +75.8942753400 -118.6344436185
-0.0711576343 -0.7427592874 +0.0818803757 +0.6607123613 -117.7589636311 +75.8942753400 -118.6344436185
The red first frame is definitely part of the "glitch" you're seeing. So copy the second
key frame and delete the first key frame so you have
Code:
11 bone_Relbow quaternion data and Milkshape euler angles
-0.0711576417 -0.7427593470 +0.0818803832 +0.6607123017 -117.7589909519 +75.8942685098 -118.6344709393
-0.0711576417 -0.7427593470 +0.0818803832 +0.6607123017 -117.7589909519 +75.8942685098 -118.6344709393
-0.0711576343 -0.7427592874 +0.0818803757 +0.6607123613 -117.7589636311 +75.8942753400 -118.6344436185
-0.0711576343 -0.7427592874 +0.0818803757 +0.6607123613 -117.7589636311 +75.8942753400 -118.6344436185
-0.0711576343 -0.7427592874 +0.0818803757 +0.6607123613 -117.7589636311 +75.8942753400 -118.6344436185
The new red first frame replaces the bad keyframe but you still have 21 frames for this bone.
The same problem occurs for bone_Rhand:
Code:
12 bone_Rhand quaternion data and Milkshape euler angles
-0.0711576343 -0.7427592874 +0.0818803757 +0.6607123613 -117.7589636311 +75.8942753400 -118.6344436185
+0.0101752775 +0.1596707702 -0.2204553485 +0.9621856213 -3.0659306189 -18.1648590693 +26.2998995312
+0.0101752775 +0.1596707702 -0.2204553485 +0.9621856213 -3.0659306189 -18.1648590693 +26.2998995312
+0.0101752775 +0.1596707702 -0.2204553485 +0.9621856213 -3.0659306189 -18.1648590693 +26.2998995312
+0.0101752775 +0.1596707702 -0.2204553485 +0.9621856213 -3.0659306189 -18.1648590693 +26.2998995312
Same solution, copy the good second keyframe values and delete the bad first frame so that
you end up with 21 good frames. Repeat for bone_Lclavical, bone_Lupperarm, bone_Lelbow,
and bone_Lhand.
Now we come to bone_LThigh. This gets interesting so I'll show the whole entry:
Code:
17 bone_LThigh quaternion data and Milkshape euler angles
-0.0081541529 -0.0539951548 -0.0931290835 +0.9941554070 -0.3548216840 +6.2506369468 +10.6839364328
-0.3135873079 -0.2903384566 -0.0319196284 +0.9035196304 -40.8125488759 +33.0022651260 -8.5312708347
-0.2785103023 -0.2977492511 -0.0440053456 +0.9120531678 -35.8209749135 +34.5856908058 -5.9668340490
-0.2299130857 -0.3079921305 -0.0393587835 +0.9223511815 -29.5772531063 +35.8914897864 -4.8871446389
-0.1462429315 -0.3401504755 -0.0080502890 +0.9288949370 -20.1416985227 +39.3668027343 -6.2774629416
-0.1036637649 -0.3524932563 +0.0015064689 +0.9300537705 -14.8742378518 +40.9471821497 -5.7660337445
-0.0637732372 -0.3406051695 +0.0086891297 +0.9380008578 -9.3828818723 +39.6329956968 -4.4491702843
-0.0332119726 -0.3033235073 +0.0076715224 +0.9522777796 -4.7701200196 +35.2529251557 -2.4395102779
+0.0007814851 -0.2596846521 -0.0071375719 +0.9656667709 +0.3454649384 +30.1010466534 +0.9398636984
+0.0743451640 -0.2032247186 -0.0318042003 +0.9757874012 +9.8898415644 +23.0714825540 +5.7569564231
+0.1082658917 -0.1750962585 -0.0469822362 +0.9774520397 +13.9945419301 +19.3976979692 +7.9071768134
+0.0830243677 -0.1645217985 -0.0565966964 +0.9812422395 +11.0224474382 +18.2686950202 +8.3797994370
-0.0152230021 -0.1544868201 -0.0668562204 +0.9856126904 -0.5628938187 +17.8522737544 +7.6726921504
-0.1626888365 -0.1362153441 -0.0832804590 +0.9736745358 -17.9123264852 +16.9990840894 +7.0790761407
-0.3695906103 -0.1503919512 -0.0903780982 +0.9124783874 -43.5228499008 +19.9539400375 +3.2792969774
-0.3874243796 -0.1564243883 -0.0880874693 +0.9042534828 -45.9621085289 +20.5576126469 +2.3321753492
-0.3960159719 -0.1793194711 -0.0696822107 +0.8978642821 -47.8058600388 +22.1603284885 -1.0453660020
-0.3553634286 -0.1639790386 -0.0590253100 +0.9183374643 -42.3970639709 +20.0675073004 -0.4961728490
-0.3606556952 -0.1648182273 -0.0403692648 +0.9171329141 -43.3983492126 +19.3561550512 -2.7239214894
-0.3649627268 -0.2295900285 -0.0247732513 +0.9019295573 -45.8439872374 +25.6092086042 -7.8328916760
-0.3515519798 -0.2539477348 -0.0253855959 +0.9007093310 -44.8413871842 +28.3798560580 -8.6828660295
We can't just copy the second keyframe here because the frames are changing. This is a
looping animation so we want to "linearly interpolate" between the last keyframe and the
second keyframe. So for the x rotation I'll pick -42.8 as being halfway between -44.84
(the last keyframe x) and -40.81 (the second keyframe). Similarly for the y and the z.
So my new first keyframe would be something like:
Code:
17 bone_LThigh quaternion data and Milkshape euler angles
-0.0081541529 -0.0539951548 -0.0931290835 +0.9941554070 -42.8548216840 +31.2506369468 -8.6139364328
-0.3135873079 -0.2903384566 -0.0319196284 +0.9035196304 -40.8125488759 +33.0022651260 -8.5312708347
-0.2785103023 -0.2977492511 -0.0440053456 +0.9120531678 -35.8209749135 +34.5856908058 -5.9668340490
That's just roughing it out for the first few significant digits, little half degree differences won't
be noticeable.
bone_Llowerleg requires the same treatment:
Code:
18 bone_Llowerleg quaternion data and Milkshape euler angles
-0.3135873377 -0.2903382778 -0.0319198929 +0.9035196304 -40.8125352155 +33.0022514656 -8.5312298536
+0.2878805399 +0.0901421756 +0.0485884547 +0.9521755576 +34.2514418384 -8.2612546738 -8.3919640039
+0.2880963683 +0.1072372198 +0.0556050837 +0.9499519467 +34.5908544288 -9.8867432198 -9.7853567456
+0.2766011953 +0.1221724972 +0.0595879853 +0.9513227344 +33.4993458032 -11.5069460532 -10.6420537128
should go to something like:
Code:
18 bone_Llowerleg quaternion data and Milkshape euler angles
-0.3135873377 -0.2903382778 -0.0319198929 +0.9035196304 +35.8125352155 -6.0022514656 -7.0312298536
+0.2878805399 +0.0901421756 +0.0485884547 +0.9521755576 +34.2514418384 -8.2612546738 -8.3919640039
+0.2880963683 +0.1072372198 +0.0556050837 +0.9499519467 +34.5908544288 -9.8867432198 -9.7853567456
+0.2766011953 +0.1221724972 +0.0595879853 +0.9513227344 +33.4993458032 -11.5069460532 -10.6420537128
And bone_Lfoot:
Code:
19 bone_Lfoot quaternion data and Milkshape euler angles
+0.2878805101 +0.0901420563 +0.0485892780 +0.9521755576 +34.2514418384 -8.2612136926 -8.3920502351
-0.0289541371 +0.0109546594 -0.0896497965 +0.9954921007 -3.4179801265 -0.9522474717 +10.3202792321
-0.0662014484 +0.0151521685 -0.1078526527 +0.9918445349 -7.7359670228 -0.9040037112 +12.4729815424
should go to something like:
Code:
19 bone_Lfoot quaternion data and Milkshape euler angles
+0.2878805101 +0.0901420563 +0.0485892780 +0.9521755576 -3.0514418384 -0.7812136926 +8.3920502351
-0.0289541371 +0.0109546594 -0.0896497965 +0.9954921007 -3.4179801265 -0.9522474717 +10.3202792321
-0.0662014484 +0.0151521685 -0.1078526527 +0.9918445349 -7.7359670228 -0.9040037112 +12.4729815424
If you save your changes and back convert using the converttxttocas button (fourth down on right
hand side) you should have a .cas file with no glitches. You can animmerge to check it out.
While on the subject, after the rotation data for bone_Lfoot comes the position animation frames
for bone_pelvis, shown below:
Code:
0 bone_pelvis animation data and deltas
+0.0000089781 +0.9089912176 -0.0000567846
-0.0119566014 +0.9362711310 +0.0770919174
-0.0188270491 +0.9536758661 +0.1445211619
-0.0227415580 +0.9556493163 +0.2371863872
-0.0248528998 +0.9503000379 +0.2990277708
-0.0260876603 +0.9372131228 +0.3798140585
-0.0218601450 +0.9144630432 +0.4702308476
-0.0109665627 +0.8891604543 +0.5713204145
+0.0079560671 +0.8697217107 +0.7156654000
+0.0203840956 +0.8796760440 +0.8177018166
+0.0290276278 +0.9047831297 +0.8947846889
+0.0362256058 +0.9322296977 +0.9549288154
+0.0413517728 +0.9499911070 +1.0092128515
+0.0424700268 +0.9463566542 +1.1409735680
+0.0423726998 +0.9442256689 +1.1588103771
+0.0409461260 +0.9320024848 +1.2297110558
+0.0356029756 +0.9121266007 +1.3017691374
+0.0285389069 +0.8945383430 +1.3617962599
+0.0109724132 +0.8757258058 +1.5074499846
+0.0064266389 +0.8848003149 +1.5499432087
+0.0002717352 +0.9089912176 +1.6206053495
These are in x, y, z order. Note the third column, the z's. The z-axis points out of the computer
screen so these values are what makes the unit move forward, in fact the unit moves 1.62 meters
in 1.05 seconds. You can adjust these slightly higher to make the unit move faster or lower
to slow it down. (You can't adjust too much or the unit will look like it is speed skating.)
Likewise, if you add 10.0 to each entry in the second column, the y-axis or vertical axis, you can
make your unit fly 10 meters above the ground.
Note that the position entries for all the other bones are zero or nearly zero. This is the
usual way CA does animations, only bone_pelvis ever moves, all other bones simply rotate relative
to bone_pelvis.
Finally, the last bit of data in a .cas file is the basepose data:
Code:
0 skeleton pose data, all bones including Scene_Root
+0.0000000000 +0.0000000000 +0.0000000000
+0.0000000000 +0.0000000000 +0.0000000000
+0.0952388123 +0.0007522846 -0.0000000077
+0.0225613099 -0.4644489586 +0.0143959792
+0.0241626594 -0.3995067179 -0.0316339023
-0.0000000069 +0.2124620527 +0.0000000008
-0.0002945330 +0.2115577906 +0.0000000299
-0.0000617082 +0.2349731028 +0.0000000668
+0.0003562596 +0.0108105801 -0.0034470388
+0.0016836961 +0.1178482771 -0.0744605809
+0.0132546443 +0.1300113499 -0.0273839142
+0.1653589010 -0.0517836586 +0.0034832826
+0.3022063971 +0.0111386608 -0.0137691945
+0.2838369906 -0.0030556759 +0.0263375100
-0.0102220895 +0.1300113499 -0.0273839142
-0.1678023189 -0.0517838039 +0.0034833583
-0.3021733165 +0.0111954408 -0.0144314393
-0.2838012278 -0.0032003860 +0.0267044436
-0.0952387825 +0.0007523639 +0.0000000220
-0.0216093510 -0.4641438425 +0.0230784956
-0.0250775032 -0.3986377716 -0.0406115167
This is where the skeleton for human units exists, it isn't in the .mesh file. All .cas files for
humans have this exact skeleton.
And since we've gone this far, the very last thing in a .cas file is the footer, a collection
of ints, floats, and a node string:
Code:
104 1 1 CaozSceneCustomAttribNode 1 0 1 0 0 0.00000 0.00000 0.00000 1.00000 0.00000 0.00000 0.00000 0 0 -1 0 0 1 16 2 0 0 16 3 0 0 16 8 0 0 16 10 0 0 12 5 0 12 12 0
And that is the basics for keyframing without a keyframer.
Bookmarks