C'mon guys, no turning back now![]()
Naw, not turning back, just finishing up things before the plunge.
Found out a little more today. The 8 floats before the final 8 signature
bytes follow this form:
first is the length of time of the animation, e.g. an 11 frame animation
is 0.5 seconds (1/20 of a second per frame, first frame starts at 0.0), a
91 frame animation is 4.5 seconds, etc.
second SEEMS to be the maximum excursion of all the entries in the relative
block or, same thing, the maximum excursion of bone_pelvis.
third, fourth, and fifth are just the last frame of the relative positions,
sort of like a registration position.
sixth, seventh, and eighth: no clue. They're not the same as any other
entry when they're non-zero. For the stationary animations (non walking,
running) they're usually zeros.
Anyway, just finishing up a little utility to convert binary .cas files to an
editable text form that can be converted back to .cas by the same
converter. Not the way I would want to do it, but it might be fun for
people to play with until the Milkshape stuff is sorted out. Just need to
add a script to turn Euler angles into quaternions that people can use
to change entries.
Last edited by KnightErrant; 04-14-2007 at 02:19.
Hi KE
Here is some more code to work with quats and eulers:-
Should be enough to fill in your weekendCode:; Change these constants if you notice slips in accuracy Const QuatToEulerAccuracy# = 0.001 Const QuatSlerpAccuracy# = 0.0001 ;convert a Rotation to a Quat Function EulerToQuat(pitch#,yaw#,roll#) ;NB roll is inverted due to change in handedness of coordinate systems Local cr# = Cos(-roll/2) Local cp# = Cos(pitch/2) Local cy# = Cos(yaw/2) Local sr# = Sin(-roll/2) Local sp# = Sin(pitch/2) Local sy# = Sin(yaw/2) ;These variables are only here to cut down on the number of multiplications Local cpcy# = cp * cy Local spsy# = sp * sy Local spcy# = sp * cy Local cpsy# = cp * sy ;Generate the output quat w# = cr * cpcy + sr * spsy vectorx = sr * cpcy - cr * spsy vectory = cr * spcy + sr * cpsy vectorz = cr * cpsy - sr * spcy End Function ; convert a Quat to a Rotation Function QuatToEuler(quatx#,quaty#,quatz#,quatw#) Local sint#, cost#, sinv#, cosv#, sinf#, cosf# Local cost_temp# sint = (2 * quatw * quaty) - (2 * quatx * quatz) cost_temp = 1.0 - (sint * sint) If Abs(cost_temp) > QuatToEulerAccuracy cost = Sqr(cost_temp) Else cost = 0 EndIf If Abs(cost) > QuatToEulerAccuracy sinv = ((2 * quaty * quatz) + (2 * quatw * quatx)) / cost cosv = (1 - (2 * quatx * quatx) - (2 * quaty * quaty)) / cost sinf = ((2 * quatx * quaty) + (2 * quatw * quatz)) / cost cosf = (1 - (2 * quaty * quaty) - (2 * quatz * quatz)) / cost Else sinv = (2 * quatw * quatx) - (2 * quaty * quatz) cosv = 1 - (2 * quatx * quatx) - (2 * quatz * quatz) sinf = 0 cosf = 1 EndIf ;Generate the output rotation vectorx = -ATan2(sinv, cosv) ; inverted due to change in handedness of coordinate system vectory = ATan2(sint, cost) vectorz = ATan2(sinf, cosf) End Function ;use this to interpolate between quaternions Function QuatSlerp(Ax#,Ay#,Az#,Aw#,Bx#,By#,Bz#,Bw#,t#) Local scaler_w#, scaler_x#, scaler_y#, scaler_z# Local omega#, cosom#, sinom#, scale0#, scale1# cosom = Ax * Bx + Ay * By + Az * Bz + Aw * Bw If cosom <= 0.0 cosom = -cosom scaler_w = -Bw scaler_x = -Bx scaler_y = -By scaler_z = -Bz Else scaler_w = Bw scaler_x = Bx scaler_y = By scaler_z = Bz EndIf If (1 - cosom) > QuatSlerpAccuracy omega = ACos(cosom) sinom = Sin(omega) scale0 = Sin((1 - t) * omega) / sinom scale1 = Sin(t * omega) / sinom Else ;Angle too small: use linear interpolation instead scale0 = 1 - t scale1 = t EndIf vectorx# = scale0 * start\x + scale1 * scaler_x vectory# = scale0 * start\y + scale1 * scaler_y vectorz# = scale0 * start\z + scale1 * scaler_z w# = scale0 * start\w + scale1 * scaler_w Return w# End Function ; result will be the same rotation as doing q1 then q2 (order matters!) Function MultiplyQuat#(Ax#,Ay#,Az#,Aw#,Bx#,By#,Bz#,Bw#) Local a#, b#, c#, d#, e#, f#, g#, h# a = (Aw + Ax) * (Bw + Bx) b = (Az - Ay) * (By - Bz) c = (Aw - Ax) * (By + Bz) d = (Ay + Az) * (Bw - Bx) e = (Ax + Az) * (Bx + By) f = (Ax - Az) * (Bx - By) g = (Aw + Ay) * (Bw - Bz) h = (Aw - Ay) * (Bw + Bz) w# = b + (-e - f + g + h) / 2 vectorx# = a - ( e + f + g + h) / 2 vectory# = c + ( e - f + g - h) / 2 vectorz# = d + ( e - f - g + h) / 2 Return w# End Function![]()
![]()
edit :- If you haven't looked already
http://www.gamasutra.com/features/19...ernions_01.htm ,
most of the code is based on this.
Cheers
GrumpyOldMan
Last edited by GrumpyOldMan; 04-14-2007 at 02:54.
Many thanks for the references, most of the quaternion stuff I've
got is from memos at work. There's a group that uses them for attitude
control for reentry vehicles in simulations which doesn't really
translate easily to moving bones around. Oh, it did hit me yesterday about
the cyclic permutation for the yaw, pitch, and roll, of course Mete's
convention has the y-axis as the vertical. D'oh!
Edit: Went and joined, lots of refs on quaternions in gaming. Even a few
physics ones!
Last edited by KnightErrant; 04-14-2007 at 04:07.
Well, I tested unpacking all the cas files and found examples
violating almost all of the rules from a couple posts back.
The first of the last eight floats is the animation time in
seconds. The header in descr_skeletons.dat say there will always
be an odd number of frames so this number will always be a multiple
of a tenth of a second. Otherwise the remaining seven floats I have
no rules for.
The header bytes aren't always 20 0 20 (14 00 14 hex), they have lots
of variations especially for the stratmap anims. The final 8 bytes aren't
always FF FF 0F 00 00 00 00 00 they have lots of variations too.
Here's a chunk with some stratmap examples from the extraction log:
The header and trailers are in decimal and I'm showing the three headerCode:31 20 20 data/animations/MTW2_Swordsman/MTW2_Swordsman_at_mid_c_stab_v1_s1_slashrl_fail.cas 39586546 18149 255 255 15 0 0 0 0 0 47 20 20 data/animations/MTW2_Swordsman/MTW2_Swordsman_at_mid_c_stab_v1_s1_slashrl_success.cas 39604695 27493 255 255 15 0 0 0 0 0 23 20 20 data/animations/MTW2_Swordsman/MTW2_Swordsman_at_overhead_c_stab_fail.cas 39632188 13477 255 255 15 0 0 0 0 0 29 20 20 data/animations/MTW2_Swordsman/MTW2_Swordsman_at_overhead_c_stab_success.cas 39645665 16981 255 255 15 0 0 0 0 0 55 20 1 data/animations/MTW2_Swordsman/MTW2_Swordsman_basepose.cas 39662646 19625 1 0 0 0 0 0 0 0 41 20 20 data/animations/MTW2_Swordsman/MTW2_Swordsman_charge_jump_attack.cas 39682271 23989 255 255 15 0 0 0 0 0 99 20 1 data/animations/New_Crew/Crew_Stand_to_Wide_Push.CAS 39706260 35289 1 0 0 0 0 0 0 0 25 20 1 data/animations/New_Crew/Crew_Wide_Push.CAS 39741549 8945 1 0 0 0 0 0 0 0 39 20 1 data/animations/New_Crew/Crew_Wide_Push_to_Crew_Stand.CAS 39750494 13929 1 0 0 0 0 0 0 0 67 2 1 data/animations/New_Swordman/Weapon/Sword_Default.CAS 39764423 4601 1 0 0 0 0 0 0 0 59 19 1 data/animations/SM_D01 Diplomat unselected idle 01.cas 39769024 20105 1 0 0 0 0 0 0 0 51 19 1 data/animations/SM_D01 Diplomat unselected idle 02.cas 39789129 17385 1 0 0 0 0 0 0 0 45 19 1 data/animations/SM_D01 Diplomat unselected idle 03.cas 39806514 15345 1 0 0 0 0 0 0 0 21 19 1 data/animations/SM_D03 Diplomat selected idle.cas 39821859 7185 1 0 0 0 0 0 0 0 25 19 1 data/animations/SM_D06 Diplomat walk loop.cas 39829044 8545 1 0 0 0 0 0 0 0 35 19 1 data/animations/SM_D11 Diplomat standing to stepping backwards.cas 39837589 11945 1 0 0 0 0 0 0 0 35 19 1 data/animations/SM_D12 Diplomat stepping backwards loop.cas 39849534 11945 1 0 0 0 0 0 0 0 25 19 1 data/animations/SM_D13 Diplomat stepping backwards to stand.cas 39861479 8545 1 0 0 0 0 0 0 0 23 19 1 data/animations/STRAT LID_08_Stand 2 90 right.cas 39870024 7865 1 0 0 0 0 0 0 0 23 19 1 data/animations/STRAT LID_09_Stand 2 90 left.cas 39877889 7865 1 0 0 0 0 0 0 0 107 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_assassinate.cas 39885754 59537 255 255 7 0 0 0 0 0 25 19 1 data/animations/Stratmap_Assassin/Strat_Assassin_basepose.cas 39945291 8545 1 0 0 0 0 0 0 0 39 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_die_backward_1.cas 39953836 21729 255 255 7 0 0 0 0 0 83 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_die_forward_1.cas 39975565 46193 255 255 7 0 0 0 0 0 41 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_no_mp_idle.cas 40021758 22841 255 255 7 0 0 0 0 0 15 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_no_mp_to_stand_A.cas 40044599 8385 255 255 7 0 0 0 0 0 131 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_sabotage.cas 40052984 72881 255 255 7 0 0 0 0 0 33 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_selected.cas 40125865 18393 255 255 7 0 0 0 0 0 41 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_idle.cas 40144258 22841 255 255 7 0 0 0 0 0 11 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_idle_selected.cas 40167099 6161 255 255 7 0 0 0 0 0 111 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_lf_idle_1.cas 40173260 61761 255 255 7 0 0 0 0 0 81 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_lf_idle_2.cas 40235021 45081 255 255 7 0 0 0 0 0 85 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_lf_idle_3.cas 40280102 47305 255 255 7 0 0 0 0 0 29 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_to_no_mp.cas 40327407 16169 255 255 7 0 0 0 0 0 25 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_to_walk.cas 40343576 13945 255 255 7 0 0 0 0 0 59 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_to_walk_backward.cas 40357521 32849 255 255 7 0 0 0 0 0 33 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_turn_90_ccw.cas 40390370 18393 255 255 7 0 0 0 0 0 33 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_stand_A_turn_90_cw.cas 40408763 18393 255 255 7 0 0 0 0 0 35 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_unselected.cas 40427156 19505 255 255 7 0 0 0 0 0 33 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_walk.cas 40446661 18393 255 255 7 0 0 0 0 0 27 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_walk_backward.cas 40465054 15057 255 255 7 0 0 0 0 0 29 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_walk_backward_to_stand_A.cas 40480111 16169 255 255 7 0 0 0 0 0 25 19 19 data/animations/Stratmap_Assassin/Strat_Assassin_walk_to_stand_A.cas 40496280 13945 255 255 7 0 0 0 0 0 55 19 19 data/animations/Stratmap_Diplomat/Strat_Diplomat_backward_1.cas 40510225 30625 255 255 7 0 0 0 0 0 21 19 1 data/animations/Stratmap_Diplomat/Strat_Diplomat_basepose.cas 40540850 7185 1 0 0 0 0 0 0 0 105 19 19 data/animations/Stratmap_Diplomat/Strat_Diplomat_conduct_diplomacy.cas 40548035 58425 255 255 7 0 0 0 0 0 67 19 19 data/animations/Stratmap_Diplomat/Strat_Diplomat_forward_1.cas 40606460 37297 255 255 7 0 0 0 0 0 41 19 19 data/animations/Stratmap_Diplomat/Strat_Diplomat_no_mp_idle.cas 40643757 22841 255 255 7 0 0 0 0 0
bytes as a short and a byte so 20 0 20 is shown as 20 20.
I modified two .cas files for MTW2_Spear and tried putting them in game
using the no_animdb=1 and no_animdb=true under [util] in my cfg file
under the assumption it was like the io_filefirst switch, i.e. only put in
modified files under /data/animations. No joy. Thinking it might be an
all or nothing I put the whole unpacked animations directory and
renamed pack.dat and pack.idx. This just crashed. That's all the experiments
so far.
Edit: The .evt event files referred to in descr_skeleton.txt aren't in pack.dat
so is it crashing because they're not there? Couldn't find them by hexing through
events.dat, that's related to other sound events.
Last edited by KnightErrant; 04-15-2007 at 20:04.
Erf, the .evt files caused a major problem in RTW also, and ultimately led to downfall of all attempts by CA helpers to allow us to keep animations unpacked. They always had to be packed back into the files, or else the game would crash. (Editing the animations and then stuffing them back into pack files was only way of modding them.) Maybe Caliban can help us there.
Ahh, thanks for that info. Reading zxiang1983's thread has me thinking
re-packing is the only way to get this to work too. Kind of ugly if that's
the only way, though.![]()
Bookmarks