Qhimm.com Forums
Miscellaneous Forums => Scripting and Reverse Engineering => Topic started by: Sephiroth2000 on 2003-11-11 02:05:41
-
I've not currently seen an active topic on this, so i've decided to make one.
I really need a decent model viewer for FFVII. I've tried ficedula's site and the FF7 PSX Model Viewer doesn't work. Does anyone know of any good Model Viewer?
-Sephiroth2000
-
Mine is fine. Look here at my page (http://www.mirex.mypage.sk/index.php?selected=1), or here a direct link: Biturn 0.831 (http://www.mirex.mypage.sk/FILES/bi0_831.rar) its 190kb and it can view .P .RDS .TEX .HRC and battle model (??AA) files
-
yeah you should check out mirex's site, his Leviathan model viewer is brilliant for viewing ff7 models, probably the best and only one i've seen, apart from another psx model viewer which is'nt as good, i just hope that some day it will have support to view summons and animations.
-
Mirex's Bitrun .84 alpha can also view the summon models when the lgp files are unpacked by Ficedula's lgp tools.
-
I have a question for Mirex. Whenever Levithian and Biturn view the model of RED XIII, its always screwed up and its only that model ( the others are fine). Does anyone else have this problem, is it just me, or is it a bug you haven't figured out yet?
-
Hey nixmahn, you could have just edited your previous post.
Thanks mirex! Leviathan works great.
-
nixmahn: yes i know it is general problem, because wo dont know proper info about how are animation data stored.
Oh and by the way, mine program Unmass can unpack .lpg files too :)
-
Ok, sorry, maybe i should rephrase the question. Does anyone know of any good PSX model viewers. Leviathan works with PC, but not with PSX.
-
i dont know any ... in fact i have never had an ff7 psx
-
I don't know about a model viewer but you can view the backgrounds of ff7 psx and ff8 psx with 7mimic and 8mimic almost perfectly. Does any one know a ff8 pc or psx model viewer (I have both) exists?
-
heres a psx ff7 model viewer it does work i tried it many years ago, but i don't have the psx version of ff7 any more.
http://www.zophar.net/utilities/download/ff7vMe.zip
-
Cool Newbie, that was the same one on ficedula's homepage =P It doesn't work with me. There are no itz. or whatever files on my PSX disc.
-
well since i don't have the psx version of ff7 anymore i can't test it, but what i can tell u is the offical site of the makers of that tool, maybe they have instruction on how to use it, but its in another language, so can't read it, try translate it or something.
http://www.cute.or.jp/~makuchan/pce/ff7v.html
-
Japanese, to be exact on the language side.
I can barely understand what they're saying, and miraculously was able to download. It's running as i type.
---edit---
Right, ive noticed the problem. My disc definately has no Itz. files on it. Also, that thing's made for Windows 95-NT and ive got XP. Would that affect it?
-
Speh2K:
It worked fine under Win2K for me
The files it is looking for are in
ENEMY1
through ENEMY6
and they are LZS files.
The program requires Open GL though so you might want to be sure your OGL drivers are up to snuff. The program was originally written in japanese and if you can figure out the site you can actually go there (I have), there seems to be nothing regarding the program on the site however.
Cyb
-
There are two versions of the tool: one for SG OpenGL and one for MS OpenGL. MS OpenGL should run.
The model files are .LZS (not ITZ).
-
[...]
-
[edit]
-
might it be that ff8 model data are stored this way too ? im going to try it :)
-
nope, no luck, i did not find any data in ff8 pc files that would look like these ... dang :(
-
How about everyone posts his complete know-how about the .LZS model files to decrypt it evt. 100%? Are you afraid that you have to credit other people in your application? Shame on you... :wink:
Unknown1 structure has a pattern that could be hierachical data.
I had not looked at models with textures yet (UV-Coords in Color-data?)
ENEMY000.LZS - Yellow Pyramid
More detailed data follows tomorrow but first:
Now it's YOUR turn.
Hmmm I think this is one of many different objects, for example this gives you one object from cloud, I wonder if there is any way to determine the number of 'elements' in an object. Using FF7me for a reference helps emensly. As for credit.. I could care less, I just want to figure out the data. :) Some things I do are embarasingly coded ;)
However back to the orginal ENEMY000.LZS
It contains only 1 object yet has 5 sections.. I would assume from that information, that each collection (IE CLOUD.LZS etc). has a minimum of 5 sections. I know cloud.LZS has quite a few more parts than Just the first part. I wonder if that unkown information may be part of ithe mystery. I think I'll hunt through sections and see if I can find another part. If not then I think there must be some information in there regarding the number of parts. I suppose I can dump the data into a POV object and generate an image from rendering that.
The Triangles/ Quadrics list are offsets from the start of the verticies I noticed as well. this limits one to about 8192 vertices.. which is quite a few :) this may also be why the vertex array begins with a byte count instead of a vertex count, so that the FF7 engine could determine if the object was too large for it to use.
I'll play some and let you know what I find/generate :)
Images removed because site is gone
The ordering of the polygon vertices isn't identical to POV's. So I suspect some 'tweaking' will be needed for POV to have things look about right. POV does not support 'coloring' of verticies either (sadly this means rendering it in POV could be very difficult).
Irregardless I have one section decoding and visable now. I am certain there are more objects I am going to have a look at the number of sections versus the number of parts FF7me shows. Acording to the author of that utility all the bone information etc. is in the file. Does cloud have one weapon type in battle all the time?
I need to play the 'used' vertices game I guess <sigh> and see what I can find out.
Cyb
-
[edit]
-
A bit of poking around has revealed the following information on FF7's format for the first section. The unknow area I gave a tentative structure information.
Section 0
The first 4 bytes is the relative offset to a piece :)
If it's zero I think it doesn't exist my guess
here is my 'dump' of this data so you can Cheer frown or grump about it
(I donno what to do my self ;) )
I think for converting it to POV information this will pretty much get every part of the person. I don't know what the Index does my guess is the last two bytes are flags of some sort :)
Section 1
Unknown
Section 2 to N-1 <accept the TIM>
UINT16 ???? I think this is some sort identifyer (see magic number for TIM files)
UINT16 Size How much data is in this section?
.... Filled to 4byte section size
OFFSET 0001C8 000000
Unkown Count = 23
OFF=00000000 Index=0 FFD9
OFF=000000C4 Index=1 FF5D
OFF=00000F28 Index=2 FF6E
OFF=00003CA4 Index=1 FF73
OFF=00000000 Index=4 FFC5
OFF=00000000 Index=5 FF7B
OFF=00006E98 Index=6 FF8B
OFF=0000826C Index=7 FFAB
OFF=00009B5C Index=1 FF73
OFF=00000000 Index=9 FFC5
OFF=00000000 Index=10 FF7B
OFF=0000A540 Index=11 FF8
OFF=0000B034 Index=12 FFB4
OFF=0000B7D8 Index=0 FFDB
OFF=00000000 Index=14 FEEB
OFF=0000C1BC Index=15 FF03
OFF=0000CD70 Index=16 FFB3
OFF=0000DBC0 Index=17 FF87
OFF=0000E2AC Index=0 FFDB
OFF=00000000 Index=19 FEEB
OFF=0000E7A8 Index=20 FF03
OFF=0000F35C Index=21 FFB3
OFF=000101AC Index=22 FF87
OFFSET 000288 0000C0
VERTICES[ 80] =
{
[ 0] < 55, 36, -40>
[ 1] < 72, 33, 34>
[ 2] < 67, -37, 34>
[ 3] < 55, -25, -40>
[ 4] < 0, 40, 46>
[ 5] < 0, -41, 46>
[ 6] < 60, 41, -10>
[ 7] < 63, -37, -10>
[ 8] < 0, 48, -40>
[ 9] < 0, 52, 14>
[10] < 0, -38, -40>
[11] < 0, -46, -10>
[12] < 0, 2, -52>
[13] < 64, 5, -40>
[14] < 75, 2, -10>
[15] < 84, 0, 34>
[16] < 0, -1, 53>
[17] < 23, 45, 24>
[18] < 0, 46, 38>
[19] < 40, 46, -16>
[20] < 0, 53, -14>
[21] < 27, 45, -40>
[22] < 0, 45, -21>
[23] < 41, 43, -40>
[24] < 33, 32, 40>
[25] < 42, 45, 29>
[26] < 64, 39, -19>
[27] < 76, 3, -19>
[28] < 48, 41, 1>
[29] < 35, 40, 4>
[30] < 20, 48, 12>
[31] < 43, 41, -5>
[32] < 14, 41, 19>
[33] < 45, 48, 15>
[34] < 74, 37, 11>
[35] < 95, -11, 11>
[36] < 25, 42, -14>
[37] < 10, 44, 0>
[38] < 27, -34, -40>
[39] < 31, -44, -10>
[40] < 33, -41, 40>
[41] < -33, -41, 40>
[42] < -31, -44, -10>
[43] < -27, -34, -40>
[44] < -10, 44, 0>
[45] < -25, 42, -14>
[46] < -95, -11, 11>
[47] < -74, 37, 11>
[48] < -45, 48, 15>
[49] < -14, 41, 19>
[50] < -43, 41, -5>
[51] < -20, 48, 12>
[52] < -35, 40, 4>
[53] < -48, 41, 1>
[54] < -76, 3, -19>
[55] < -64, 39, -19>
[56] < -42, 45, 29>
[57] < -33, 32, 40>
[58] < -41, 43, -40>
[59] < -27, 45, -40>
[60] < -40, 46, -16>
[61] < -23, 45, 24>
[62] < -84, 0, 34>
[63] < -75, 2, -10>
[64] < -64, 5, -40>
[65] < -63, -37, -10>
[66] < -60, 41, -10>
[67] < -55, -25, -40>
[68] < -67, -37, 34>
[69] < -72, 33, 34>
[70] < -55, 36, -40>
[71] < 65, -42, 11>
[72] < 32, -47, 15>
[73] < 0, -48, 18>
[74] < -32, -47, 15>
[75] < -65, -42, 11>
[76] < 71, -26, 11>
[77] < -71, -26, 11>
[78] < 84, 13, 11>
[79] < -84, 13, 11>
}
OFFSET 000510 000348
OFFSET 000518 000350
TRIANGLES[144] =
{
[ 0] <61 < 28, 24, 32>,
4 < 15, 10, 20>,
57 < 15, 10, 20>>
[ 1] <41 < 17, 15, 17>,
16 < 15, 10, 20>,
5 < 17, 15, 17>>
[ 2] <69 < 17, 15, 17>,
79 < 25, 20, 30>,
47 < 25, 22, 28>>
[ 3] <54 < 15, 10, 20>,
55 < 25, 22, 28>,
63 < 15, 10, 20>>
[ 4] <47 < 25, 22, 28>,
48 < 30, 25, 35>,
56 < 15, 10, 20>>
[ 5] <43 < 19, 18, 21>,
11 < 15, 10, 20>,
10 < 25, 20, 30>>
[ 6] <12 < 5, 0, 10>,
43 < 19, 18, 21>,
10 < 25, 20, 30>>
[ 7] <64 < 25, 20, 30>,
67 < 30, 25, 35>,
12 < 5, 0, 10>>
[ 8] <12 < 5, 0, 10>,
58 < 25, 20, 30>,
70 < 32, 28, 39>>
[ 9] <54 < 15, 10, 20>,
67 < 30, 25, 35>,
64 < 25, 20, 30>>
[ 10] <75 < 15, 10, 20>,
77 < 15, 10, 20>,
68 < 17, 15, 17>>
[ 11] <57 < 15, 10, 20>,
16 < 15, 10, 20>,
62 < 17, 15, 17>>
[ 12] <68 < 17, 15, 17>,
46 < 15, 10, 20>,
62 < 17, 15, 17>>
[ 13] <65 < 15, 10, 20>,
54 < 15, 10, 20>,
63 < 15, 10, 20>>
[ 14] <64 < 25, 20, 30>,
12 < 5, 0, 10>,
70 < 32, 28, 39>>
[ 15] <16 < 15, 10, 20>,
68 < 17, 15, 17>,
62 < 17, 15, 17>>
[ 16] <4 < 15, 10, 20>,
61 < 15, 10, 20>,
18 < 25, 20, 30>>
[ 17] <18 < 25, 20, 30>,
61 < 15, 10, 20>,
49 < 20, 15, 25>>
[ 18] <60 < 35, 30, 40>,
58 < 25, 20, 30>,
59 < 30, 25, 35>>
[ 19] <56 < 15, 10, 20>,
57 < 15, 10, 20>,
69 < 17, 15, 17>>
[ 20] <61 < 28, 24, 32>,
57 < 15, 10, 20>,
56 < 15, 10, 20>>
[ 21] <59 < 25, 20, 30>,
12 < 5, 0, 10>,
8 < 25, 20, 30>>
[ 22] <58 < 25, 20, 30>,
12 < 5, 0, 10>,
59 < 25, 20, 30>>
[ 23] <55 < 25, 22, 28>,
64 < 25, 20, 30>,
70 < 32, 28, 39>>
[ 24] <60 < 35, 30, 40>,
70 < 32, 28, 39>,
58 < 25, 20, 30>>
[ 25] <52 < 15, 10, 20>,
49 < 20, 15, 25>,
61 < 15, 10, 20>>
[ 26] <50 < 20, 15, 25>,
51 < 19, 17, 20>,
52 < 15, 10, 20>>
[ 27] <60 < 20, 15, 25>,
50 < 20, 15, 25>,
66 < 10, 5, 15>>
[ 28] <18 < 25, 20, 30>,
49 < 20, 15, 25>,
9 < 10, 5, 15>>
[ 29] <49 < 20, 15, 25>,
52 < 15, 10, 20>,
51 < 19, 17, 20>>
[ 30] <48 < 30, 25, 35>,
61 < 28, 24, 32>,
56 < 15, 10, 20>>
[ 31] <52 < 15, 10, 20>,
48 < 30, 25, 35>,
53 < 30, 27, 37>>
[ 32] <79 < 25, 20, 30>,
46 < 15, 10, 20>,
63 < 15, 10, 20>>
[ 33] <48 < 30, 25, 35>,
47 < 25, 22, 28>,
53 < 30, 27, 37>>
[ 34] <53 < 30, 27, 37>,
47 < 25, 22, 28>,
66 < 10, 5, 15>>
[ 35] <46 < 15, 10, 20>,
77 < 15, 10, 20>,
63 < 15, 10, 20>>
[ 36] <51 < 19, 17, 20>,
50 < 20, 15, 25>,
60 < 20, 15, 25>>
[ 37] <45 < 29, 26, 35>,
60 < 35, 30, 40>,
59 < 30, 25, 35>>
[ 38] <51 < 19, 17, 20>,
9 < 10, 5, 15>,
49 < 20, 15, 25>>
[ 39] <20 < 25, 20, 30>,
9 < 25, 20, 30>,
44 < 20, 15, 25>>
[ 40] <22 < 35, 30, 40>,
59 < 25, 20, 30>,
8 < 25, 20, 30>>
[ 41] <22 < 35, 30, 40>,
20 < 15, 10, 20>,
59 < 25, 20, 30>>
[ 42] <45 < 29, 26, 35>,
59 < 30, 25, 35>,
44 < 30, 25, 35>>
[ 43] <41 < 17, 15, 17>,
75 < 15, 10, 20>,
68 < 17, 15, 17>>
[ 44] <42 < 15, 10, 20>,
43 < 19, 18, 21>,
67 < 30, 25, 35>>
[ 45] <43 < 19, 18, 21>,
12 < 5, 0, 10>,
67 < 30, 25, 35>>
[ 46] <16 < 15, 10, 20>,
41 < 17, 15, 17>,
68 < 17, 15, 17>>
[ 47] <16 < 15, 10, 20>,
57 < 15, 10, 20>,
4 < 15, 10, 20>>
[ 48] <57 < 15, 10, 20>,
62 < 17, 15, 17>,
69 < 17, 15, 17>>
[ 49] <15 < 15, 10, 20>,
24 < 15, 10, 20>,
1 < 15, 10, 20>>
[ 50] <24 < 15, 10, 20>,
16 < 15, 10, 20>,
4 < 15, 10, 20>>
[ 51] <40 < 17, 15, 17>,
16 < 15, 10, 20>,
2 < 17, 15, 17>>
[ 52] <12 < 5, 0, 10>,
38 < 20, 15, 25>,
3 < 24, 22, 27>>
[ 53] <38 < 20, 15, 25>,
39 < 15, 10, 20>,
3 < 24, 22, 27>>
[ 54] <71 < 15, 10, 20>,
40 < 17, 15, 17>,
2 < 17, 15, 17>>
[ 55] <19 < 28, 25, 33>,
36 < 29, 26, 35>,
21 < 20, 15, 25>>
[ 56] <20 < 15, 10, 20>,
37 < 15, 10, 20>,
9 < 25, 20, 30>>
[ 57] <31 < 10, 5, 15>,
30 < 20, 15, 25>,
19 < 15, 10, 20>>
[ 58] <2 < 17, 15, 17>,
35 < 30, 25, 35>,
76 < 15, 10, 20>>
[ 59] <34 < 35, 30, 40>,
28 < 35, 30, 40>,
6 < 15, 10, 20>>
[ 60] <34 < 35, 30, 40>,
33 < 35, 30, 40>,
28 < 35, 30, 40>>
[ 61] <35 < 30, 25, 35>,
78 < 25, 20, 30>,
14 < 20, 15, 25>>
[ 62] <33 < 35, 30, 40>,
29 < 28, 25, 33>,
28 < 35, 30, 40>>
[ 63] <17 < 28, 24, 32>,
33 < 20, 15, 25>,
25 < 15, 10, 20>>
[ 64] <29 < 28, 25, 33>,
32 < 10, 5, 15>,
30 < 20, 15, 25>>
[ 65] <31 < 10, 5, 15>,
19 < 15, 10, 20>,
6 < 15, 10, 20>>
[ 66] <30 < 20, 15, 25>,
31 < 10, 5, 15>,
29 < 28, 25, 33>>
[ 67] <32 < 10, 5, 15>,
29 < 28, 25, 33>,
17 < 28, 24, 32>>
[ 68] <0 < 25, 20, 30>,
19 < 28, 25, 33>,
23 < 25, 20, 35>>
[ 69] <13 < 15, 10, 20>,
26 < 30, 25, 35>,
0 < 25, 20, 30>>
[ 70] <12 < 5, 0, 10>,
23 < 20, 15, 25>,
21 < 20, 15, 25>>
[ 71] <12 < 5, 0, 10>,
21 < 20, 15, 25>,
8 < 25, 20, 30>>
[ 72] <18 < 25, 20, 30>,
9 < 25, 20, 30>,
32 < 10, 5, 15>>
[ 73] <24 < 15, 10, 20>,
17 < 28, 24, 32>,
25 < 15, 10, 20>>
[ 74] <30 < 20, 15, 25>,
32 < 10, 5, 15>,
9 < 25, 20, 30>>
[ 75] <24 < 15, 10, 20>,
25 < 15, 10, 20>,
1 < 15, 10, 20>>
[ 76] <23 < 20, 15, 25>,
19 < 28, 25, 33>,
21 < 20, 15, 25>>
[ 77] <37 < 30, 25, 35>,
21 < 20, 15, 25>,
36 < 29, 26, 35>>
[ 78] <22 < 20, 15, 25>,
8 < 25, 20, 30>,
21 < 20, 15, 25>>
[ 79] <20 < 15, 10, 20>,
22 < 20, 15, 25>,
21 < 20, 15, 25>>
[ 80] <17 < 28, 24, 32>,
18 < 25, 20, 30>,
32 < 10, 5, 15>>
[ 81] <17 < 28, 24, 32>,
4 < 15, 10, 20>,
18 < 25, 20, 30>>
[ 82] <2 < 17, 15, 17>,
16 < 15, 10, 20>,
15 < 15, 10, 20>>
[ 83] <13 < 15, 10, 20>,
12 < 5, 0, 10>,
3 < 24, 22, 27>>
[ 84] <27 < 20, 15, 25>,
7 < 17, 16, 18>,
14 < 20, 15, 25>>
[ 85] <35 < 30, 25, 35>,
2 < 17, 15, 17>,
15 < 15, 10, 20>>
[ 86] <16 < 15, 10, 20>,
24 < 15, 10, 20>,
15 < 15, 10, 20>>
[ 87] <76 < 15, 10, 20>,
71 < 15, 10, 20>,
2 < 17, 15, 17>>
[ 88] <3 < 24, 22, 27>,
27 < 35, 30, 40>,
13 < 15, 10, 20>>
[ 89] <23 < 25, 20, 35>,
12 < 5, 0, 10>,
0 < 25, 20, 30>>
[ 90] <12 < 5, 0, 10>,
13 < 15, 10, 20>,
0 < 25, 20, 30>>
[ 91] <38 < 20, 15, 25>,
12 < 5, 0, 10>,
10 < 25, 20, 30>>
[ 92] <11 < 20, 15, 25>,
38 < 20, 15, 25>,
10 < 25, 20, 30>>
[ 93] <33 < 20, 15, 25>,
34 < 30, 25, 35>,
25 < 15, 10, 20>>
[ 94] <26 < 30, 25, 35>,
27 < 20, 15, 25>,
14 < 20, 15, 25>>
[ 95] <78 < 25, 20, 30>,
1 < 15, 10, 20>,
34 < 30, 25, 35>>
[ 96] <16 < 15, 10, 20>,
40 < 17, 15, 17>,
5 < 17, 15, 17>>
[ 97] <4 < 15, 10, 20>,
17 < 28, 24, 32>,
24 < 15, 10, 20>>
[ 98] <39 < 15, 10, 20>,
71 < 15, 10, 20>,
7 < 17, 16, 18>>
[ 99] <11 < 20, 15, 25>,
72 < 15, 10, 20>,
39 < 15, 10, 20>>
[100] <74 < 15, 10, 20>,
11 < 15, 10, 20>,
42 < 15, 10, 20>>
[101] <75 < 15, 10, 20>,
42 < 15, 10, 20>,
65 < 15, 10, 20>>
[102] <71 < 15, 10, 20>,
76 < 15, 10, 20>,
7 < 17, 16, 18>>
[103] <76 < 15, 10, 20>,
35 < 30, 25, 35>,
14 < 20, 15, 25>>
[104] <77 < 15, 10, 20>,
75 < 15, 10, 20>,
65 < 15, 10, 20>>
[105] <77 < 15, 10, 20>,
46 < 15, 10, 20>,
68 < 17, 15, 17>>
[106] <15 < 15, 10, 20>,
78 < 25, 20, 30>,
35 < 30, 25, 35>>
[107] <79 < 25, 20, 30>,
62 < 17, 15, 17>,
46 < 15, 10, 20>>
[108] <40 < 17, 15, 17>,
71 < 15, 10, 20>,
72 < 15, 10, 20>>
[109] <75 < 15, 10, 20>,
41 < 17, 15, 17>,
74 < 15, 10, 20>>
[110] <21 < 20, 15, 25>,
37 < 20, 15, 25>,
20 < 20, 15, 25>>
[111] <44 < 20, 15, 25>,
59 < 25, 20, 30>,
20 < 25, 20, 30>>
[112] <44 < 30, 25, 35>,
51 < 19, 17, 20>,
45 < 29, 26, 35>>
[113] <30 < 20, 15, 25>,
37 < 30, 25, 35>,
36 < 29, 26, 35>>
[114] <30 < 20, 15, 25>,
36 < 29, 26, 35>,
19 < 28, 25, 33>>
[115] <45 < 29, 26, 35>,
51 < 19, 17, 20>,
60 < 35, 30, 40>>
[116] <9 < 10, 5, 15>,
51 < 19, 17, 20>,
44 < 30, 25, 35>>
[117] <30 < 20, 15, 25>,
9 < 25, 20, 30>,
37 < 30, 25, 35>>
[118] <77 < 15, 10, 20>,
65 < 15, 10, 20>,
63 < 15, 10, 20>>
[119] <7 < 17, 16, 18>,
76 < 15, 10, 20>,
14 < 20, 15, 25>>
[120] <42 < 15, 10, 20>,
75 < 15, 10, 20>,
74 < 15, 10, 20>>
[121] <11 < 15, 10, 20>,
74 < 15, 10, 20>,
73 < 15, 10, 20>>
[122] <72 < 15, 10, 20>,
11 < 20, 15, 25>,
73 < 15, 10, 20>>
[123] <71 < 15, 10, 20>,
39 < 15, 10, 20>,
72 < 15, 10, 20>>
[124] <79 < 25, 20, 30>,
69 < 17, 15, 17>,
62 < 17, 15, 17>>
[125] <63 < 15, 10, 20>,
55 < 25, 22, 28>,
66 < 10, 5, 15>>
[126] <47 < 25, 22, 28>,
56 < 15, 10, 20>,
69 < 17, 15, 17>>
[127] <11 < 15, 10, 20>,
43 < 19, 18, 21>,
42 < 15, 10, 20>>
[128] <67 < 30, 25, 35>,
54 < 15, 10, 20>,
65 < 15, 10, 20>>
[129] <64 < 25, 20, 30>,
55 < 25, 22, 28>,
54 < 15, 10, 20>>
[130] <70 < 32, 28, 39>,
60 < 35, 30, 40>,
55 < 25, 22, 28>>
[131] <60 < 20, 15, 25>,
66 < 10, 5, 15>,
55 < 25, 22, 28>>
[132] <48 < 30, 25, 35>,
52 < 15, 10, 20>,
61 < 15, 10, 20>>
[133] <42 < 15, 10, 20>,
67 < 30, 25, 35>,
65 < 15, 10, 20>>
[134] <3 < 24, 22, 27>,
39 < 15, 10, 20>,
7 < 17, 16, 18>>
[135] <29 < 28, 25, 33>,
33 < 35, 30, 40>,
17 < 28, 24, 32>>
[136] <6 < 15, 10, 20>,
19 < 15, 10, 20>,
26 < 30, 25, 35>>
[137] <19 < 28, 25, 33>,
0 < 25, 20, 30>,
26 < 30, 25, 35>>
[138] <26 < 30, 25, 35>,
13 < 15, 10, 20>,
27 < 35, 30, 40>>
[139] <27 < 35, 30, 40>,
3 < 24, 22, 27>,
7 < 17, 16, 18>>
[140] <38 < 20, 15, 25>,
11 < 20, 15, 25>,
39 < 15, 10, 20>>
[141] <25 < 15, 10, 20>,
34 < 30, 25, 35>,
1 < 15, 10, 20>>
[142] <26 < 30, 25, 35>,
14 < 20, 15, 25>,
6 < 15, 10, 20>>
[143] <1 < 15, 10, 20>,
78 < 25, 20, 30>,
15 < 15, 10, 20>>
}
OFFSET 00105C 000E94
QAUDRICS[6] =
{
[ 0] <73 < 15, 10, 20>,
74 < 15, 10, 20>,
5 < 17, 15, 17>,
41 < 17, 15, 17>>
[ 1] <66 < 10, 5, 15>,
50 < 20, 15, 25>,
53 < 30, 27, 37>,
52 < 15, 10, 20>>
[ 2] <31 < 24, 22, 27>,
6 < 15, 10, 20>,
29 < 15, 10, 20>,
28 < 30, 27, 37>>
[ 3] <72 < 15, 10, 20>,
73 < 15, 10, 20>,
40 < 17, 15, 17>,
5 < 17, 15, 17>>
[ 4] <14 < 20, 15, 25>,
78 < 25, 20, 30>,
6 < 15, 10, 20>,
34 < 35, 30, 40>>
[ 5] <79 < 25, 20, 30>,
63 < 15, 10, 20>,
47 < 25, 22, 28>,
66 < 10, 5, 15>>
}
OFFSET 0010F0 000F28
-
[edit]
-
Kislinskiy:
After some dickering with the information some small changes ;)
For objects that have textures things are slightly different
There appears to be a 'normal' section but the upper 16 bits of the count have flags in them I believe and indicate weather these are 'normal' polygons/triangles or 'textured' ones. If textured the format is DEFINATELY not the same. I Think it gives vertices with UV pixel coordinates instead of vertex colors. Technically this would make them the same size (UV can be done with 2 16 bit ints and the colors are 4 8 bit values). Or it may give vertex colors and UV values. I believe the former is more likely. Why? Well it shows how to 'map' the texture onto a list of vertexes. It makes sense to me at least :) The order of the information given though so far doesn't make much sense. More twiddling I guess for me.
I've rendered a few more interesting object sets if you care to look.
Image removed Site is gone
Yes it's one of WEAPON!
You can see the feet at the end of the pile of objects ;)
There are 28 objects in all for that one.
-
Well I have some better images.
I discovered that the QUADS follow PSX ordering of vertices (yea me :( ).
Quadrics on the PSX are split into 2 trinagles, and that's how the PSX processes a quad (not a joke. Even though there is a quadric command, this is how the PSX internally handles them. What has this to do with the model data? Well it helps to know how the vertices are actually ordered.
Triangle Quad
B--C B--D
| / | |
| / | |
|/ | |
A A--C
These are the ordering of the vertices given to have a correct triangle or quad draw. The normal follows the left hand rule. The vertices are the vertices as they appear in the model data (in order).
Any how I also found out how to make the objects into meshs. I broke the quads into triangles (because meshes do not support quads in POV). Currently it creates a huge file however the results speak for themselves.
Images removed Site is gone
ENEMY011 <WEAPON>
ENEMY010 <WEAPON>
TIFA <reprise>
-
Since FF7 models use only vertex colors for shading, I think you'll find the quality of your renders will increase if you turn gouraud/phong shading off (or set self-illumination to 100% or similar).
-
Sorry I had not much time the last weeks. Yes I know about the ordering of the quad vertices -> look at the one in ENEMY000.BIN (the bottom of the pyramid). =)
Textured objects must have vertex colors AND U/V-coords. Look at the face textures. They have transparent areas => textures have to be mapped over colored vertices.
I'll write a small D3D application that can display our progress this month I think.
Vertices, colors, textures, objects are no mysteries anymore. We should look at animation and bone/hierachy data. :o
-
I'm a little baffled about the UV data so far.. what it looks like is that ALL numbers are used.
I believe it goes this way now:
Vertice Counts
Vertices
UV Count
UV objects (they are 16 bytes each)
Line Count
Lines (16 bytes each as well)
Triangle Count
Triangles
Quad Count
Quadds
UV exist if the lower word is > 0
It decodes better now that I have that added in.
However I found Lines in a model and it's still not decoding line data correctly yet.. I don't know why.
Qhimm:
I'm using a raytracer so things will look odd. because there is no vertex normal data I can't make them smooth triangles. In any case the fact I can get it to export model code for a raytracer is a good start :) Yufi decodes quite nicely safe her head. Still working on the UV data.
Cyb
-
I don't know whether line data is really line data. :) That was an assumption, because I had looked on ENEMY000 and 012 only.
-
I don't know whether line data is really line data. :) That was an assumption, because I had looked on ENEMY000 and 012 only.
Ahh.. well look at ENEMY019.lZS that is the first one with any texture to it. I noticed that the 'line' data is used and another one you ignored was used whenever textures were added. I need to recompile my OGL components for BCB in order to add function OGL commands. It's been a while since I've messed with it. I guess better now than never? ;) One anoying thing the author of FF7meV did was use a black background for model viewing, a lot of the FF7 models are REALLY dark so you can't see the shape very well. The second one is that you can't change your POV or the scale of the model being viewed.
I am working on FF8 Models Qhimm as well, I have a scanner for the PSX version that finds valid TIMs I've noticed that all objects begin on XXXXX800 or XXXXX000 boundaries in the *.IMG files. This to me indicates The file is broken up into 2K sectors which makes sense because FMV on the PSX version are 2K video JPEG compression with 256bytes per sector added for the audio Data. The files must be written in MODE2 with blank data for regular files in the extra 256 bytes and for Movies has the audio stuffed into 256 extra bytes per sector. So I'm going to try using the model data you have posted and corelate that to the begining of the model file. This means an FF8 model viewer for the PSX version is possible. I haven't tried FF9 yet.. but my suspicion is they used the same engine and model format with better modeling (because a lot of the characters look quite good in FF9).
Cyb
-
Here are a few teaser screenshots of my D3D9 application :) :
(http://home.arcor.de/kislinskiy/enemy010_5.jpg)
(http://home.arcor.de/kislinskiy/enemy010_1.jpg)
(http://home.arcor.de/kislinskiy/enemy010_1w.jpg)
-
nice keep up the good work!
-
Yeah looks nice
-
Ok Fine fine.. I'll post my shots from my internal viewer for TV too (woo).
It took me a couple hours to remember my opengl code and to fix up a few mistakes I made. Anything with textures still can't be read sadle so here is weapon (same as you Kislinskiy) without an FPS being displayed. ( rather unimportant to me hehehe).
Images removed Site is gone
Yep a few hours work and poof.. no textures yet which sucks.. maybe with some more abuse.
-
Looks nice. :)
This week I will try to handle/unterstand texture data.
One more thing:
I have noticed that the most models have one more visible object than non-zero offsets in the "unknown"-structures. E.g. ff7vM reads 18 objects from ENEMY010. My app can only read 17 objects. Any idea?
We should look at ENEMY145 (mirror) and ENEMY165 (airplane) because they have only 3 visible objects, no textures and 2 offsets in the "unknown"-structures.
-
Here is the visible object format :D :
SizCoords
Coords[SizCoords / 2]
NumTexturedTriangles (LOWORD only)
TexturedTriangles[NumTexturedTriangles]
NumTexturedPlanes (LOWORD only)
TexturedPlanes[NumTexturedPlanes]
NumTriangles
Triangles[NumTriangles]
NumPlanes
Planes[NumPlanes]
-
Now we can read HICLOUD (ff7vM can not). 8)
It should be easy to implement the textured triangles and planes to our applications. I will do it tomorrow, because I have not much time today. Then I'll look at the "missing-last-visible-objects-problem". :)
I guess the animation and bone data are harder to decrypt. :o More on this later.
-
Cool data!
I'll see if I can abuse it as well. I'm wondering if the textured areas are drawn 2 times, IE first the nontextured versions of the polygons. Then with the textured layer and black being transparent. Just a thought :)
Oh some more on the information contained in the Unknown area in FF7 I was looking at the bone data Qhimm has listed in FF8's format. The section I called flags has very similar settings in the FF8 data. I believe that might be a good clue as to what it is. I do believe the unknown area is bone data but I think it might be the data heirarchy information as for actual skeletal data that hasn't poped out yet to my eyes.
I assume by Coords you are refering to vertices ;)
Cyb
-
Coords -> vertices. I call it coords because it is only position data. I call the coords + colors/uv's "vertices". :)
Your assumptions about the transparent textures are right. You must render the colored vertices before the textured vertices.
-
Can someone post a link to a good TIM file format description please?
-
Scarfed from the Internet
TIM Graphic Formats (PSX 2D Graphics)
By Klarth ([email protected])
http://rpgd.emulationworld.com/klarth
Version 0.7 - January 1, 2001
-- Totally rewritten for extra clarity
-- Removed Opinions/Ideas on Editing Utilities Section
Version 0.5 - August 22, 2000
-- Initial Release
I. Table of Contents
1. Introduction and Terminology
2. TIM Graphic Formats (4BPP, 8BPP, 16BPP, and 24BPP)
3. TIM Header Formats (4BPP, 8BPP, 16BPP, and 24BPP)
4. Color Conversion Algorithms (15bit BGR <-> 24bit RGB)
_______________________________________________________________________________________________
1. Introduction and Terminology
-----A. Introduction
Hmm, I started this doc awhile ago when I first started to get interested in PSX hacking.
I then concluded that many tools needed to be coded before the PSX translation "scene"
could really get started. So I decided to finish it and release it so that all you
coders out there can start making some graphic tools to make PSX translations remotely
possible for anybody willing to try to tackle one. These formats all have headers so I
decided to make a seperate document for them only since they're so different from other
console graphics formats.
If you wish to put this document on your site, please contact me for authorization
*before* you post this file on your site. If I seem to "magically" disappear from the
scene, you may post this document *only* in its original form. If you use this doc
please credit me in a thanks section since I just like to see who reads and uses them.
-----B. Terminology
CLUT - Color LookUp Table (The Sony term for Palette)
Image Org - Sets the coordinate of an image zero point, used for TIM files
in the VRAM of the Playstation. Not particularly necessary from an editing point
but could be useful for a program that creates TIM images and their headers.
Palette Org - Sets the coordinates of a CLUT image zero point. Not particularly necessary
from an editing standpoint but could be useful for a program that creates TIM images and
their headers.
BPP: Bits per pixel.
[pA-B rC]: pixels A-B (leftmost pixel 0), row number C (topmost row 0).
This won't have a bitplane value because it's a linear format.
[pX rX]: The last pixel of row X. The last pixel's number is equal to the correct width
of the image as defined in the header.
_______________________________________________________________________________________________
2. TIM Graphics Data (A. 4BPP, B. 8BPP, C. 16BPP, D. 24BPP)
All the graphics are stored in Big Endian order.
-----A. 4BPP PSX TIM
Each pair represents one byte
Format:
[p0-1 r0], [p2-3 r0], [p4-5 r0], [p6-7 r0], ..., [pX r0]
[p0-1 r1], [p2-3 r1], [p4-5 r1], [p6-7 r1], ..., [pX r1]
...
And it continues until the row number equals the height (from the header). It gets its
colors from a 16 entry CLUT in the header of the file, there may be multiple CLUTs.
-----B. 8BPP PSX TIM
Each pair represents one byte
Format:
[p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
[p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
...
And it continues until the row number equals the height (from the header). It gets its
colors from a 256 entry CLUT in the header of the file, there may be multiple CLUTs.
-----C. 16BPP PSX TIM
Each pair represents two bytes
Format:
[p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
[p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
...
And it continues until the row number equals the height (from the header). It doesn't need
a CLUT because it's basically a type of 15bit color.
-----D. 24BPP PSX TIM
Each pair represents three bytes
Format:
[p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
[p0 r0], [p1 r0], [p2 r0], [p3, r0], [p4, r0], [p5, r0], [p6, r0], [p7, r0], ..., [pX r0]
...
Continues until the row number equals the height (from the header). It doesn't need a CLUT
since it's 24bit color. I've never actually ripped a 24BPP TIM from a PSX game but I found
one 24BPP TIM image and took this info from it. May or may not actually be used on the PSX.
_______________________________________________________________________________________________
3. TIM Headers (A. 4BPP, B. 8BPP, C. 16BPP, D. 24BPP)
All two byte values are in Little Endian. The rest are in Big Endian.
-----A. 4BPP TIM Header:
[1-4] - 10 00 00 00: ID Tag for TIM Format
[5-8] - 08 00 00 00: ID Tag for 4BPP
[9-10] - ?
[11-12] - ?
[13-14] - Palette Org X
[15-16] - Palette Org Y
[17-18] - ?
[19-20] - Number of CLUTs
[??-??] - CLUT Data. 16 Colors per CLUT, 32 bytes per CLUT.
[21-22] - ?
[23-24] - ?
[25-26] - Image Org X
[27-28] - Image Org Y
[29-30] - Image Width (Multiply by 4 to get actual width)
[31-32] - Image Height
-----B. 8BPP TIM Header:
[1-4] - 10 00 00 00: ID Tag for TIM
[5-8] - 09 00 00 00: ID Tag for 8BPP
[9-10] - ?
[11-12] - ?
[13-14] - Palette Org X
[15-16] - Palette Org Y
[17-18] - ?
[19-20] - Number of CLUTs
[??-??] - CLUT Data. 256 Colors per CLUT, 512 bytes per CLUT.
[21-22] - ?
[23-24] - ?
[25-26] - Image Org X
[27-28] - Image Org Y
[29-30] - Image Width (Multiply by 2 to get actual width)
[31-32] - Image Height
-----C. 16BPP TIM Header:
[1-4] - 10 00 00 00: ID Tag for TIM
[5-8] - 02 00 00 00: ID Tag for 16BPP
[9-10] - ?
[11-12] - ?
[13-14] - Image Org X
[15-16] - Image Org Y
[17-18] - Image Width (Stored as actual width)
[19-20] - Image Height
There is no CLUT data.
-----D. 24BPP TIM Header:
[1-4] - 10 00 00 00: ID Tag for TIM
[5-8] - 03 00 00 00: ID Tag for 24BPP
[9-10] - ?
[11-12] - ?
[13-14] - Image Org X
[15-16] - Image Org Y
[17-18] - Image Width (Divide by 1.5 to get actual height)
[19-20] - Image Height
There is no CLUT data.
_______________________________________________________________________________________________
4. Color Conversion Algorithms (15bit BGR <-> 24bit RGB)
-----A. 15bit BGR to 24bit RGB Color Conversion Algorithm
Two bytes per 15bit BGR color, stored in Little Endian.
Miscellaneous Note - Same as a SNES Palette Color.
Initial 15bit BGR color in Little Endian:
{ggg{rrrrr} {0}{bbbbb}gg}
Swap the two bytes to change to Big Endian from Little Endian.
The color order will look like this now: (b-Blue, g-Green, r-Red, 0-mystery bit)
{0}{bbbbb}{gg ggg}{rrrrr}
Take each of the color pairings and multiply by 8 to get a 24bit BGR color:
{bbbbbbbb} {gggggggg} {rrrrrrrr}
Rearrange from 15bit BGR to 24bit RGB:
{rrrrrrrr} {gggggggg} {bbbbbbbb}
This algorithm expands the color to 3 bytes instead of the original 2 bytes.
-----B. 24bit to 15bit Color Conversion Algorithm
Three bytes per 24bit RGB color, stored in Big Endian.
{rrrrrrrr} {gggggggg} {bbbbbbbb}
Integer Divide (DIV) each color by 8
{rrrrr}{ggg gg}{bbbbb}{0}
Rearrange into 15bit BRG
{0}{bbbbb}{gg ggg}{rrrrr}
Swap the bytes to change from Big Endian to Little Endian (so the PSX can read it proerly)
{ggg{rrrrr} {0}{bbbbb}{gg}
-----C. Notes on PSX 15bit BGR Colors
These are the same as the SNES 15bit BGR Colors. There is a color loss whenever converting
from 24bit RGB <-> 15bit BRG. Also, there's probably a more advanced and quicker algorithm
to convert the colors, however this is explaining the basic idea behind the algorithm.
My TIM Headers from my code
typedef short int INT16;
typedef unsigned short UINT16;
typedef char INT8;
typedef unsigned char UINT8;
typedef struct
{
UINT32 Magic;
UINT32 Type;
} base_tim_hdr;
typedef struct
{
UINT32 WCount;
UINT16 IMGX, IMGY; // origin of image
UINT16 Pitch; // in 16 bit words per horizontal line
UINT16 Height; // number of lines;
} base_tim_img;
typedef struct
{
base_tim_hdr INFO;
UINT32 Bytes;
UINT16 PALX, PALY;
UINT16 ZZ01;
UINT16 CLUT_CNT;
} tim_4bpp;
typedef struct
{
base_tim_hdr INFO;
UINT32 Bytes;
UINT16 PALX, PALY;
UINT16 ZZ01;
UINT16 CLUT_CNT;
} tim_8bpp;
typedef struct
{
base_tim_hdr INFO;
base_tim_img IMAGEDAT;
} tim_16bpp;
typedef struct
{
base_tim_hdr INFO;
base_tim_img IMAGEDAT;
} tim_24bpp;
#define TIM_4BPP 8
#define TIM_8BPP 9
#define TIM_16BPP 2
#define TIM_24BPP 3
#define TIM_MAGIC 0x10
// Pallette/Color Look Up Tables for TIM files
typedef UINT16 CLUT_4bpp[16];
typedef UINT16 CLUT_8bpp[256];
-
Cyberman: great info, thank you, i could not find anything on TIM so far !
-
Small adendum
You see 'Bytes' in the structure that's the size in bytes of the whole TIM. Useful I suppose if you want to know how big it is.
WCount also means WORD count. ALL image data is stored as 16bit words and broken up from those That is the whole image structure though in word sized units.
I've seen images with as many as 16 CLUT's, this is important to remember as the CLUTS <palettes> are prior to the actual image header in 4BPP and 8BPP TIMS.
That's all ;)
-
Kislinskiy:
These are the vertices
[ 1] < 39, 52, -99>
[ 2] < 0, 72, -96>
[ 5] < 39, 47, -79>
[ 6] < 8, 65, -68>
[ 7] < 0, 69, -78>
[ 12] < 37, 49, -64>
[ 14] < 5, 70, -57>
[ 22] < 0, 55, -29>
[ 52] < -28, 48, -47>
[ 57] < -5, 70, -57>
[ 58] < -37, 49, -64>
[ 62] < -8, 65, -68>
[ 63] < -39, 47, -79>
[ 64] < -39, 52, -99>
Texture Triangle information
TexturedTri[11] = {
[ 0] 2, 7, 62
D0080|1600 7800 2D00 390D
// negative direction above nose
[ 1] 7, 2, 6
D0080|2D00 7800 1600 390B
// Positive direction above nose
[ 2] 2, 63, 64
D0080|1600 7800 2C38 1338
// positive ebrow area
[ 3] 63, 2, 62
D0080|2C38 7800 1600 390D
// positive eye area
[ 4] 63, 62, 58
D0080|2C38 7800 390D 3E34
// positive cheek area
[ 5] 57, 22, 52
D0080|006D 7840 3579 1046
// positive mouth/right
[ 6] 57, 14, 22
D0080|006D 7840 0082 3579
// mouth center
[ 7] 22, 14, 21
D0080|3579 7840 0082 10A9
// negative mouth/left
[ 8] 6, 5, 12
D0080|390B 7800 2C38 3E34
// negative cheek/left
[ 9] 2, 5, 6
D0080|1600 7800 2C38 390B
// negative eye/left
[ 10] 5, 2, 1
D0080|2C38 7800 1600 1336
// negative eye brow/left
}
These are from TIFA.LZS
Triangle 0 goes right to left < ( negative offset) where as Triangle one goes left to right (positive). I don't know what the numbers do (these are read as unsigned little endian ints currently.) However it looks as if they are rotated 180 degress as 1600 and 2D00 are swaped in location in both. the first 2 triangles are part of the face/eye area thus should use the same pallete and image. Also these are 'oposite' parts of TIFA's eye.Triangle 1 is sweeping across texture left to right.. the other is as well only the texture is pasted in the reverse direction. I gleaned this from giving the varirious triangles a different color intensity for each triangle number made it easier to figure out what triangle was which :)
I hope this helps maybe you can figure it out some more than I can.
-
Oh, I have forget to post the format of the textured polygons. :oops:
Textured Triangle:
UINT16 Index to Coordinate 1
UINT16 Index to Coordinate 2
UINT16 Index to Coordinate 3
[80 00]
UCHAR8 U 1
UCHAR8 V 1
[00 78]
UCHAR8 U 2
UCHAR8 V 2
UCHAR8 U 3
UCHAR8 V 3
Textured Plane:
UINT16 Index to Coordinate 1
UINT16 Index to Coordinate 2
UINT16 Index to Coordinate 3
UINT16 Index to Coordinate 4
UCHAR8 U 1
UCHAR8 V 1
[80 78]
UCHAR8 U 2
UCHAR8 V 2
UCHAR8 U 3
UCHAR8 V 3
UCHAR8 U 4
UCHAR8 V 4
[80 00]
U/V-coords are X/Y-coords in the TIM image.
To convert the U/V-coords to float[0.0f ... 1.0f] just
divide 1.0f by TIM-width/Height and multiply this with the U/V-coord:
fU = (1.0f / static_cast<float>(TIM.Width)) * static_cast<float>(ucU);
fV = (1.0f / static_cast<float>(TIM.Height)) * static_cast<float>(ucV);
THX for the TIM data. :)
-
Well I had gotten to this:
V0 U0, PALETTE, V1 U1, V2 U2
Palette is actually information about which CLUT to use for the texture (yes it's time to groan because this is where the PSX system gets high efficiency but makes reading this data a pain).
0x7800 CLUT one
0x7840 CLUT two
In TIFA.LZS
I've seen as many as 3 CLUTS in FF7's data.
I looked at all of them too. That being said.
Only a few of the TIM's support 8bpp these are in ENEMY6 and are the hirez Sephiros and Cloud models. I believe other information is in amongst the UV data, namely if the texture is transparent or not. In a few cases the texture is not (actually quite a few) Right now I'm going to assume the alpha channel on pixel of black pixels is 1.
The only way I can think of generating the textures is when I count 'parts' I can use this to find which sections of the TIM are which CLUT then create the texture acordingly in OGL.
Of course counting the parts in done first.
I believe the other sections are all the animation data etc. So I will be inspecting those after I finish making the model pieces look pretty ;)
Cyb
-
Yes, it seems to be palette data between the U/V-coords. I have not checked all models but I assume black (0, 0, 0) is always transparent.
There are two options to render the models with textures:
1. Create one palettized texture (8 bit) and up to 3 palettes
2. Create a High/True-Color texture for every TIM-CLUT
-
Yes, it seems to be palette data between the U/V-coords. I have not checked all models but I assume black (0, 0, 0) is always transparent.
There are two options to render the models with textures:
1. Create one palettized texture (8 bit) and up to 3 palettes
2. Create a High/True-Color texture for every TIM-CLUT
for 1 I'll have to see if I can do that in OGL
2 I didn't really think of but is a possibility. It would still work with FF8 data and FF9 data from what I've seen of that.
There is a third option which I am currently trying to use.
3. Create a texture using the palette and TIM data to generate a complete image from rectangular sections used from the polygon data. This is iffy if it will work but I've noticed all textured regions do not overlap in rectangular coordinates. This is the most likely to work, but complicated. Since the polygons are not ordered based on there palettes (and also cannot be) I use the rectangular max min for X and Y directions then scan the tim generating the 24 bit resulting color data to create the data. My problem is what to do with the alpha channel. At the moment, I am clearing everything and setting the alpha channel on just the sections used / read by the polygons. Messy but for now most likely to work. Since it's only done ONCE per for each model It shouldn't have too much of an overhead.
I think the single texture in 32bit is the 'best' however as you've seen how I am doing it, well it's tricky :)
Cyb
-
We have to correct the u/v-coords a little bit.
Change this:
fU = (1.0f / static_cast<float>(TIM.Width)) * static_cast<float>(ucU);
fV = (1.0f / static_cast<float>(TIM.Height)) * static_cast<float>(ucV);
to something like this:
fU = (1.0f / static_cast<float>(TIM.Width + 4)) * static_cast<float>(ucU);
fV = (1.0f / static_cast<float>(TIM.Height + 6)) * static_cast<float>(ucV);
-
I don't know if this helps but if your looking for more info on the TIM format.
http://rveach.romhack.org/
The page contains a PSX TIM viewer/extractor/insertor, the author of the tool may be of some help and he posted other information in the INFO PSX TIM section
-
Texturing seems to be more complicated. Obviously we have to read in some TIMs from right to left or use this formula: "fU = 1.0f - fU". I should code a more comfortable editor before I continue to decrypt this file format.
Merry X-mas and a happy new year!
-
Yes.. I'm still trying to figure a way around open GL's binary size requirements for textures.
Makes this kind of stuff a pain I'm going to work on 'depaletizing' the texture The palette play I think is what is giving me troubles with OGL. This reduces everything to 1 256x256 texture for me, so I have a 'new' time method that reads the time texture assuming color 0 is transparent anything else is opaque. I think this will work for me though it does require yet another rewrite (sigh), it will only need to be done once.
Cyb
-
Palettised textures are going to be a pain with OpenGL, because it doesn't (as you know) support them natively; there's an extension, which most modern cards don't support, because nobody uses paletted textures any more... ;)
Converting them to 32-bit textures as you read them in is the best choice by a long way. When you're decoding the file format yourself, as you will be for TIM's, it's not really extra effort anyway.
The binary size requirement for OpenGL textures shouldn't give you any problems, though. If no polygon uses multiple palettes, then you can have one texture per palette, and each polygon uses one texture. If for some reason you REALLY need to have non-power-of-two-dimensioned textures (NPOTD), then there is an OpenGL extension to support that (at least one extension, maybe two), but your program isn't going to be fully portable if it uses that. Quality will suffer, too: there's good reasons why graphics cards prefer POTD textures.
-
Palettised textures are going to be a pain with OpenGL, because it doesn't (as you know) support them natively; there's an extension, which most modern cards don't support, because nobody uses paletted textures any more... ;)
Converting them to 32-bit textures as you read them in is the best choice by a long way. When you're decoding the file format yourself, as you will be for TIM's, it's not really extra effort anyway.
The binary size requirement for OpenGL textures shouldn't give you any problems, though. If no polygon uses multiple palettes, then you can have one texture per palette, and each polygon uses one texture. If for some reason you REALLY need to have non-power-of-two-dimensioned textures (NPOTD), then there is an OpenGL extension to support that (at least one extension, maybe two), but your program isn't going to be fully portable if it uses that. Quality will suffer, too: there's good reasons why graphics cards prefer POTD textures.
My current method needs improving what I do is go through each part and check for textured triangles and quads then use the edges of where the trinagles and quads are to choose the texture information. I 'assume' anything black is transparent. This is probably wrong but I couldn't think of any more convienent way :)
Unfortunately now my application just closes when I try viewing with OGl. I wish it left some error or the like darn it so I knew why it was being a whiner.
Cyb
-
Raw data from structure
Parts[35] =
{
//OFFSET ID UNKNOWN DATA
000000 0 FFCE ff ce 1111111111001110
000124 1 FF1F ff 1f 1111111100011111
0003C8 2 FF69 ff 69 1111111101101001
000B7C 1 FF21 ff 21 1111111100100001
000000 4 FFC4 ff c4 1111111111000100
000000 5 FF23 ff 23 1111111100100011
001A44 6 FEEC fe ec 1111111011101100
001D58 7 FFCC ff cc 1111111111001100
000000 8 FF6A ff 6a 1111111101101010
001FEC 7 FFC8 ff c8 1111111111001000
000000 10 FF6A ff 6a 1111111101101010
0020F0 7 FFC8 ff c8 1111111111001000
000000 12 FF6A ff 6a 1111111101101010
0021F4 7 FFCC ff cc 1111111111001100
000000 14 FF6A ff 6a 1111111101101010
0022F8 1 FF21 ff 21 1111111100100001
000000 16 FFC4 ff c4 1111111111000100
000000 17 FF23 ff 23 1111111100100011
0023FC 18 FEEC fe ec 1111111011101100
002710 19 FFCC ff cc 1111111111001100
000000 20 FF6A ff 6a 1111111101101010
0029A4 19 FFC8 ff c8 1111111111001000
000000 22 FF6A ff 6a 1111111101101010
002AA8 19 FFC8 ff c8 1111111111001000
000000 24 FF6A ff 6a 1111111101101010
002BAC 19 FFCC ff cc 1111111111001100
000000 26 FF6A ff 6a 1111111101101010
002CB0 0 FFD8 ff d8 1111111111011000
000000 28 FEBB fe bb 1111111010111011
002DB4 29 FF00 ff 00 1111111100000000
002F88 30 FF6E ff 6e 1111111101101110
0031EC 0 FFD8 ff d8 1111111111011000
000000 32 FEBB fe bb 1111111010111011
003670 33 FF00 ff 00 1111111100000000
003844 34 FF6E ff 6e 1111111101101110
}
Inspection results of data
FF7 Object ENEMY019.LZS
LOC ID PART DESCRIPTION
0 0 NONE uncertain
1 1 1 Waist
2 2 2 Chest
3 1 3 Head
4 4 NONE uncertain
5 5 NONE uncertain
6 6 4 Right shoulder
7 7 5 Right Gun Hand
8 8 NONE uncertain
9 7 6 Left Talon?
10 10 NONE uncertain
11 7 7 Middle Talon 1?
12 12 NONE uncertain
13 7 8 Middle Talon 2?
14 14 NONE uncertain
15 1 9 Right Talon?
16 16 NONE uncertain
17 17 NONE uncertain
18 18 10 Left Shoulder
19 19 11 Left Gun hand
20 20 NONE uncertain
21 19 12 Right Talon?
22 22 NONE uncertain
23 19 13 Middle Talon1?
24 24 NONE uncertain
25 19 14 Middle Talon2?
26 26 NONE uncertain
27 0 15 Left Talon?
28 28 NONE uncertain
29 29 16 thigh?
30 30 17 shin?
31 0 18 foot?
32 32 NONE uncertain
33 33 20 shin?
34 34 21 foot?
After some careful tweaking through the unknown area you'll notice some information I've gathered. ID is not the object ID to be honest it's behavior is rather inconsistant with that possibility. My guess is it's more likely the parent. The object format in FF7 is quite complicated (way too complicated I think hehehe) I've detailed an example of ENEMY019.
I can't get textureing working yet so I'm toying with this some trying to figure it out.
Anything with a REAL object on it has the offset > 0 almost always a non object referencing member has the same ID as it's index in the array. (Self referencing) they don't seem to mean ANYTHING at all actually ;)
I think ID is actually PARENT information notice the arms and talons they all form a heirarchy.
How to string everything together is anyones guess. I think the none object referencing stuff merely indicates a 'break' in a group of objects. This however gives no positional information. I've also noticed they throw in zero's at random seemingly into the array of references. That I believe is elsewhere in the file. Pretty much section zero is resolved as far as I can tell :)
The flag/whatever area is still the whatever area to me.. I've yet to make sense of it.
I think I'll have to next try and figure out the other sections (other than the TIM one).
-
ok, i really shouldnt post because i have no idea what im talking about, but that said. what about viewing a full thingy. like all of tifa? or is that like, not possible?
-
ok, i really shouldnt post because i have no idea what im talking about, but that said. what about viewing a full thingy. like all of tifa? or is that like, not possible?
You're right you probably shouldn't post ;) hehehe
No it's not.. I'm trying to figure out how it arranges the skeletal information and where that information is stored. I have an idea it will just take a little while beating the data out of it.
Cyb
-
Desaigy Ouimate: it is possible, on FF7 PC
-
Desaigy Ouimate: it is possible, on FF7 PC
Oh.. yes forgot that.. what tool does that? I forget.
Kislinskiy:
No good fortune as yet, however the 'structure' hid in unknown 'makes' sense. It however doesn't give rotation and offsets.
However...
Section[0] contains
bone structure heirarchy
vertices
textured trii's
textured quads
tri's
quads
Something I've noticed about
Section[1]
it's ALWAYS about the same size. The bigger the model it grows bigger It doesn't vary a lot so the information contained in it is fairly static. This I believe is the section that contains pertinent information about the model and it's sections. As the number of sections increase it increases in size. Thus I think it contains some important information. It's largest on the character models.
Hacking time Ciao
-
And now for something completely different.
First ALL the weapon models are stored with the character model.
The END of the character model is the TIM image in the file. However everything beyond that is a model for there weapons. No Changes to decoding of the section need to be made, it decodes it as is just like section 0 is decoded. TADA! :)
That's IT I can view the weapons just dandy this way.
And here is the image to prove it!
Image removed Site is gone
PS only one.. we don't need all the weapons to see this fact.
PPS Each Character has 16 weapons.. low rez Sephiroth has 16 Masuami's for example.
-
That's a good news. :)
Currently I have no time to look at the file format because i want to learn more on advanced OOP first (patterns, composition, delegation, interfaces etc.). Then I will try to code a well designed model viewer for this file format to continue decyrption more comfortable. 8)
-
That's a good news. :)
Currently I have no time to look at the file format because i want to learn more on advanced OOP first (patterns, composition, delegation, interfaces etc.). Then I will try to code a well designed model viewer for this file format to continue decyrption more comfortable. 8)
Oh.. I take the other approach to things get something working for a bit then rebuild it after I see how far I can push it. I suppose I should try and make it more balanced. I've already had to introduce multithreading just so I can scan a disk without the form freezing. I probably should do that for reading models as well. Lots of improvements to make.
Although I think soon I should be able to break the bone format, it's coming bit by bit. Now that I know what those extra things are past the TIM image are, I can focus on what's between the TIM and the model data. Section 1 is the most suspicious one of these It contains a number of odd short ints and ints I think they are a list of offsets, there also seem to be a list of short ints later on.. I suspect they are bone offsets and rotations.
Anyhow glad you aren't dead.
I went back to my original 'extraction' method for textures (go through the textures and use the correct palette) this works correctly now. My only problem is I need to blend the textures with the polygons now like decals in OGL :)
Cyb
-
A few things on textures:
Forget that about U = 1 - U.
Forget that about U/V correction.
fU = 1 / Width * U
fV = 1 / Height * V
HICLOUD-TIM (256x192, 8 bit):
0) 0...127,128...255
1) 0...127,128...255
...
191) 0...127,128...255
convert to:
0) 128...255,0...127
1) 128...255,0...127
...
191) 128...255,0...127
(Any other models with 8 bit TIM? Swap them too?)
CLUT information stored between textured triangle/plane data:
4 bit:
00 78 = CLUT 0
40 78 = CLUT 1
80 78 = CLUT 2
...
8 bit:
14 30 = CLUT 0
Evt. further changes of U/V mapping. Look at first textured part of ENEMY019.
-
Well I have the texture ordering almost right.. (heh)
So it reverses the UV coordinates on an 8bpp bitmap as oposed to a 4bpp bitmap? that's bizare. Of course as one person I heard say 'FF7 file formats are horribly complicated and the guy making them must have been horribly confused' :)
Cyb
-
Solution of the "Last Object Missed Problem"
"unknown structures" of ENEMY165:
(http://home.arcor.de/kislinskiy/ENEMY165.gif)
number of structs
structs
point of interest
There is a UINT32 after the "unknown structures" and before the coordinates of the first visible object. This is an offset to a visible object like the first UINT32's of the "unknown structures".
Now we should not look at the "unknown structures" in this way:
number of structs
struct 0
struct 1
...
struct n
struct m
We should look at it in this way:
number of structs
offset 0 <- connector 0 -> offset 1 <- connector 1 -> ... <- connector n -> offset m
-
So basically it's a list of the number of 'information' structures surrounded by pointers?
I remember going through it Quite meticulously
So what we really have is
N Entries
One 32 bit empty pointer at the begining and
<heirchy> U16
<flags> U16
<Offset> U32
There always seems to be a reference to the last object as well. :)
So looking at it that way may make more sense (Shift the whole array by 4 bytes)
I know what you are (originally) saying however there are no links to anything real otherwise. If you shift it by four bytes and refer to it as that array then the data makes a bit more sense. Let me tinker with it and see if I can get anything useful.
Still haven't found the Structure of Section 1 yet but I think it has to do with the model standing still.
None of the numbers as yet make sense but I believe it's critical to knowing how to piece together the model (correctly). There are a series of short ints and long ints. Then what might be coordinates. I guess I continue to beat on the data tell I decipher it?
I looked at the data (the way I tweaked it) seems to make sense now really (with the offset at the end and skiping to an offset 12 to start looking at the structure).
Cyb
-
Has anyone fully rendered Jessie? I remember going through with a model viewer and finding a Jessie model somewhere in there.
-
Has anyone fully rendered Jessie? I remember going through with a model viewer and finding a Jessie model somewhere in there.
These are battle models, scene models are included with the scenes they are in (IE say the reactor at the begining of the game or the train station). Cloud Jesse Barret etc are all included in the actual scene. For battle the game loads in a different set of models (that look totally different as well). At the moment these models haven't been found or extracted by anything I've made :)
Cyb
-
Yeah, the Jessie model I saw was a battle model; it was only the top half of Jessie so I assumed the viewer couldn't fully render the model.
-
Yeah, the Jessie model I saw was a battle model; it was only the top half of Jessie so I assumed the viewer couldn't fully render the model.
Jessie is not possible to have in a battle thus it can't be a battle model. I've never seen Jessie in a battle in all the times I've played FF7 through the part Jessie is still alive. Jessie is never in your battle group either. The only thing I can think of is someone extracted Jessie from a scene file and put it in a battle sccene (quite doable).
Sounds like something Ficedula would do with Zanan.
I made a 'exporter' plugin module for that and POV Ray, I suppose if I understood FF7 battle scenes well enough I could make something like Zangan.
Cyb
-
By scene model you mean the low-poly model that you use to navigate the game right?
The model I saw was the top half of what appeared to be a battle model, or something that could have been possibly used in a battle sequence.
-
That model was used in the scene where you and Jessie are standing in front of the monitor, and she explains the Midgar rail system to you. I've seen it in the PC version, using I believe Ifalna. There is one of Cloud in the same scale.
-Contra-
-
the highly detailed Cloud and half-Jessie models are never used in the game. It's been theorized that Square was going to make higher-resolution models throughout the game, but gave up, leaving what you see there.
-
Are you *sure* they aren't used when Cloud and Jessie are looking at the railway map?
I mean, I could be wrong, but I really think they are.
-
How about everyone posts his complete know-how about the .LZS model files to decrypt it evt. 100%? Are you afraid that you have to credit other people in your application? Shame on you... :wink:
Bits Description
======================================
32 NumOffsets
32 * NumOffsets Offsets
32 NumUnknown1
32 00 00 00 00
64 * NumUnknown1 Unknown1 structures (Hierachy data ?)
32 00 00 00 00
32 VertexDataSize in Bytes
8 * VertexDataSize VertexData (4 * 2 Bytes -> X, Y, Z, Unknown)
32 00 00 20 00
32 NumLines
--- LINE STRUCTURE * NumLines --- (not used in game) -------------------
64 Indices in VertexData(4 * 2 Bytes -> A, B, 0, 0)
32 * 2 Color (4 * 1 Byte -> R, G, B, Unknown)
------------------------------------------------------------------------
32 NumTriangles
--- TRIANGLE STRUCTURE * NumTriangles ----------------------------------
64 Indices in VertexData(4 * 2 Bytes -> A, B, C, 0)
32 * 3 Color (4 * 1 Byte -> R, G, B, Unknown)
------------------------------------------------------------------------
32 NumQuads
--- QUAD STRUCTURE * NumQuads ------------------------------------------
64 Indices in VertexData(4 * 2 Bytes -> A, B, C, D)
32 * 4 Color (4 * 1 Byte -> R, G, B, Unknown)
------------------------------------------------------------------------
XX UNKNOWN + AnimationData?
Last Entry of Offsets TIM-File (only palette(s) if model has no texture)
== END ==
Unknown1 structure has a pattern that could be hierachical data.
I had not looked at models with textures yet (UV-Coords in Color-data?)
ENEMY000.LZS - Yellow Pyramid
More detailed data follows tomorrow but first:
Now it's YOUR turn.
Excuse my ignorance, but aren't .LZS files supposed to be compressed?
and if so how can I uncompress them? (lzs.exe from Ficedula's site seems to constantly crash on either XP or Win98)
Thank you in advance
-
Welcome to the Forums Anakin. We will be watching your career with great interest...
Please don't bring back dead topics like this if you don't have something to add to the discussion. It's in the rules (http://forums.qhimm.com/viewtopic.php?t=1731).
Yes .lzs files are compressed. If ficedula's app isn't working for you (makes sense--it's designed for files from the PC version), the only other one I know of is a tool written by M4v3R. I can't find a working link, though, so you'll just have to hope he posts one (no whining/begging, please. I don't have it.)
the highly detailed Cloud and half-Jessie models are never used in the game.
that model was used in the scene where you and Jessie are standing in front of the monitor, and she explains the Midgar rail system to you. I've seen it in the PC version, using I believe Ifalna. There is one of Cloud in the same scale.
After a quick Techdoc consultation, it looks like Contra is correct. Here's proof:
The train monitor location is rootmap.
rootmap loads the following two 3D models:
clgd.hrc -high res. Cloud
cmde.hrc -high res. Jessy upper torso
-
Welcome to the Forums Anakin. We will be watching your career with great interest...
Please don't bring back dead topics like this if you don't have something to add to the discussion. It's in the rules (http://forums.qhimm.com/viewtopic.php?t=1731).
Yes .lzs files are compressed. If ficedula's app isn't working for you (makes sense--it's designed for files from the PC version), the only other one I know of is a tool written by M4v3R. I can't find a working link, though, so you'll just have to hope he posts one (no whining/begging, please. I don't have it.)
LOL
Thx for bothering to answer
-
LOL
Thx for bothering to answer
Hmmm well the thread isn't dead however it's just not been active because I ran into trouble with getting OpenGL to apply textures to surfaces, I don't know what I am doing wrong either.
As for compression
All LZS files are compressed, in fact almost all files are compressed in FF7, I suppose if they hadn't done that they couldn't fit the entire game on 3 disks (4 like the successors). FF7 had a lot of cool ideas in it, however I think 1/3 of them never saw completion (such as the Shinra dolls).
Suggestion don't quote a huge section of text next time ;)
If you have questions regarding the Battle models for the playstation version ask away :)
Cyb
-
Thx
Well in fact I'm also interested in the simpler -deformed- character models that are used throughout the game (always refering to the PSX version).
I would like to be able to export the coordinates of the shapes that make up these characters as well so I could reconstruct them in AutoCad or 3DMax.
Only I don't know where to start from, where to look...
-
I would like to be able to export the coordinates of the shapes that make up these characters as well so I could reconstruct them in AutoCad or 3DMax.
Dont know about PSX files ... if you are interested in PC files this is possible.
-
Dont know about PSX files ... if you are interested in PC files this is possible.
Yes, I've seen it done in another thread (PC version).
You know there is this program FF7vm001 http://www.cute.or.jp/~makuchan/pce/ff7v.html which can view the 3D models of PSX version, but it has no option for extracting them.
Hence it IS possible to manipulate the PSX files on a PC, the problem is how is it done?
-
why using PSX files when PC files are more easy to use?
-
Are you sure the models are identical?
-
Are you sure the models are identical?
If not the same, better. :)
-
Are you sure the models are identical?
If not the same, better. :)
*The model format is not the same
*They are no different in quality than the PSX version
[/list:u]
It appears Eidos took the original data files and ported them to something that worked for them. The P model information is completely different than the playstation information. FF7mv was supposed to have a sequel but the author never made it. I suppose he got busy. It would have been nice if he had shared the model information. However As you can see the PSX versions model data is loosely extractable. Definately imperfect Kelsinki is further along than I by all means :) I stoped for a bit because banging my head against the wall didn't help ;)
It's the same models per sea they are just same original data :)
I wish they WERE the same it would save me a lot of hassle dang it.
Cyb
-
Hmmm, I seem to be getting a small bug with this program, whenever I convert it to 3DSmax, the character's are missing facial features/textures and some of the polygons are off. Is there a fix for this?
-
Well, the models come with .tex files, which contain all of the eyes and mouths that would appear on the models. I haven't screwed with 3DSMax in a long time, especially with ff7 models, but as far as I know you'll have to paste the textures onto the models manually.
-
When you load it in 3DSmax I doubt it loads the materials with it. You will have to apply them yourself I guess...
-
Hmm, that still doesn't explain that polygons being misaligned. Perhaps there is a fix for Biturn that I missed...
-
Alright Kislinskiy
why Icouldn't make heads or tales of the 'unknown' part of section 0 of the model files. Please so DOH loadly 3 times .. it will make me feel less stupid :oops:
here is a BETTER look at the structure of the begining of that section :)
typedef struct
{
UINT16 Parent; // parent bone
INT16 BoneLength;// length of this bone (not completely understood yet)
UINT32 Offset; // Offset to data that belongs to this bone
} bone_data;
UINT32 BONE_COUNT;
bone_data ROOT_BONE; // There is always a ROOT bone even if there is no model data!
bone_data bones[BONE_COUNT];
That's it.. kindly beat your head against the wall and laugh like a madman it's so simple ARGH. You have a ROOT BONE, I was always ignoring that thinking it was just empty data, which it is. So basically at 0x0000 you have the count of bones then the Root bone then the actual bone information. You may now sigh and let out a light scream.
Essentially the root bone is all zeros and that was what was confusing me. Any bone that does NOT have an offset is a JOINT! (IE if the Offset value is 00000000) and has no visable data. That's it.. I know, too simple :lol:
Cyb
-
That's also new to me. :) The last time I looked at this file format was in January. I know about the Parent-UInt16, the root bone and the joints but I didn't know that the negative values are the bone length.
[loud]DOH!! DOH!! DOH!![/loud] :wink:
-
So basically it's kind of empty data bone lengths and offsets to bones and joint lengths. NO position information but the lengths are there and there jointedness is 'obvious'
I'll post a 'structured' decoding of Yuffie sometime.
Now.. if someone would kindly put up the other data information used to position the parts in the PC version I bet one could figure out the thing on the PSX quickly (mumble).
Cyb
-
NO position information but the lengths are there
Maybe its like in PC version, in skeleton file are only lengths and parents of the bone, and rotations of the bones are in different file.
-
NO position information but the lengths are there
Maybe its like in PC version, in skeleton file are only lengths and parents of the bone, and rotations of the bones are in different file.
Well they aren't seperate files however, they are seperate sections.
For example Section 1 of the PSX file has the following information
bone information
visable structures.
the bone information is a binary equivalent to the PC's HRC data
the visable structures are binary versions of the PC's RSD formation
The bone information has offset references to the visable structures for regular bones and a NULL offset for Joints.
SO if you have the file format for the bone rotation information for the PC let me know! Because then I can piece one of these things together from that on the PSX which is all compiled.
Cyb
-
Yup I have to have it somewhere, i've coded those long time ago into biturn
-- going to search for sourcecodes --
So i bustled some raw description of PC FF7 anim file .. here it is:
http://mirex.mypage.sk/FILES/ff7_a.txt
-
Looking at that indicates to me that it's some intermediate format they created and nothing like the HRC or RSD files I guess they started making there own proprietary first hmms.
If it's not in ASCII it probably isn't the base format (sigh). I wonder how many text files are in the PC version.
Cyb
-
Would this be of any service?
File Name: SEFIROS.LZS
File Size: 98044
TOD found at offset 1820
FileSize:336348 Version:0 Resolution:16 NumFrames:248
TOD found at offset 11072
FileSize:400840 Version:0 Resolution:176 NumFrames:88
TOD found at offset 18820
FileSize:412008 Version:0 Resolution:40 NumFrames:200
TOD found at offset 19304
FileSize:336728 Version:0 Resolution:96 NumFrames:104
TOD found at offset 22780
FileSize:343140 Version:0 Resolution:72 NumFrames:144
TOD found at offset 22820
FileSize:237148 Version:0 Resolution:136 NumFrames:128
TOD found at offset 23356
FileSize:347568 Version:0 Resolution:72 NumFrames:96
TOD found at offset 23396
FileSize:387184 Version:0 Resolution:136 NumFrames:40
TOD found at offset 23416
FileSize:281768 Version:0 Resolution:96 NumFrames:128
TOD found at offset 24388
FileSize:405620 Version:0 Resolution:8 NumFrames:16
TOD found at offset 24408
FileSize:374792 Version:0 Resolution:96 NumFrames:88
TOD found at offset 24428
FileSize:172992 Version:0 Resolution:72 NumFrames:96
TOD found at offset 24448
FileSize:331048 Version:0 Resolution:88 NumFrames:32
TOD found at offset 25216
FileSize:30360 Version:0 Resolution:64 NumFrames:48
TOD found at offset 25456
FileSize:131720 Version:0 Resolution:24 NumFrames:8
TOD found at offset 25516
FileSize:254684 Version:0 Resolution:32 NumFrames:88
TOD found at offset 25556
FileSize:414472 Version:0 Resolution:88 NumFrames:24
TOD found at offset 28268
FileSize:414520 Version:0 Resolution:88 NumFrames:56
TOD found at offset 28348
FileSize:226020 Version:0 Resolution:16 NumFrames:72
TOD found at offset 28508
FileSize:290816 Version:0 Resolution:56 NumFrames:24
TOD found at offset 28708
FileSize:329908 Version:0 Resolution:152 NumFrames:144
TOD found at offset 30356
FileSize:25728 Version:0 Resolution:136 NumFrames:112
TOD found at offset 30616
FileSize:25728 Version:0 Resolution:32 NumFrames:24
TOD found at offset 31632
FileSize:364988 Version:0 Resolution:112 NumFrames:144
TOD found at offset 31932
FileSize:24276 Version:0 Resolution:120 NumFrames:56
TOD found at offset 32132
FileSize:135912 Version:0 Resolution:232 NumFrames:200
TOD found at offset 32832
FileSize:436704 Version:0 Resolution:144 NumFrames:368
TOD found at offset 34220
FileSize:466168 Version:0 Resolution:32 NumFrames:128
TOD found at offset 34380
FileSize:366220 Version:0 Resolution:136 NumFrames:104
4 bit TIM + CLUT found at offset 51420
FileSize:5728 BufferX:320 BufferY:0 Width:176 Height:64
10000000080000004C0000000000E0011000020000003436D12D4D1DEA10E230
TOD found at offset 58052
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 60608
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 63164
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 65720
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 68276
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 70832
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 73388
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 75944
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 78500
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 81056
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 83612
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 86168
FileSize:167544 Version:0 Resolution:56 NumFrames:72
TOD found at offset 88724
FileSize:111284 Version:0 Resolution:56 NumFrames:72
TOD found at offset 91280
FileSize:111284 Version:0 Resolution:56 NumFrames:72
TOD found at offset 93836
FileSize:111284 Version:0 Resolution:56 NumFrames:72
TOD found at offset 96392
FileSize:107840 Version:0 Resolution:56 NumFrames:72
-
I wonder how many text files are in the PC version.
I havent seen much of them so far. Only HRC's and RSD's.
-
Haven't posted here for a little while....did anyone make any more attempt on trying to figure out how the transparencies work with enemy models?
Thanks,
~Sky
-
Texture transparencies? Can't remember well but try this:
1) Black is transparent
2) First palette entry is transparent
-
Well actually a bit further Kislinskiy
[list=1]
- if bit 15 is of the color is Set (see the Palette) the value is transparent
- color zero (4 or 8 bit textures) is transparent
[/list:o]
I don't know for certain all black is transparent however palette entry 0 is.
Apparently the Palettes in FF7 use the PS1's transparency bit as well.
Cyb
-
I don't know if it's the textures that are transparent...I think it's the entire pologon...
Here's an example with Brain Pod
actual shot taken ingame: www.ffcompendium.com/~Skylark/BrainPod.jpg
with model viewer: www.ffcompendium.com/~Skylark/Brain.jpg
Then one other problem I ran into with the viewer was with Death Dealer....when viewing one of his cards from the bottom the texture doesn't load and you can see completly through it....but if you view it from the top you can see the back of the card.
www.ffcompendium.com/~Skylark/DeathCard.bmp (sorry for the bmp)
-
Haven't posted here for a little while....did anyone make any more attempt on trying to figure out how the transparencies work with enemy models?
Not me. I was not working on ff7 for a long time ... right now ripping apart HalfLife models
-
I don't know if it's the textures that are transparent...I think it's the entire pologon...
Here's an example with Brain Pod
actual shot taken ingame: www.ffcompendium.com/~Skylark/BrainPod.jpg
with model viewer: www.ffcompendium.com/~Skylark/Brain.jpg
Then one other problem I ran into with the viewer was with Death Dealer....when viewing one of his cards from the bottom the texture doesn't load and you can see completly through it....but if you view it from the top you can see the back of the card.
www.ffcompendium.com/~Skylark/DeathCard.bmp (sorry for the bmp)
I'm not sure what you are getting at. The texture determines what part of the polygon is transparent if at all. Each model consists of a number of objects. Each texture has a palette, the palette (most often several 4 bit ones), is then used to create the texture in the texture cache follow the rules I outlined. If the whole polygon was transparent you couldn't see clouds eyes, instead you would just see the polygons behind the eyes and no eyes. The textured polygons are rendered on the final frame pass.
At least in PS1 FF7 that's the way things are done! :)
Cyb
-
I'm must saying...Leviathan currently doesn't support the transparencies.....if you know how this is done - tell mirex so he can add it to the viewer when he gets time...
Is there any way you can fix the little card error with the Death Dealer so I can view what that card actually is? :P
Thanks.
-
Judging by what's there and what's missing from the Death Dealer's attacks, I'd guess it's The Sun that's missing. (Sun: Magical Change Status, inflicts Silence/Darkness with Class [63] chance)
The other four cards are all there.
-
Cyberman: I think that Lord_Skylark has in mind the polygons that are half-transparent. Im not sure if they are on PSX though. For example brain pod has transparent little round window on its side, through which you can see the brain inside the jug.
Is there any way you can fix the little card error with the Death Dealer so I can view what that card actually is? :P
Im not sure, but IIRC there is none ... i remember only 7 cards on the texture.
-
On semi transparent (Opaque) polys
You know, have you guys maybe thought that one of the vertexs have the mask bit (bit 15) set and it's interpolating the transparency on the polygon itself?
-
honestly nope ... but i thought that transparency info could be somewhere in the groups ... because one of Cloud's swords gets more and less transparent, i think it depends on his health or something
-
honestly nope ... but i thought that transparency info could be somewhere in the groups ... because one of Cloud's swords gets more and less transparent, i think it depends on his health or something
If youre referring to his ultimate weapon, yea, its shade changes depending on his health...
-
honestly nope ... but i thought that transparency info could be somewhere in the groups ... because one of Cloud's swords gets more and less transparent, i think it depends on his health or something
If youre referring to his ultimate weapon, yea, its shade changes depending on his health...
And his "Organics" Weapon does that I THINK...Not sure though
-
honestly nope ... but i thought that transparency info could be somewhere in the groups ... because one of Cloud's swords gets more and less transparent, i think it depends on his health or something
Well its definately not in the textures because there are no textures for weapons. Unless they handle that as an exception to the rule (IE unique operation).
I've almost got textures working on the models.
That and the animation information will make things visiable.
Cyb
-
Well things have been quiet for a while.
State of things are thus:
We know the (mumble) bone format and length information
It's now pretty fast to decode that information on the PC.
The remaining objective is the animation information.
Unforunately for the PC and PSX this is poorly understood.
This weekend it should meet it's match.. or maker or both ;)
Cyb
-
Naru *SHOULD* be up by then, I'm still using a temporary root drive (Read: binaray duct tape) to keep the system from atrophy.
I can catch the information and can toss it into gears.
If anyoe is going to do a write up, for ease of editing, you mind following the header/subheader/trinary header format that's in my latestest version of Gears. That would be great if I can keep it uniform.
Also does any one mind if I convert the European english to American english and clean up the grammer with some of the files? My spell shecker just has a horrable time with some f the stuff you guys write.
-
I have no problem with loosing the U out of colour :P. As long as its in english (Any form of) Ill read it ^_^
-
It's also losing the "z" in realized, and dropping a few extra "u"s, "e"s, and a little clean up in scemantics
-
It's also losing the "z" in realized, and dropping a few extra "u"s, "e"s, and a little clean up in scemantics
It would be interesting to see if Euro english is more like LEET speak than actually from British origins. Of course the British say Maths (which is very confusing because it could be a plural of Math or it could refer to Mathematics that's why in american English if you say that you get strangled it leavesto much in contention and believe it or not.. it's actually irritating to hear for some people).
Back on subject I actually made some progress, at least with the PC format and also discerning more animation information.
EX using cloud as an example the PC version RTDA file has 94 animations. Oddly examining clouds model there are 94 sections between section 0 (battle model and skeleton information) and the models texture. So that leads me to believe that all sections between 0 and the Texture are the animations. Another thing I believe that the animations may infact only store rotation data, and no translation data per sea. Why? Well I think the FF7 engine itself handles the translation. There are only a few places where anyone leaps into the air etc. This is important because those happen to be the special attacks. The animation for the special attacks like these are likely somewhere else. OR The other possibility is that there is a flag indicating if it's just rotation information or not (you would only need rotation for the static poses Victory Being hit Dead and Standing for example).
Just a thought. :D
Cyb
-
i think that:
All bones are rotated in each frame, any character pose can be done by rotation. There are needed only 2 positions, player's current position (that should be somehow modified by engine, because it depends on enemy's position) and weapon's position for thrown weapons.
-
i think that:
All bones are rotated in each frame, any character pose can be done by rotation. There are needed only 2 positions, player's current position (that should be somehow modified by engine, because it depends on enemy's position) and weapon's position for thrown weapons.
Hmmm
There are positions in SCENE.BIN in the BATTLE directory right? For each character I mean.
I think you are right, the system likely translates then generates the information. Thrown weapons are just Yuffie right?
Progress:
Yes I'm making progress, it's slow because I have to deal with C++ classes and there way of handling things. Nothing is as simple as making a COPY of data is it? (geesh)
However Maybe in a week I'll be able to put images up with the new object system. Then maybe the battle scenes and textures will be visable as well.
So my current order of priorities on updates are:
[list=1]
- Finish recoding and generating a functional model from FF7's battle models.
- Make FF7's battle models viewable with the new system.
- Read and decode Battle Scenes into new system.
(note this automatically makes then viewable the way the new viewer is set up)
- Initial release distribution made (IE other people can play with it).
- BCX files.
- BSX files.
- Finish deciphering Animation format.
- Add export dialog and built export to POV ray include file and texture.
- Add plugin support to allow new file type exports.
- Scene Script Viewer/Decompilor with dialog.
- XML data base of known variables added
- Background viewing for FF7
- FF8 Model support
- FF8 Background viewing.
- FF9 Model support
- FF9 Background viewing.
[/list:o]
Cyb
-
Can you put in the list "find the #%#* field walkmesh and camera locations". I'm about ready to put a bounty on that data for a really nice prize *COUGH* US PSOne *COUGH*
-
Can you put in the list "find the #%#* field walkmesh and camera locations". I'm about ready to put a bounty on that data for a really nice prize *COUGH* US PSOne *COUGH*
Well I think the walk mesh is possibly in 2 places most likely only in 1 really.
The BSX files we know contain the NPC field models. I think that's all it contains.
The MIM files are the background images, and that's it.
That leeaves the DAT files which also contain the script. I think it would make sense to have the walk meshes there really and likely the camera locations as well. As you only need one angle per scene this shouldn't require a whole lot of data storage.
A PSOne.. I have one of older units you can hook all sorts of things too :D
I use to play FF7 for HOURS on that thing!
Cyb/Stephen
-
The animation method would most likely be whatever is fastest on a PS1.
Anyway, I saw a project a while back that used OGRE (a free 3d engine) to render Tomb Raider cutscenes and levels. You might want to check it out.
It's here: http://www.evpopov.com/
-
sfx1999:
I'm not sure what you are getting at with what's fastest on the PS1.. most of square FF7 engine is a combination of ideas.
[list=1]
- Compactness of data
- Mixed 3d data with CGI animation.
- Simultaneous operation of several things at once.
- Ease of switching between different views and programs handling those views.
[/list:o]
Basically the thing was designed that way. Animation data they include isn't necessarily the fastest method by far, they included bones and rotation angles for each stage of the animation. Fastest would be to precalculate each polygons position. I believe they choose this method because it got them to the goal of ease of animation, and wasted less space in the game. FF8 and FF9 didn't bother using compression and split the disks at FMV story intervals :) Which works just fine it's just kind of funny.
Yes the TRX site is interesting, though I don't know what the CORE engine has to do with what Square used for FF7 (and they updated it, for FF8 and then again for FF9 it seems it was quite modular so they merely need to make tweaks).
Halkun:
I'll be beating on the new TV over the weekend, a few more hours of redoing the classes and such and I think I'll be able to get it to assimilate model data (woo hoo) after that. Rendering time, hopefully the textures will work after all this (never did before though). It's been such a pain with Win98 and doing any form of developement on the platform ARGH. Hopefully I'll have win2K installed and that will aleviate the anoyance of memory leaks under win98 and thus not have programs cause resource errors while compiling.
Cyb
-
Hey hey. Thanks to Cyberman and his description and also thanks to Kislinskiy i've added reader of LZS's into Biturn ... yet not complete, it cannot read animations and textured polygons coords properly.
Also I cannot read some polygons of HICLOUD.lzs model; but i'll work on that.
Here are some progress pics from cloud.lzs:
(http://bin.mypage.sk/FILES/psx_cl1.png)
(http://bin.mypage.sk/FILES/psx_cl2.png)
(http://bin.mypage.sk/FILES/psx_cl3.png)
here is report what have i read:
reading 23 bones
reading objects
start offset: 0000028C
reading 26 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 48 triangles
reading 0 quads
ending offset: 00000730
start offset: 00000730
reading 76 vertices
reading 0 groups, flag 0020
skipping 0 lines
reading 108 triangles
reading 20 quads
ending offset: 000013F4
start offset: 000013F4
reading 131 vertices
reading 11 groups, flag 0025
#00: 10 2E8 78 80 600 7840 2036 39
#01: 198 10 08 80 2036 7840 600 3A
#02: 2F0 2E8 10 80 380C 7840 2036 600
#03: 2E8 2F0 308 80 2036 7840 380C 3932
#04: 10 198 318 80 600 7840 2036 380D
#05: 300 368 320 80 AB 7800 37B5 1583
#06: 10 2F8 2F0 80 600 7840 3400 380C
#07: 300 310 368 80 AB 7800 BF 37B5
#08: 2F8 10 318 80 3400 7840 600 380D
#09: 368 310 3E0 80 37B5 7800 BF 15E6
#10: 318 198 48 80 380D 7840 2036 3932
skipping 0 lines
reading 248 triangles
reading 5 quads
ending offset: 00002CA8
start offset: 00002CA8
reading 25 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 40 triangles
reading 3 quads
ending offset: 000030EC
start offset: 000030EC
reading 19 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 8 triangles
reading 11 quads
ending offset: 00003340
start offset: 00003340
reading 32 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 40 triangles
reading 10 quads
ending offset: 00003864
start offset: 00003864
reading 24 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 38 triangles
reading 3 quads
ending offset: 00003C78
start offset: 00003C78
reading 11 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 10 triangles
reading 4 quads
ending offset: 00003E0C
start offset: 00003E0C
reading 32 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 40 triangles
reading 10 quads
ending offset: 00004330
start offset: 00004330
reading 14 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 24 triangles
reading 0 quads
ending offset: 00004594
start offset: 00004594
reading 35 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 50 triangles
reading 5 quads
ending offset: 00004B20
start offset: 00004B20
reading 17 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 25 triangles
reading 1 quads
ending offset: 00004DC8
start offset: 00004DC8
reading 11 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 13 triangles
reading 1 quads
ending offset: 00004F50
start offset: 00004F50
reading 14 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 24 triangles
reading 0 quads
ending offset: 000051B4
start offset: 000051B4
reading 35 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 50 triangles
reading 5 quads
ending offset: 00005740
start offset: 00005740
reading 17 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 25 triangles
reading 1 quads
ending offset: 000059E8
start offset: 000059E8
reading 11 vertices
reading 0 groups, flag 0025
skipping 0 lines
reading 13 triangles
reading 1 quads
ending offset: 00005B70
specially to the 'groups' part
#00: 10 2E8 78 80 600 7840 2036 39
#01: 198 10 08 80 2036 7840 600 3A
#02: 2F0 2E8 10 80 380C 7840 2036 600
#03: 2E8 2F0 308 80 2036 7840 380C 3932
#04: 10 198 318 80 600 7840 2036 380D
#05: 300 368 320 80 AB 7800 37B5 1583
#06: 10 2F8 2F0 80 600 7840 3400 380C
#07: 300 310 368 80 AB 7800 BF 37B5
#08: 2F8 10 318 80 3400 7840 600 380D
#09: 368 310 3E0 80 37B5 7800 BF 15E6
#10: 318 198 48 80 380D 7840 2036 3932
first 3 numbers are vertice references (not indexes but offsets, as in polygons) and the rest should be tex coords. i'd say that repeating value '80' and '7840' are just fillers so only rest 3 nums are texture coords (which is enough, 2 bytes for each vertex)
-
Hehehe good stuff Mirex!
About those animations :D
I can't get those working tell I can find out why my vertex data is being corrupted, otherwise things would work. I haven't been able to figure out why or what is corrupting the data. However at least I know it's the vertex data being corrupted. (even if it's been driving me crazy)
After that comes rotating the data and information properly.
My current idea for drawing the whole model is kind of questionable but here it is:
[list=1]
- Draw object
- rotate object
- offset object
- Goto next sibling
- start at 1 again
- if no more siblings, goto parent
- start at 1 again
[/list:o]
I'm assuming that the skeleton is treated as a tree and it's drawn by a depth first traversal of the nods, that is they are drawn rotated and translated, when there are no children. This is a recursive algorythm. Let me know if I have this wrong.
I'll send you the information on extracting the animation data. It's, thank goodness, REALLY simple.
Cyb
-
Yes rotations are parent-relative; if you work in opengl you can use code like this
1) for the main bone do this:
2) glPushMatrix();
glRotate( this bone's x rotation );
glRotate( this bone's y rotation );
glRotate( this bone's z rotation );
glTranslate( this bone's position );
3) draw models attached to this bone
4) find all children of this bone
5) for each child bone do 2)-6)
6) glPopMatrix
#00: 10 2E8 78 80 600 7840 2036 39
#01: 198 10 08 80 2036 7840 600 3A
#02: 2F0 2E8 10 80 380C 7840 2036 600
#03: 2E8 2F0 308 80 2036 7840 380C 3932
#04: 10 198 318 80 600 7840 2036 380D
#05: 300 368 320 80 AB 7800 37B5 1583
#06: 10 2F8 2F0 80 600 7840 3400 380C
#07: 300 310 368 80 AB 7800 BF 37B5
#08: 2F8 10 318 80 3400 7840 600 380D
#09: 368 310 3E0 80 37B5 7800 BF 15E6
#10: 318 198 48 80 380D 7840 2036 3932
first 3 numbers are vertice references (not indexes but offsets, as in polygons) and the rest should be tex coords. i'd say that repeating value '80' and '7840' are just fillers so only rest 3 nums are texture coords (which is enough, 2 bytes for each vertex)
so those texture coords are correct; only thing buggin me is that they are correct only when number at offset 12 is '7840' (the number is actually size of the texture 120x64 ) ... those coords stand for cloud's eyes; but when the number is '7800' (at records #5, #7, #9) then the Y coord is way too big, out of picture. That should stand for cloud's mouth.
-
so those texture coords are correct; only thing buggin me is that they are correct only when number at offset 12 is '7840' (the number is actually size of the texture 120x64 ) ... those coords stand for cloud's eyes; but when the number is '7800' (at records #5, #7, #9) then the Y coord is way too big, out of picture. That should stand for cloud's mouth.
Thanks for the clue, as soon as I fix my corrupted vertex information problem I'll try to see if I can get a whole looking cloud! :)
All right here is how you extract the palette index information You take the palette word and >> 6 then and it with 7. In other words. bit 8:6 are the palette number. Those are the ONLY bits you need for the palette number being used. No X or Y UV value should be > 255 as they are all unsigned bytes. They are relative to the dimensions of the texture of course.
Cyb
-
What happens if you run out of matrixes (over 32)? Most likely wouldn't happen, but you never know if you are using something custom.
Well, you most likely don't need more than 6, because of the root node controlling the other ones.
-
Cyberman, when you mentioned (two posts back) that you would send mirex the animation data, are you talking about the normal .a files from fchar.lgp or the **da ones in battle.lgp?
If you’re talking about the **da ones I would like a copy.
I have been out of the loop for so long, so let me just take a moment to ask a few newbie questions and get caught up.
What is the status on the **da files? More frames working than just the first?
Do we know what is inside **ab files?
How much do we know about the files that store each 2-D map location?
-
Cyberman, when you mentioned (two posts back) that you would send mirex the animation data, are you talking about the normal .a files from fchar.lgp or the **da ones in battle.lgp?
If you’re talking about the **da ones I would like a copy.
I have been out of the loop for so long, so let me just take a moment to ask a few newbie questions and get caught up.
What is the status on the **da files? More frames working than just the first?
Do we know what is inside **ab files?
How much do we know about the files that store each 2-D map location?
No Mirex has that already outlined somewhat I'm refering to the data in the PS1 version of FF7 as with a little help from mirex I have it decoding from the PS1 version of FF7. The animation data is compiled with the models in the PS1 version. However the data isn't completely understood as yet (IE it's not animated yet just the basic information). I still have to fix some bugs in the new object system. Cloud's head currently looks like a yllow and blue flat plate LOL. The PC information you might want to look at halkun's GEAR's project it's pretty up to date as far as I know :)
sfx1999
Only 8 palettes are ever used, as for matrices.. hmmm don't know of the use of any matrix within the model information :) the closest thing might be the animation information :D
-
That’s Cloud’s head from fchar.lgp or cloud.lzs?
Maybe my head is screwed (and it is) but I have never heard of cloud.lzs.
Where is it used (not in battle, not in cinemas, and not on the world map, so where)?
I feel like such a newbie, I’m not going to put my signature on this post.
-
That’s Cloud’s head from fchar.lgp or cloud.lzs?
Maybe my head is screwed (and it is) but I have never heard of cloud.lzs.
Where is it used (not in battle, not in cinemas, and not on the world map, so where)?
I feel like such a newbie, I’m not going to put my signature on this post.
CLOUD.LZS is in the PS1 version of FF7 in ENEMY006 directory on the CD's. That's what we are examining. It contains very similiar data to the PC version (of which data is stuck in an LGP archive). Instead of a bunch of archived sections the data is compacted into something the playstation can load into memory and directly use to draw the information. The file includes all the animation weapon models and the texture for the eyes and mouth. There is some addition information in the CLOUD.LZS but I've yet to figure out what exactly it is or means.
Cyb
-
Cyberman, when you mentioned (two posts back) that you would send mirex the animation data, are you talking about the normal .a files from fchar.lgp or the **da ones in battle.lgp?
If you’re talking about the **da ones I would like a copy.
I have been out of the loop for so long, so let me just take a moment to ask a few newbie questions and get caught up.
What is the status on the **da files? More frames working than just the first?
Do we know what is inside **ab files?
Yup we are now working on the Playstation version of FF7 ... no great progress in FF7 PC .. we still have only 1st frame from DA anim files, no idea about AB files ... but maybe we can get to more information if we compare PC and PSX files.
Oh and Cyberman ... for the displaying of rotations of bones you don't have to use OpenGl functions ... Im using them in the Leviathan (as you can see it works that way too) but in Biturn i'm recalculating the positions by the simple math ... first i calculate positions of all the joints (by rotating the length of the bones) and absolute rotations of the bones, then i rotate body-part-models by these rotations and add bone's position ... and its all set up for displaying
-
Mirex
Yes I originally thought of doing things that way but I prefer to keep things simple so I might as well use that method.
There is one disturbing problem. The parent doesn't know it's children, so I assumed everything was depth first traversed. I suppose the playstation handles rendering this by creating a tree from the bone data and applying the animation data acordingly.
There really is no SIMPLE way to do it looks like.
Cyb
-
You have to think about how the PSX renders things:
When a model is sent to the GPU for render, the GPU packets are placed into an Ordering Table. This is a glorified Linked list with a little hardware help (A free Root Counter is used to transverce the OT to place data within it) When the model is done, the OT is linked to DMA and the whole Linked List is streamed to the GPU like a train.
Most of the time the GPU packets in the OT is orginazed via the Z coordinate, but the packets can have zeroed data for things not calculated yet. As long as the packets are the correct size, with null data in the place that where you will insert data later, everything should be OK. It's bad juju to "expand" a packet in the OT as it messes up the addresses in the Linked list and the Root Counter spins off into oblivion.
After the packets are lined up, you would use the the Root Counter in conjuction with the GTE to insert the correct rotation data. When the root counter is done, you send the thing to the GPU. That's how it's done.
Looks like you might have to make two passes.
I don't know much about 3d graphics, just how the PSX works.
-
There is one disturbing problem. The parent doesn't know it's children, so I assumed everything was depth first traversed. I suppose the playstation handles rendering this by creating a tree from the bone data and applying the animation data acordingly.
Yea parent does not know its children but you can get them easily because children know their parent.
You could make an simple recursive function:
draw_bone( int index, float posx, posy, posz )
{
rotate bone
display bone's body part
calculate bone's minor_joint_position
for( i=0; i<bones_count; i++ ) {
if ( bone[ i ].parent == index )
draw_bone( i, minor_joint_position );
}
}
and call it draw_bone( 0, 0, 0, 0 );
or you could precalculate the order of bones into some stack
-
Yea parent does not know its children but you can get them easily because children know their parent.
You could make an simple recursive function:
draw_bone( int index, float posx, posy, posz )
{
rotate bone
display bone's body part
calculate bone's minor_joint_position
for( i=0; i<bones_count; i++ ) {
if ( bone[ i ].parent == index )
draw_bone( i, minor_joint_position );
}
}
and call it draw_bone( 0, 0, 0, 0 );
or you could precalculate the order of bones into some stack
What axis do you translate on by default the model? Currently I'm assuming X, however I'll worry more once things begin to actually render correctly. Amazingly the C++ with gl code seems to work rather neatly. I just need to hunt down this damnable vertex corruption bug.
I've at least stoped most of the exception errors :D
Cyb
-
After I load a model file (including all bones, etc.) I make a called called SetBoneChildren() which looks like this:
VOID FF7Model::SetBoneChildren() {
char szBuffer[32];
int iIndex;
for ( int I = 0; I < m_iBones; I++ ) {
m_pBone[I].GetParentName( szBuffer );
iIndex = GetBoneIndexByName( szBuffer );
m_pBone[I].SetParentIndex( iIndex );
if ( iIndex != -1 ) {
m_pBone[iIndex].AddChild( I );
}
}
}
This is for the regular overworld models whose parents are stored by name. GetBoneIndexByName() checks the list of bones for a name matching the one supplied and returns its index.
That index (as you can see from the code clearly) is the applied as the current bone’s parent, and then the current bone is added as a child to the same index.
But now I have a question also.
So far, all the overworld models I open with my program load and display perfectly. They are constructed and animated perfectly as well.
I recently downloaded mirex’s document on the battle animation files and used it to start making my program load battle models.
Each part of the model loads and draws perfectly fine.
When applied to an animation frame (and always only the first frame, since that is all that works anyway), however, they go crazy.
My modified animation file loader is temporary just to see how things work with just the first frame, and this is where I have problems.
Here is what I am doing:
My animation loader takes the **da file and reads the appropriate bytes (size determined by the “block_len†[this doesn’t matter since I only read enough vertices to cover the first frame of animation]).
When it parses each into their 12-bit types, this is the code:
for ( int I = 0; I < iBones * 3; I++ ) { // 3 floats per bone.
iCurrentBit = I * 12;
iBytewiseOffset = iCurrentBit / 8;
iBitwiseOffset = iCurrentBit % 8;
iTemp = * (unsigned int *)(&baData[iBytewiseOffset]);
iTemp = iTemp << iBitwiseOffset;
iTemp = iTemp & 0xFFF;
if ( I % 3 == 0 ) {
fTemp0 = (float)iTemp * 360.0f / 4096.0f;
}
if ( I % 3 == 1 ) {
fTemp1 = (float)iTemp * 360.0f / 4096.0f;
}
if ( I % 3 == 2 ) {
fTemp2 = (float)iTemp * 360.0f / 4096.0f;
AttachRotationToBone( 0, iCount, fTemp0, fTemp1, fTemp2 );
iCount++;
}
}
I know this is fairly sloppy but it is piecemill.
On every 3rd read it takes the current read and the previous 2 (as floats) and adds them with AttachRotationToBone(). 0 is used because the frame is always 0 (I am only loading the first frame, remember). iCount represents the bone number. I’ll optimize it when get it working.
Well, the bones, when loaded with the first frame, do not even connect to each other.
I mean, it isn’t even as if they are going to random places, connected to each other.
I can’t quite tell yet how it is deciding to plot one of the 3-D parts, but it is certainly incorrect.
The parts that apply animations to model bones is tried-and-true as shown by hundreds of char.lpg files. So, as long as the animations are loaded correctly, things should work.
Is the code doing what it should? I go to the relative byte (the formula to calculate the current bytes to read and to shift them work) and then shift either by 0 or by 4.
Here are the bytes in rtda (Cloud’s file) as shown by Visual Studio .NET (meaning reverse order of the Windows® Calculator):
00 00 00 00 0C 00 EC E0 00
which translates into:
0.000 0.000 270.000 || 16.875 20.742 315.000 (Generated by my code)
If you take these bytes in this order, the answer would be:
0.000 0.000 0.000 || 270.000 333.106 0.000 (Generated by Windows® Calculator)
Which of these ouputs is correct? In order for my code to generate the second output, I would need to reverse the bytes, then shift (in the opposite direction), then reverse back, and then translate. I am positive this is the correct way to do it.
If the animations are loading correctly, what about the rest of the formats?
The bone lengths on battle models are always nagative. Do they go off a different axis from the overworld models?
When I attach normally, I go to the next bone by translating along the Z axis according to the bone length.
Should I translate along a different axis? Should I translate by -BoneLength?
Are the rotations supposed to be in a different order?
For overworld models I rotate by X, -Y, -Z:
tempXr = m_pBone[I].GetXRotation();
tempYr = m_pBone[I].GetYRotation();
tempZr = m_pBone[I].GetZRotation();
dxRotatef( -tempYr, 0, 1, 0 );
dxRotatef( tempXr, 1, 0, 0 );
dxRotatef( -tempZr, 0, 0, 1 );
m_pBone[I].SetMatrix( mDXMatrixStack[mDXStackPointer] );
dxTranslatef( 0, 0, m_pBone[I].GetLength() );
Are there any special exceptions in the formats for battle models?
L. Spiro
-
L.Spiro: You can compare your rotation values to ones in this thread FF7 Animation information <more about it> (http://forums.qhimm.com/viewtopic.php?t=3394), i've posted there the cloud's (RTDA) rotation values of 1st frame from PC and Cyberman posted values from PSX.
If it won't work out i can post you my piece of c++ code that decodes it properly. I dont think it has any other special expections.
-
Those are the rotations I get when I use Windows® Calculator but for my code it’s just not coming together, even when I reverse the bytes.
I wrote a very simple script to parse these files before diving into C++ with it and the output in the scripts are perfectly fine:
< 0 0 0 >
< 270 333.105469 0 >
< 348.925781 357.626953 327.128906 >
< 16.435547 17.578125 61.523438 >
< 332.050781 337.675781 245.214844 >
…
I guess you can post your code if you like. Much appreciated mi amigo.
L. Spiro
P. S.: 0x0FC8EB30 through 0x0FC8EC44 is one full frame of Cloud’s kneeling animation (near death). I do not yet know how many frames precede this one in this animation so I do not know the exact start of his kneeling animation.
When unpacked, rtda should contain one frame that matches this one exactly (I will post a dump).
0FC8EB30 0. (Base-rtam)
0FC8EB34 12.48047
0FC8EB38 1.669922
0FC8EB3C 329.7656 (Body-rtan)
0FC8EB40 16.43555
0FC8EB44 17.57813
0FC8EB48 61.52344 (Head-rtao)
0FC8EB4C 355.166
0FC8EB50 343.3008
0FC8EB54 239.6777
0FC8EB58 33.13477
0FC8EB5C 87.80273
0FC8EB60 56.86523
0FC8EB64 54.75586
0FC8EB68 51.32813
0FC8EB6C 344.0918 (Shoulder-rtar)
0FC8EB70 320.3613
0FC8EB74 0.
0FC8EB78 0. (Lower Arm-rtas)
0FC8EB7C 0.9667969
0FC8EB80 7.207031
0FC8EB84 334.5117 (Hand-rtat)
0FC8EB88 18.98438
0FC8EB8C 26.98242
0FC8EB90 65.47852
0FC8EB94 61.875
0FC8EB98 357.9785
0FC8EB9C 13.62305
0FC8EBA0 39.11133
0FC8EBA4 255.0586
0FC8EBA8 328.7109 (Shoulder-rtaw)
0FC8EBAC 338.9063
0FC8EBB0 0.
0FC8EBB4 0. (Lower Arm-rtax)
0FC8EBB8 352.9688
0FC8EBBC 359.6484
0FC8EBC0 329.502 (Hand-rtay)
0FC8EBC4 0.
0FC8EBC8 199.7754
0FC8EBCC 0.
0FC8EBD0 61.17188
0FC8EBD4 20.03906
0FC8EBD8 247.7637 (Upper Leg-rtba)
0FC8EBDC 71.80664
0FC8EBE0 0.
0FC8EBE4 0. (Lower Leg-rtbb)
0FC8EBE8 349.0137
0FC8EBEC 344.8828
0FC8EBF0 75.67383 (Upper Foot-rtbc)
0FC8EBF4 298.125
0FC8EBF8 0.
0FC8EBFC 0. (Lower Foot-rtbd)
0FC8EC00 0.
0FC8EC04 47.90039
0FC8EC08 0.
0FC8EC0C 3.867188
0FC8EC10 293.7305
0FC8EC14 2.988281 (Upper Leg-rtbf)
0FC8EC18 70.57617
0FC8EC1C 180.
0FC8EC20 180. (Lower Leg-rtbg)
0FC8EC24 307.9688
0FC8EC28 357.1875
0FC8EC2C 2.197266 (Upper Foot-rtbh)
0FC8EC30 300.0586
0FC8EC34 0.
0FC8EC38 0. (Lower Foot-rtbi)
0FC8EC3C 0.
0FC8EC40 0.
I can post as many frames ahead and behind this as you like but I just can’t tell when this animation ends and the next begins.
When I get my program to load things correctly I can track down the first frame of the first animation in RAM and then export all the following frames so we can see how each should appear, and that should help decode the format much more easily, don’t you think?
-
mirex, I think maybe you should definitely post that code.
After looking more closely at my list (generated by script) and yours on the other page, and compared to Cyberman’s, my list matches Cyberman’s exactly and yours is way off in left field.
So here goes the first animation rotation data of battle cloud:
bones = 23
AnimHdr:
rec_a = 24
rec_b = 90
block_len = 5656
block_a = 90
real_data_len = 5650
translat = < 0, 65024, 62 >
u1 = 0
<270, 333, 0>
<356, 353, 327>
<16, 17, 61>
<338, 334, 243>
<34, 89, 61>
I get 24 for rec_a, sure.
rec_b is 20. Where did you get 90?
block_len is 5656?? Is this rtda?
So when I decoded mine, all of my values matched Cyberman’s exactly.
So obviously Cyberman and I made the same mistake(s).
I modified my loader to perform a 4-bit swap chain at various times during the shifting of the bits but no combination of swapping/shifting/reversing works to get either the results of my script/Cyberman’s results or your results.
One attempt was close but he was mounting a horse and looking over his shoulder.
L. Spiro
-
Spiro I can't find my data in this thread, where did you find it?!
In any case mine almost exactly matches mirex's now.
Are you reading the data in by bytes from the file or loading it into a structure? If the later be sure you have your structure alignment in your copilor optimizations set to BYTE instead of double or quad word. It will never look right otherwise.
My structures that I've posted won't work without that little detail :)
As for reading the 12 bit ints. I do it thus.
if (Odd)
{
AI[0] = (*A_Decode <<8) & 0xFF00 | *(A_Decode + 1);
AI[0]&= 0xFFF;
A_Decode+=2;
AI[1] = (*A_Decode <<8) & 0xFF00 | *(A_Decode + 1);
AI[1]>>= 4;
A_Decode++;
AI[2] = (*A_Decode <<8) & 0xFF00 | *(A_Decode + 1);
AI[2]&= 0xFFF;
A_Decode +=2;
}
else
{
AI[0] = (*A_Decode <<8) & 0xFF00 | *(A_Decode + 1);
AI[0] >>= 4;
A_Decode++;
AI[1] = (*A_Decode <<8) & 0xFF00 | *(A_Decode + 1);
AI[1]&=0xFFF;
A_Decode+=2;
AI[2] = (*A_Decode <<8) & 0xFF00 | *(A_Decode + 1);
AI[2] >>= 4;
A_Decode++;
}
Odd = !Odd;
Bone->Alpha = AI[0] * 360.0/4096.0;
Bone->Beta = AI[1] * 360.0/4096.0;
Bone->Gamma = AI[2] * 360.0/4096.0;
Where A_Decode is a unsigned char array.
AI is an array of ints
Odd is boolean and initialized to false.
Most of my problems were silly mistakes so look at what your code is doing and be sure it's what it's supposed to be doing :D
Cyb
-
All right I have had some success with getting CLOUD.LZS working however I think I'm translating the wrong direction or something :lol: because it looks a bit wrong (after using the original data). Hmmm looks OK just the wrong direction I suspect for translating. I've tried X and Y I suppose all that's left is Z (this is Y).
(http://bin.mypage.sk/FILES/CLOUD_01.jpg)
I also need to be sure to have the quads and triangles ordered right, something isn't working right with that, I believe I'm missing a gl cull call. Hmmm.
Cyb
-
I've had things look like that once. I was drawing quads in the wrong order. Doh!
-
Cyberman, I posted your code exactly and it’s not working for me.
if ( Odd ) {
baEachNumber[0] = (*baData <<8) & 0xFF00 | *(baData + 1);
baEachNumber[0] &= 0xFFF;
baData += 2;
baEachNumber[1] = (*baData <<8) & 0xFF00 | *(baData + 1);
baEachNumber[1] >>= 4;
baData++;
baEachNumber[2] = (*baData <<8) & 0xFF00 | *(baData + 1);
baEachNumber[2] &= 0xFFF;
baData +=2;
}
else {
baEachNumber[0] = (*baData <<8) & 0xFF00 | *(baData + 1);
baEachNumber[0] >>= 4;
baData++;
baEachNumber[1] = (*baData <<8) & 0xFF00 | *(baData + 1);
baEachNumber[1] &=0xFFF;
baData += 2;
baEachNumber[2] = (*baData <<8) & 0xFF00 | *(baData + 1);
baEachNumber[2] >>= 4;
baData++;
}
Odd = !Odd;
fTemp0 = baEachNumber[0] * 360.0f / 4096.0f;
fTemp1 = baEachNumber[1] * 360.0f / 4096.0f;
fTemp2 = baEachNumber[2] * 360.0f / 4096.0f;
AttachRotationToBone( 0, iCount, fTemp0, fTemp1, fTemp2 );
baData is your A_Decode and it is where I stored the entire list of data bytes for the animation.
baEachNumber is clearly where I have store each byte from that array temporarily.
In this case I am doing exactly as you were (shifting my pointer up along the line to get each byte) but I rewrote it to use an index instead but the results were exactly the same.
As for how I am loading it…
I am creating a dynamic byte array
byte * baData = new byte[iChunkSize];
and then reading directly into it
if ( !fread( baData, iChunkSize, 1, file ) ) { return; }
.
The bytes are aligned correctly because I can walk them in the debugger and view them with my hex viewer to see that they match the data file exactly.
I am reading at the correct offset inside the file as well. baData starts as “00 00 00 00 0C…â€.
Your method is giving me these results:
< 0.000 0.000 0.000 >
< 0.000 1.230 0.000 >
< 0.126 20.13 0.879 >
< 16.44 0.703 16.52 >
These numers are all so low it makes me suspect your shifts are in the opposite direction of mine.
In my original code, I shifted << (left) to decrease the bytes.
I notice in your code you shift by 4’s going right.
Sigh. This is the whole reason for any confusion at all. If machines and operating systems didn’t switch the lower-end bits all the time…
I tried switching your >>’s to <<’s and <<’s to >>’s but that failed also.
For a moment, I am going back to my original code.
iCurrentBit = I * 12; // Calculate the current bit.
iBytewiseOffset = iCurrentBit / 8; // Get the offset of the byte that has that bit.
iBitwiseOffset = iCurrentBit % 8; // Calculate how many bits we need to shift.
iTemp = * (unsigned int *)(&baData[iBytewiseOffset]);
iTemp = iTemp << iBitwiseOffset;
SwapAllBytes( (byte *) &iTemp, sizeof( iTemp ) );
iTemp = iTemp & 0xFFF;
if ( I % 3 == 0 ) {
fTemp0 = (float)iTemp * 360.0f / 4096.0f;
}
if ( I % 3 == 1 ) {
fTemp1 = (float)iTemp * 360.0f / 4096.0f;
}
if ( I % 3 == 2 ) {
fTemp2 = (float)iTemp * 360.0f / 4096.0f;
AttachRotationToBone( 0, iCount, fTemp0, fTemp1, fTemp2 );
iCount++;
}
What this does is…
Calculate the current bit.
Calculate which byte has that bit (iCurrentBit / 8).
Calculate the shifting offset (iCurrentBit % 8).
Cast a 4-byte unsigned integer to the value at “iBytewiseOffset†in the array.
iTemp = * (unsigned int *)(&baData[iBytewiseOffset]);
Now the four bytes that make up “iTemp†are the same four bytes that are in the “iBytewiseOffset†location in the stored data array.
baData[3] is “00 0C 00 EC†(EC 00 0C 00 on Windows® Calculator) which makes iTemp 3959426048.
We shift those four bytes left by “iBitwiseOffset†(which toggles between 0 and 4 appropriately, via the math used).
3959426048 becomes 3221274624, or “00 C0 00 C0†(C0 00 C0 00 on Windows® Calculator).
Then we take only the first three byte halves, so we “iTemp &= 0xFFF;â€.
Do the math from there to get the results.
How can this not work? We go right to the byte that holds our data and shift it by either 0 or 4 appropriately. Then take only the first 12 bits and do the math on them. It’s perfectly logical. Check the formulas to see that my math to go to the appropriate byte and to calculate between 0 and 4 bitwise shift IS correct and it works perfectly.
I have modified this in every way. I changed the unsigned int to an unsigned short (to read only the first two bytes). I have changed the order and directiono f the shifting.
Everything.
-
Did you initialize Odd to false?
Let's say your first set of numbers are
00 00 00 00 0C 00 EC E0 00
And they are numbered
00 01 02 03 04 05 06 07 08
from left to right
first you start off at 0 which is EVEN (see odd is false).
You have 3 ints to load the data into (lets say).
A B and C
A = byte 00 << 8
That is byte 0 is shifted left 8 place.
A |= byte 01
So now A has the value 00 00 in it
the hexdecimal numbers are ordered like this
01 23
00 00
You only want the upper 12 bits and they need to be right justified so
A >>=4;
and
-0 12
00 00
is left
The lower 4 bites of byte 1 and all of byte 2 make up the next 12 bit integer.
So
B = Byte 1 << 8
B |= Byte 2
B &= 0xFFF;
This removes the upper four bits we don't want.
again we get 0 in this case but HEY! :)
The next 12 bit in it's
C = Byte 3 << 8
C |= Byte 4;
C is now 000C
C >>=4;
C is now 000
Now we are ODD yep it's bone 1 now
A = Byte 4 << 8
A |= Byte 5
A &= 0xFFF
A = C00
or 3072 * 360.0 / 4096
or 270.0 degrees.
etc etc.. that's how I decode them at least
Cyb
-
Hmmmm here is my code, only from what i remember ... i forgot to put it on the floppy and to bring it here on internet pc ... duh why i dont have internet at home... -_-
unsigned char* data;
int odd;
unsinged long data_pointer;
odd = 0;
data_pointer = 0;
for( i=0; i<bones_count; i++ ) {
// these comments are zero indexed as arrays in c++ :)
// x - take 0st byte and higher 4 bits of 1nd byte
// y - take lower 4 bits of 1nd and whole 2rd
// z - take 3th byte and higher 4 bits of 4th
if ( odd == 0 ) {
x = data[ data_pointer ] << 4 + data[ data_pointer + 1 ] >> 4;
y = ( data[ data_pointer+1 ] & 0xF ) << 8 + data[ data_pointer + 2 ];
z = data[ data_pointer + 3 ] << 4 + data[ data_pointer + 4 ] >> 4;
data_pointer += 4;
} else {
x = ( data[ data_pointer ] & 0xF ) << 8 + data[ data_pointer + 1 ];
y = data[ data_pointer + 2 ] << 4 + data[ data_pointer + 3 ] >> 4;
z = ( data[ data_pointer + 3 ] & 0xF ) << 8 + data[ data_pointer + 4 ];
data_pointer += 5;
}
odd = 1 - odd;
}
hmm now when i compare some data from RTDA (http://bin.mypage.sk/FILES/RTDA) i see that my documentation is maybe wrong ... but anyhow when i take data from RTDA offset 0x24:
FD 2F B2 E9; 10 BB 0C 82
split it by 12 bits:
FD2 FB2 E91 0BB 0C8 (notice relation to original data, and compare it to your calculations results)
and then multiply it by * 360 / 4096 to get angles i get
355,353,327; 16,17...
which are right the data from the animation
<270, 333, 0>
<356, 353, 327> <---
<16, 17, 61> <---
<338, 334, 243>
<34, 89, 61>
So i'll have to take a look at the documents and update them.
--edited lotsa times--
-
I am finally getting the correct rotations (khob khun krap) but I remembered something from a long time ago (this was not affecting my results with getting the correct animation data).
Something was wrong when I loaded models that forced me to load their inverse Y and Z coordinates (per vertex and normal) in order to get their animations to align properly.
When animating, ficedula had told me to do this:
dxRotatef( -fTempYr, 0, 1, 0 );
dxRotatef( fTempXr, 1, 0, 0 );
dxRotatef( -fTempZr, 0, 0, 1 );
He said you had to rotate in that order and by the inverse of the Y and Z (strange how those were the same coordinates I had to reverse to get my model to align properly!).
Now that my battle models have loaded with the correct data, they aren’t displaying properly.
I can’t perform this same translation on them for whatever reason, even though it worked perfectly on all overworld models.
Since you have mentioned how to rotate them but did not mention anything about inverses or order, I am wondering now how to correct whatever was wrong back then (the correct way, instead of loading inverted vertices).
I'm rotating in YXZ order, by negative Y and Z, and then translating by (+)bone length along the Z:
dxTranslatef( 0, 0, m_pBone[I].GetLength() );
Anything wrong with this?
None of my models align at all anymore when I load without inverting each Y and Z vertex/normal.
This is all called in the same manner as you had posted, with each per bone per child, recursively. Consistant motion is created but the ends of each 3D model don’t end where the bones end.
-
Hmmmm here is my code, only from what i remember ... i forgot to put it on the floppy and to bring it here on internet pc ... duh why i dont have internet at home... -_-
USB flash drive time?
Have an idea why my pieces aren't too integrated with cloud mirex? :)
I need to be sure I am doing back face removal! DOH!
Cyb/Stephen
-
USB flash drive time?
Duh not having any ... seems too expensive to me for just a 128MB ... i could have HDD 40GB for that price ... so i use floppies and HDD's :)
Have an idea why my pieces aren't too integrated with cloud mirex?
I need to be sure I am doing back face removal! DOH!
Thats simple, your skelet is not calculated properly, or your model parts are not lined up with skelet ;) Try drawing skeleton aswell (you can use glBegin( LINE ) command), then you will see clearly what's wrong.
-
Can you do me a favor (mirex)?
Try adding something that exports information to a file for each bone you draw on Cloud’s model.
The information just needs to be which bone, and the rotation for that bone.
It may be possible for me to be walking the bones in a slightly wrong order. So I need to see the order of the bones when walked correctly and the rotation for each bone.
Thank you in advance.
L. Spiro
-
Here are my results.
These lists are organized by order of drawing/rotating, walking down the bone tree. It just happens that each child down the line is the next bone in the master list. For each child the matrix is pushed and popped, so the parent rotations carry into the child, and the child is then rotated from there.
For Battle Cloud:
Bone 0: Name: rtam, Parent: -1, Children: 3, Rotations: 0.00000000 0.00000000 0.00000000 Translating: -39.00000000
Bone 1: Name: rtan, Parent: 0, Children: 1, Rotations: 270.00000000 333.10546875 0.00000000 Translating: -163.00000000
Bone 2: Name: rtao, Parent: 1, Children: 0, Rotations: 348.92578125 357.62695313 327.12890625 Translating: -146.00000000
Bone 3: Name: , Parent: 0, Children: 1, Rotations: 16.43554688 17.57812500 61.52343750 Translating: -141.00000000
Bone 4: Name: , Parent: 3, Children: 1, Rotations: 332.05078125 337.67578125 245.21484375 Translating: -59.00000000
Bone 5: Name: rtar, Parent: 4, Children: 1, Rotations: 34.27734375 90.08789063 61.96289063 Translating: -133.00000000
Bone 6: Name: rtas, Parent: 5, Children: 1, Rotations: 74.88281250 42.53906250 335.21484375 Translating: -117.00000000
Bone 7: Name: rtat, Parent: 6, Children: 0, Rotations: 322.29492188 0.00000000 0.00000000 Translating: -85.00000000
Bone 8: Name: , Parent: 0, Children: 1, Rotations: 3.69140625 8.52539063 336.18164063 Translating: -141.00000000
Bone 9: Name: , Parent: 8, Children: 1, Rotations: 358.50585938 21.09375000 53.34960938 Translating: -59.00000000
Bone 10: Name: rtaw, Parent: 9, Children: 1, Rotations: 66.18164063 0.52734375 15.90820313 Translating: -133.00000000
Bone 11: Name: rtax, Parent: 10, Children: 1, Rotations: 56.25000000 242.05078125 318.77929688 Translating: -117.00000000
Bone 12: Name: rtay, Parent: 11, Children: 0, Rotations: 338.20312500 0.00000000 0.00000000 Translating: -76.00000000
Bone 13: Name: , Parent: -1, Children: 1, Rotations: 354.72656250 358.68164063 332.22656250 Translating: -37.00000000
Bone 14: Name: rtba, Parent: 13, Children: 1, Rotations: 0.00000000 229.04296875 0.00000000 Translating: -277.00000000
Bone 15: Name: rtbb, Parent: 14, Children: 1, Rotations: 58.44726563 313.68164063 235.28320313 Translating: -253.00000000
Bone 16: Name: rtbc, Parent: 15, Children: 1, Rotations: 24.96093750 0.00000000 0.00000000 Translating: -77.00000000
Bone 17: Name: rtbd, Parent: 16, Children: 0, Rotations: 303.83789063 358.76953125 68.20312500 Translating: -121.00000000
Bone 18: Name: , Parent: -1, Children: 1, Rotations: 298.91601563 358.41796875 1.40625000 Translating: -37.00000000
Bone 19: Name: rtbf, Parent: 18, Children: 1, Rotations: 0.00000000 77.16796875 0.00000000 Translating: -277.00000000
Bone 20: Name: rtbg, Parent: 19, Children: 1, Rotations: 31.46484375 270.35156250 7.64648438 Translating: -253.00000000
Bone 21: Name: rtbh, Parent: 20, Children: 1, Rotations: 58.44726563 0.00000000 0.00000000 Translating: -77.00000000
Bone 22: Name: rtbi, Parent: 21, Children: 0, Rotations: 331.25976563 349.36523438 5.97656250 Translating: -121.00000000
This results in:
(http://upload.serverseed.com/pictars4/BentCloud.png)
For Overworld Cloud:
Bone 0: Name: hip, Parent: -1, Children: 3,Rotations: 270.00000000 0.00000000 0.00000000 Translating: -1.74572361
Bone 1: Name: chest, Parent: 0, Children: 1,Rotations: 49.21875000 0.00000000 0.00000000 Translating: -5.18153906
Bone 2: Name: head, Parent: 1, Children: 0,Rotations: 313.59375000 0.00000000 0.00000000 Translating: -6.83338976
Bone 3: Name: l_chest, Parent: 0, Children: 1,Rotations: 36.56250000 315.00000000 40.78125000 Translating: -4.98453712
Bone 4: Name: l_collar, Parent: 3, Children: 1,Rotations: 300.93750000 323.43750000 39.37500000 Translating: -2.30645990
Bone 5: Name: l_uparm, Parent: 4, Children: 1,Rotations: 316.40625000 39.37500000 57.65625000 Translating: -2.73342323
Bone 6: Name: l_foarm, Parent: 5, Children: 1,Rotations: 282.65625000 0.00000000 0.00000000 Translating: -4.60069847
Bone 7: Name: l_hand, Parent: 6, Children: 0,Rotations: 0.00000000 0.00000000 0.00000000 Translating: -2.27860451
Bone 8: Name: r_chest, Parent: 0, Children: 1,Rotations: 36.56250000 45.00000000 320.62500000 Translating: -4.98453712
Bone 9: Name: r_collar, Parent: 8, Children: 1,Rotations: 303.75000000 30.93750000 324.84375000 Translating: -2.30645990
Bone 10: Name: r_uparm, Parent: 9, Children: 1,Rotations: 322.03125000 298.12500000 323.43750000 Translating: -2.73342323
Bone 11: Name: r_foarm, Parent: 10, Children: 1,Rotations: 288.28125000 0.00000000 0.00000000 Translating: -4.60069847
Bone 12: Name: r_hand, Parent: 11, Children: 0,Rotations: 0.00000000 0.00000000 0.00000000 Translating: -2.27860451
Bone 13: Name: l_hip, Parent: -1, Children: 1,Rotations: 0.00000000 251.71875000 180.00000000 Translating: -1.98165441
Bone 14: Name: l_femur, Parent: 13, Children: 1,Rotations: 289.68750000 63.28125000 7.03125000 Translating: -5.28867340
Bone 15: Name: l_tibia, Parent: 14, Children: 1,Rotations: 29.53125000 0.00000000 0.00000000 Translating: -7.72580004
Bone 16: Name: l_foot, Parent: 15, Children: 0,Rotations: 284.06250000 191.25000000 171.56250000 Translating: -6.90587616
Bone 17: Name: r_hip, Parent: -1, Children: 1,Rotations: 0.00000000 108.28125000 180.00000000 Translating: -1.98165441
Bone 18: Name: r_femur, Parent: 17, Children: 1,Rotations: 309.37500000 108.28125000 180.00000000 Translating: -5.28867340
Bone 19: Name: r_tibia, Parent: 18, Children: 1,Rotations: 47.81250000 180.00000000 180.00000000 Translating: -7.72580004
Bone 20: Name: r_foot, Parent: 19, Children: 0,Rotations: 272.81250000 175.78125000 181.40625000 Translating: -6.90587616
You’ll notice this time I reversed the translations along the Z. This gets this result:
(http://upload.serverseed.com/pictars4/BentSmallCloud2.png)
But notice that even though the bones land in the right spots they are on the wrong side of Cloud. This only shows because of the coloring on his arm and shoulder. On Yuffie, of course, her whole arm is backwards.
If I DON’T translate along the Z by the NEGATIVE bone length, this is what happens:
(http://upload.serverseed.com/pictars4/BentSmallCloud.png)
Each part is facing the correct direction, and is on the correct side of his body, but the bones went in the wrong direction. After placing his body, instead of going up to place his head, it went down and put his head under his ass instead, in the exact opposite direction it was supposed to go.
That is why I reversed the bone lengths in the first place.
Then, to fix the problem with his part landing on the wrong sides, I reversed the Y and Z vertex coordinates on each model upon loading.
The first and last shots are without any modifications to the bone lengths and all of them are without modifications to the vertices upon loading (or after).
I suspect I may be walking in the wrong order, but that doesn't explain why reversing the things I reversed fixes the problem (actually it isn’t fixed with my method; the models align properly, but are exactly mirrored of what they should be).
So I posted my walking order and all the information there is about each bone.
The information about Battle Cloud is his first frame.
The other Cloud’s information is just some frame from aaga.a.
L. Spiro
-
I've made some progress it's still not right but it's better, I think something is messed up somewhere but
(http://bin.mypage.sk/FILES/CLOUD_02.jpg)
is a lot better I would say.
L. Spiro doing good there!
Mirex
I seem to be having trouble getting the Lines to be drawn OVER model, do I have to make the model semi transparent for them to be properly visable or something?
Cyb
-
Hehe!
"Not in the face! Not in the face!"
-
Hehe!
"Not in the face! Not in the face!"
You know. you're right that is what it looks like!
Or how about "Don't hit me Tifa!"
Cyb
-
I seem to be having trouble getting the Lines to be drawn OVER model, do I have to make the model semi transparent for them to be properly visable or something?
if you want to draw them over the model you have to disable depth checking.
1) enable depth check so model will be drawn properly:
glEnable( GL_DEPTH_TEST );
2) draw your model
3) disable depthcheck by glDisable( GL_DEPTH_TEST );
4) draw bone lines
and voila there it is, bones allways on top of the model :)
reason is that if depth test is on, there is test if drawn item should be drawn or it is 'hidden' behind some other graphic object. If depth test is off no test is performed, and item is drawn anyhow.
-
Any possible solutions to my problem at all?
What could possibly cause all the correct numbers to place his head under his ass instead of on his shoulders?
I’m definitely not walking in the wrong order.
The bones are definitely loaded correctly and so are the animations.
The models are loaded correctly as well, as shown in the pictures.
But the only error is that the bone goes down instead of up.
Anyone want to post their code of walking/drawing the bone tree with recursion?
L. Spiro
-
I think your documentation may be off, mirex.
To get this result:
(http://upload.serverseed.com/pictars4/BattleCloud.png)
I had to seek past 4 extra bytes at the start of the animation (go after “u1†in the document) and then skip four MORE bytes, AND start with Odd set to false instead of true (when I copied your code from above, it starts as true).
Weird.
But now you can see I am back to the same problem I had with the overworld models. Everything is on the wrong side.
HEEEEELLLP!!!
L. Spiro
-
if everything is on the wrong side try:
-flipping model coordinates ( negate Y coords or something )
-switching one rotation from positive to negative values
-
I did that; I switched the Y and Z so the models would flip over.
But that isn’t the PROPER way to do it.
My models are exact mirrors of the real game.
I’ve tried mangling with the rotations in every way but none lead to Rome.
L. Spiro
-
I did that; I switched the Y and Z so the models would flip over.
But that isn’t the PROPER way to do it.
My models are exact mirrors of the real game.
I’ve tried mangling with the rotations in every way but none lead to Rome.
L. Spiro
I am totaly ignorant of programming, especially of graphics programming but could you try to use 360-X for X 360-Y for Y and 360-Z for Z and see what happens?
(or maybe 180-X,Y,Z respectively ...you can understand my thinking)
just a silly idea...
(maybe the PSX has a 'perverse' way of producing 3D graphics...)
-
These pictures are too big to post into the forum box but here are a few pictures of my results.
I have been having fun.
http://upload.serverseed.com/pictars4/HereTheyCome.png
http://upload.serverseed.com/pictars4/Ruby%20Weapon%203.png
http://upload.serverseed.com/pictars4/Bahamut%20ZERO.png
But actually you can’t tell that each part is mirrored.
As for rotating 180-X, etc., my problem is that I am sure they didn’t do it that way. What I have now does work fine, but it too is wrong in the end.
And 3-D manipulation of objects isn’t really complicated so I don’t understand why I messed up somewhere, but it is not big deal anymore.
Maybe my game will just use mirrored graphics and see if anyone notices.
L. Spiro
-
probably they didn't do it this way...
but reflecting some more on it I am more convinced that 360-X,Y,Z gives you the mirror of the mirror image = the correct image
-
Here is Barret’s normal animation unpacked.
It is the first animation in his **da file(s).
Frame 0: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 494.0f -1.0f
Frame 0: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 0: Bone 1: < 12.39258f, 0.7910156f, 4.482422f >
Frame 0: Bone 2: < 353.584f, 3.427734f, 18.89648f >
Frame 0: Bone 3: < 354.5508f, 346.1133f, 34.98047f >
Frame 0: Bone 4: < 329.3262f, 286.7871f, 239.8535f >
Frame 0: Bone 5: < 42.27539f, 346.377f, 270.9668f >
Frame 0: Bone 6: < 292.3242f, 73.47656f, 295.5762f >
Frame 0: Bone 7: < 1.757813f, 15.64453f, 6.416016f >
Frame 0: Bone 8: < 352.5293f, 12.65625f, 333.5449f >
Frame 0: Bone 9: < 338.5547f, 70.3125f, 121.9043f >
Frame 0: Bone 10: < 44.38477f, 322.2949f, 26.45508f >
Frame 0: Bone 11: < 296.543f, 349.1016f, 0.0f >
Frame 0: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 0: Bone 13: < 359.209f, 48.16406f, 61.52344f >
Frame 0: Bone 14: < 64.16016f, 8.789063e-002f, 0.1757813f >
Frame 0: Bone 15: < 306.6504f, 26.89453f, 346.2012f >
Frame 0: Bone 16: < 299.2676f, 0.0f, 0.0f >
Frame 0: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 0: Bone 18: < 341.4551f, 317.4609f, 298.4766f >
Frame 0: Bone 19: < 62.22656f, 0.8789063f, 0.9667969f >
Frame 0: Bone 20: < 318.0762f, 346.7285f, 6.416016f >
Frame 0: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 1: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 490.0f -3.0f
Frame 1: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 1: Bone 1: < 12.65625f, 0.7910156f, 4.482422f >
Frame 1: Bone 2: < 353.1445f, 3.427734f, 18.89648f >
Frame 1: Bone 3: < 354.8145f, 346.1133f, 34.89258f >
Frame 1: Bone 4: < 329.502f, 287.3145f, 239.6777f >
Frame 1: Bone 5: < 42.71484f, 346.2891f, 270.8789f >
Frame 1: Bone 6: < 292.5f, 72.68555f, 296.2793f >
Frame 1: Bone 7: < 1.142578f, 15.82031f, 6.416016f >
Frame 1: Bone 8: < 352.793f, 12.65625f, 333.6328f >
Frame 1: Bone 9: < 337.9395f, 69.25781f, 122.3438f >
Frame 1: Bone 10: < 44.47266f, 320.7129f, 25.3125f >
Frame 1: Bone 11: < 296.6309f, 349.1016f, 0.0f >
Frame 1: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 1: Bone 13: < 359.4727f, 47.37305f, 61.17188f >
Frame 1: Bone 14: < 65.47852f, 8.789063e-002f, 0.1757813f >
Frame 1: Bone 15: < 306.2109f, 28.30078f, 344.9707f >
Frame 1: Bone 16: < 299.2676f, 0.0f, 0.0f >
Frame 1: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 1: Bone 18: < 341.3672f, 318.3398f, 298.3887f >
Frame 1: Bone 19: < 64.16016f, 0.8789063f, 1.054688f >
Frame 1: Bone 20: < 316.9336f, 346.1133f, 7.03125f >
Frame 1: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 2: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 484.0f -7.0f
Frame 2: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 2: Bone 1: < 13.00781f, 0.8789063f, 4.482422f >
Frame 2: Bone 2: < 352.5293f, 3.251953f, 18.89648f >
Frame 2: Bone 3: < 355.166f, 346.1133f, 34.80469f >
Frame 2: Bone 4: < 329.8535f, 287.9297f, 239.3262f >
Frame 2: Bone 5: < 43.33008f, 346.2891f, 270.791f >
Frame 2: Bone 6: < 292.6758f, 71.54297f, 297.4219f >
Frame 2: Bone 7: < 0.2636719f, 15.99609f, 6.328125f >
Frame 2: Bone 8: < 353.1445f, 12.65625f, 333.7207f >
Frame 2: Bone 9: < 337.0605f, 67.76367f, 122.959f >
Frame 2: Bone 10: < 44.56055f, 318.4277f, 23.64258f >
Frame 2: Bone 11: < 296.8066f, 349.1016f, 8.789063e-002f >
Frame 2: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 2: Bone 13: < 359.7363f, 46.23047f, 60.73242f >
Frame 2: Bone 14: < 67.32422f, 0.1757813f, 0.1757813f >
Frame 2: Bone 15: < 305.5957f, 30.41016f, 343.2129f >
Frame 2: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 2: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 2: Bone 18: < 341.1914f, 319.4824f, 298.125f >
Frame 2: Bone 19: < 66.88477f, 1.054688f, 1.142578f >
Frame 2: Bone 20: < 315.3516f, 345.1465f, 7.910156f >
Frame 2: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 3: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 478.0f -12.0f
Frame 3: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 3: Bone 1: < 13.53516f, 0.8789063f, 4.482422f >
Frame 3: Bone 2: < 351.6504f, 3.164063f, 18.89648f >
Frame 3: Bone 3: < 355.6055f, 346.2012f, 34.7168f >
Frame 3: Bone 4: < 330.293f, 288.8086f, 238.9746f >
Frame 3: Bone 5: < 44.12109f, 346.2012f, 270.6152f >
Frame 3: Bone 6: < 292.9395f, 70.13672f, 298.7402f >
Frame 3: Bone 7: < 359.209f, 16.17188f, 6.240234f >
Frame 3: Bone 8: < 353.584f, 12.65625f, 333.8086f >
Frame 3: Bone 9: < 336.0938f, 66.00586f, 123.6621f >
Frame 3: Bone 10: < 44.56055f, 315.791f, 21.79688f >
Frame 3: Bone 11: < 296.8945f, 349.0137f, 8.789063e-002f >
Frame 3: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 3: Bone 13: < 8.789063e-002f, 45.0f, 60.29297f >
Frame 3: Bone 14: < 69.3457f, 0.1757813f, 0.1757813f >
Frame 3: Bone 15: < 304.9805f, 32.7832f, 341.1914f >
Frame 3: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 3: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 3: Bone 18: < 341.0156f, 320.8887f, 297.7734f >
Frame 3: Bone 19: < 70.04883f, 1.230469f, 1.318359f >
Frame 3: Bone 20: < 313.5059f, 344.0918f, 9.052734f >
Frame 3: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 4: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 472.0f -16.0f
Frame 4: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 4: Bone 1: < 14.0625f, 0.9667969f, 4.482422f >
Frame 4: Bone 2: < 350.7715f, 2.988281f, 18.98438f >
Frame 4: Bone 3: < 356.1328f, 346.2891f, 34.62891f >
Frame 4: Bone 4: < 330.8203f, 289.7754f, 238.5352f >
Frame 4: Bone 5: < 45.0f, 346.1133f, 270.4395f >
Frame 4: Bone 6: < 293.291f, 68.55469f, 300.1465f >
Frame 4: Bone 7: < 358.0664f, 16.43555f, 6.064453f >
Frame 4: Bone 8: < 354.1113f, 12.74414f, 333.8965f >
Frame 4: Bone 9: < 335.127f, 64.24805f, 124.3652f >
Frame 4: Bone 10: < 44.56055f, 313.2422f, 19.95117f >
Frame 4: Bone 11: < 297.0703f, 349.0137f, 0.1757813f >
Frame 4: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 4: Bone 13: < 0.4394531f, 43.68164f, 59.85352f >
Frame 4: Bone 14: < 71.45508f, 0.1757813f, 0.1757813f >
Frame 4: Bone 15: < 304.4531f, 35.33203f, 338.9941f >
Frame 4: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 4: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 4: Bone 18: < 340.8398f, 322.207f, 297.5098f >
Frame 4: Bone 19: < 73.21289f, 1.494141f, 1.494141f >
Frame 4: Bone 20: < 311.748f, 342.8613f, 10.37109f >
Frame 4: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 5: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 466.0f -20.0f
Frame 5: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 5: Bone 1: < 14.50195f, 0.9667969f, 4.482422f >
Frame 5: Bone 2: < 349.9805f, 2.8125f, 18.98438f >
Frame 5: Bone 3: < 356.6602f, 346.2891f, 34.45313f >
Frame 5: Bone 4: < 331.3477f, 290.8301f, 238.0957f >
Frame 5: Bone 5: < 45.9668f, 346.0254f, 270.1758f >
Frame 5: Bone 6: < 293.6426f, 66.88477f, 301.6406f >
Frame 5: Bone 7: < 356.748f, 16.69922f, 5.888672f >
Frame 5: Bone 8: < 354.6387f, 12.74414f, 333.9844f >
Frame 5: Bone 9: < 334.248f, 62.66602f, 125.0684f >
Frame 5: Bone 10: < 44.47266f, 310.957f, 18.45703f >
Frame 5: Bone 11: < 297.2461f, 349.0137f, 0.1757813f >
Frame 5: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 5: Bone 13: < 0.6152344f, 42.53906f, 59.58984f >
Frame 5: Bone 14: < 73.30078f, 0.1757813f, 0.1757813f >
Frame 5: Bone 15: < 304.0137f, 37.5293f, 336.9727f >
Frame 5: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 5: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 5: Bone 18: < 340.6641f, 323.3496f, 297.1582f >
Frame 5: Bone 19: < 76.02539f, 1.757813f, 1.845703f >
Frame 5: Bone 20: < 310.166f, 341.7188f, 11.51367f >
Frame 5: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 6: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 462.0f -23.0f
Frame 6: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 6: Bone 1: < 15.0293f, 1.054688f, 4.482422f >
Frame 6: Bone 2: < 349.1016f, 2.636719f, 18.98438f >
Frame 6: Bone 3: < 357.0996f, 346.377f, 34.36523f >
Frame 6: Bone 4: < 331.9629f, 291.7969f, 237.6563f >
Frame 6: Bone 5: < 46.8457f, 345.8496f, 270.0f >
Frame 6: Bone 6: < 294.082f, 65.39063f, 303.1348f >
Frame 6: Bone 7: < 355.5176f, 16.96289f, 5.712891f >
Frame 6: Bone 8: < 355.0781f, 12.74414f, 334.1602f >
Frame 6: Bone 9: < 333.7207f, 61.52344f, 125.5078f >
Frame 6: Bone 10: < 44.38477f, 309.375f, 17.31445f >
Frame 6: Bone 11: < 297.334f, 180.0f, 0.1757813f >
Frame 6: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 6: Bone 13: < 0.7910156f, 41.74805f, 59.32617f >
Frame 6: Bone 14: < 74.53125f, 0.1757813f, 0.2636719f >
Frame 6: Bone 15: < 303.6621f, 39.19922f, 335.4785f >
Frame 6: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 6: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 6: Bone 18: < 340.4883f, 324.2285f, 296.8945f >
Frame 6: Bone 19: < 77.95898f, 2.021484f, 2.109375f >
Frame 6: Bone 20: < 309.1113f, 340.9277f, 12.48047f >
Frame 6: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 7: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 461.0f -24.0f
Frame 7: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 7: Bone 1: < 15.38086f, 1.054688f, 4.482422f >
Frame 7: Bone 2: < 348.4863f, 2.548828f, 18.98438f >
Frame 7: Bone 3: < 357.4512f, 346.377f, 34.27734f >
Frame 7: Bone 4: < 332.4902f, 292.7637f, 237.3047f >
Frame 7: Bone 5: < 47.72461f, 345.7617f, 269.7363f >
Frame 7: Bone 6: < 294.4336f, 63.89648f, 304.4531f >
Frame 7: Bone 7: < 354.2871f, 17.13867f, 5.537109f >
Frame 7: Bone 8: < 355.5176f, 12.83203f, 334.248f >
Frame 7: Bone 9: < 333.457f, 61.08398f, 125.6836f >
Frame 7: Bone 10: < 44.29688f, 308.7598f, 16.875f >
Frame 7: Bone 11: < 297.334f, 348.9258f, 0.1757813f >
Frame 7: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 7: Bone 13: < 0.8789063f, 41.48438f, 59.23828f >
Frame 7: Bone 14: < 75.05859f, 0.2636719f, 0.2636719f >
Frame 7: Bone 15: < 303.5742f, 39.81445f, 334.9512f >
Frame 7: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 7: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 7: Bone 18: < 340.4883f, 324.4922f, 296.8066f >
Frame 7: Bone 19: < 78.66211f, 2.197266f, 2.285156f >
Frame 7: Bone 20: < 308.6719f, 340.5762f, 12.83203f >
Frame 7: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 8: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 461.0f -23.0f
Frame 8: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 8: Bone 1: < 15.64453f, 1.054688f, 4.482422f >
Frame 8: Bone 2: < 348.0469f, 2.460938f, 19.07227f >
Frame 8: Bone 3: < 357.7148f, 346.377f, 34.18945f >
Frame 8: Bone 4: < 332.9297f, 293.5547f, 236.9531f >
Frame 8: Bone 5: < 48.51563f, 345.6738f, 269.5605f >
Frame 8: Bone 6: < 294.7852f, 62.66602f, 305.5078f >
Frame 8: Bone 7: < 353.2324f, 17.40234f, 5.361328f >
Frame 8: Bone 8: < 355.7813f, 12.83203f, 334.248f >
Frame 8: Bone 9: < 333.5449f, 61.34766f, 125.5957f >
Frame 8: Bone 10: < 44.38477f, 309.0234f, 17.13867f >
Frame 8: Bone 11: < 297.334f, 348.9258f, 0.1757813f >
Frame 8: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 8: Bone 13: < 0.8789063f, 41.57227f, 59.23828f >
Frame 8: Bone 14: < 74.79492f, 0.1757813f, 0.2636719f >
Frame 8: Bone 15: < 303.6621f, 39.55078f, 335.2148f >
Frame 8: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 8: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 8: Bone 18: < 340.4883f, 324.4043f, 296.8066f >
Frame 8: Bone 19: < 78.31055f, 2.109375f, 2.197266f >
Frame 8: Bone 20: < 308.8477f, 340.752f, 12.65625f >
Frame 8: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 9: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 463.0f -22.0f
Frame 9: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 9: Bone 1: < 15.73242f, 1.054688f, 4.570313f >
Frame 9: Bone 2: < 347.8711f, 2.460938f, 19.07227f >
Frame 9: Bone 3: < 357.8027f, 346.377f, 34.18945f >
Frame 9: Bone 4: < 333.2813f, 294.1699f, 236.6895f >
Frame 9: Bone 5: < 49.13086f, 345.498f, 269.3848f >
Frame 9: Bone 6: < 295.0488f, 61.69922f, 306.3867f >
Frame 9: Bone 7: < 352.3535f, 17.57813f, 5.273438f >
Frame 9: Bone 8: < 355.8691f, 12.83203f, 334.3359f >
Frame 9: Bone 9: < 333.8086f, 61.875f, 125.332f >
Frame 9: Bone 10: < 44.38477f, 309.8145f, 17.66602f >
Frame 9: Bone 11: < 297.334f, 348.9258f, 0.1757813f >
Frame 9: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 9: Bone 13: < 0.7910156f, 42.01172f, 59.41406f >
Frame 9: Bone 14: < 74.17969f, 0.1757813f, 0.1757813f >
Frame 9: Bone 15: < 303.75f, 38.75977f, 335.918f >
Frame 9: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 9: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 9: Bone 18: < 340.5762f, 323.9648f, 296.9824f >
Frame 9: Bone 19: < 77.43164f, 1.933594f, 2.021484f >
Frame 9: Bone 20: < 309.375f, 341.1035f, 12.2168f >
Frame 9: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 10: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 466.0f -20.0f
Frame 10: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 10: Bone 1: < 15.64453f, 1.054688f, 4.482422f >
Frame 10: Bone 2: < 348.0469f, 2.460938f, 19.07227f >
Frame 10: Bone 3: < 357.7148f, 346.377f, 34.18945f >
Frame 10: Bone 4: < 333.5449f, 294.6094f, 236.5137f >
Frame 10: Bone 5: < 49.57031f, 345.498f, 269.209f >
Frame 10: Bone 6: < 295.3125f, 61.08398f, 307.002f >
Frame 10: Bone 7: < 351.8262f, 17.66602f, 5.185547f >
Frame 10: Bone 8: < 355.7813f, 12.83203f, 334.248f >
Frame 10: Bone 9: < 334.248f, 62.66602f, 125.0684f >
Frame 10: Bone 10: < 44.47266f, 310.957f, 18.45703f >
Frame 10: Bone 11: < 297.2461f, 349.0137f, 0.1757813f >
Frame 10: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 10: Bone 13: < 0.6152344f, 42.53906f, 59.58984f >
Frame 10: Bone 14: < 73.30078f, 0.1757813f, 0.1757813f >
Frame 10: Bone 15: < 304.0137f, 37.5293f, 336.9727f >
Frame 10: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 10: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 10: Bone 18: < 340.6641f, 323.3496f, 297.1582f >
Frame 10: Bone 19: < 76.02539f, 1.757813f, 1.845703f >
Frame 10: Bone 20: < 310.166f, 341.7188f, 11.51367f >
Frame 10: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 11: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 470.0f -17.0f
Frame 11: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 11: Bone 1: < 15.38086f, 1.054688f, 4.482422f >
Frame 11: Bone 2: < 348.4863f, 2.548828f, 18.98438f >
Frame 11: Bone 3: < 357.4512f, 346.377f, 34.27734f >
Frame 11: Bone 4: < 333.6328f, 294.7852f, 236.5137f >
Frame 11: Bone 5: < 49.74609f, 345.4102f, 269.209f >
Frame 11: Bone 6: < 295.3125f, 60.82031f, 307.1777f >
Frame 11: Bone 7: < 351.6504f, 17.75391f, 5.097656f >
Frame 11: Bone 8: < 355.5176f, 12.83203f, 334.248f >
Frame 11: Bone 9: < 334.7754f, 63.63281f, 124.6289f >
Frame 11: Bone 10: < 44.47266f, 312.4512f, 19.42383f >
Frame 11: Bone 11: < 297.1582f, 349.0137f, 0.1757813f >
Frame 11: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 11: Bone 13: < 0.5273438f, 43.24219f, 59.76563f >
Frame 11: Bone 14: < 72.07031f, 0.1757813f, 0.1757813f >
Frame 11: Bone 15: < 304.2773f, 36.12305f, 338.291f >
Frame 11: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 11: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 11: Bone 18: < 340.752f, 322.6465f, 297.334f >
Frame 11: Bone 19: < 74.17969f, 1.582031f, 1.582031f >
Frame 11: Bone 20: < 311.2207f, 342.5098f, 10.81055f >
Frame 11: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 12: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 474.0f -15.0f
Frame 12: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 12: Bone 1: < 15.0293f, 1.054688f, 4.482422f >
Frame 12: Bone 2: < 349.1016f, 2.636719f, 18.98438f >
Frame 12: Bone 3: < 357.0996f, 346.377f, 34.36523f >
Frame 12: Bone 4: < 333.457f, 294.4336f, 236.6016f >
Frame 12: Bone 5: < 49.39453f, 345.498f, 269.2969f >
Frame 12: Bone 6: < 295.2246f, 61.34766f, 306.7383f >
Frame 12: Bone 7: < 352.0898f, 17.66602f, 5.185547f >
Frame 12: Bone 8: < 355.0781f, 12.74414f, 334.1602f >
Frame 12: Bone 9: < 335.3906f, 64.77539f, 124.1895f >
Frame 12: Bone 10: < 44.56055f, 314.1211f, 20.56641f >
Frame 12: Bone 11: < 297.0703f, 349.0137f, 8.789063e-002f >
Frame 12: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 12: Bone 13: < 0.2636719f, 44.12109f, 60.0293f >
Frame 12: Bone 14: < 70.75195f, 0.1757813f, 0.1757813f >
Frame 12: Bone 15: < 304.6289f, 34.54102f, 339.6973f >
Frame 12: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 12: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 12: Bone 18: < 340.8398f, 321.7676f, 297.5977f >
Frame 12: Bone 19: < 72.24609f, 1.40625f, 1.40625f >
Frame 12: Bone 20: < 312.2754f, 343.3008f, 9.931641f >
Frame 12: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 13: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 478.0f -12.0f
Frame 13: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 13: Bone 1: < 14.50195f, 0.9667969f, 4.482422f >
Frame 13: Bone 2: < 349.9805f, 2.8125f, 18.98438f >
Frame 13: Bone 3: < 356.6602f, 346.2891f, 34.45313f >
Frame 13: Bone 4: < 332.9297f, 293.5547f, 236.9531f >
Frame 13: Bone 5: < 48.51563f, 345.6738f, 269.5605f >
Frame 13: Bone 6: < 294.7852f, 62.66602f, 305.5078f >
Frame 13: Bone 7: < 353.2324f, 17.40234f, 5.361328f >
Frame 13: Bone 8: < 354.6387f, 12.74414f, 333.9844f >
Frame 13: Bone 9: < 336.0938f, 66.00586f, 123.6621f >
Frame 13: Bone 10: < 44.56055f, 315.791f, 21.79688f >
Frame 13: Bone 11: < 296.8945f, 349.0137f, 8.789063e-002f >
Frame 13: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 13: Bone 13: < 8.789063e-002f, 45.0f, 60.29297f >
Frame 13: Bone 14: < 69.3457f, 0.1757813f, 0.1757813f >
Frame 13: Bone 15: < 304.9805f, 32.7832f, 341.1914f >
Frame 13: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 13: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 13: Bone 18: < 341.0156f, 320.8887f, 297.7734f >
Frame 13: Bone 19: < 70.04883f, 1.230469f, 1.318359f >
Frame 13: Bone 20: < 313.5059f, 344.0918f, 9.052734f >
Frame 13: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 14: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 482.0f -9.0f
Frame 14: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 14: Bone 1: < 14.0625f, 0.9667969f, 4.482422f >
Frame 14: Bone 2: < 350.7715f, 2.988281f, 18.98438f >
Frame 14: Bone 3: < 356.1328f, 346.2891f, 34.62891f >
Frame 14: Bone 4: < 332.2266f, 292.2363f, 237.4805f >
Frame 14: Bone 5: < 47.37305f, 345.8496f, 269.8242f >
Frame 14: Bone 6: < 294.2578f, 64.59961f, 303.75f >
Frame 14: Bone 7: < 354.9023f, 17.05078f, 5.625f >
Frame 14: Bone 8: < 354.1113f, 12.74414f, 333.8965f >
Frame 14: Bone 9: < 336.709f, 67.14844f, 123.2227f >
Frame 14: Bone 10: < 44.56055f, 317.5488f, 23.02734f >
Frame 14: Bone 11: < 296.8066f, 349.1016f, 8.789063e-002f >
Frame 14: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 14: Bone 13: < 359.8242f, 45.79102f, 60.64453f >
Frame 14: Bone 14: < 67.93945f, 0.1757813f, 0.1757813f >
Frame 14: Bone 15: < 305.4199f, 31.20117f, 342.5977f >
Frame 14: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 14: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 14: Bone 18: < 341.1035f, 319.9219f, 298.0371f >
Frame 14: Bone 19: < 67.93945f, 1.054688f, 1.142578f >
Frame 14: Bone 20: < 314.7363f, 344.7949f, 8.261719f >
Frame 14: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 15: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 486.0f -6.0f
Frame 15: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 15: Bone 1: < 13.53516f, 0.8789063f, 4.482422f >
Frame 15: Bone 2: < 351.6504f, 3.164063f, 18.89648f >
Frame 15: Bone 3: < 355.6055f, 346.2012f, 34.7168f >
Frame 15: Bone 4: < 331.3477f, 290.8301f, 238.0957f >
Frame 15: Bone 5: < 45.9668f, 346.0254f, 270.1758f >
Frame 15: Bone 6: < 293.6426f, 66.97266f, 301.6406f >
Frame 15: Bone 7: < 356.748f, 16.69922f, 5.888672f >
Frame 15: Bone 8: < 353.584f, 12.65625f, 333.8086f >
Frame 15: Bone 9: < 337.4121f, 68.29102f, 122.7832f >
Frame 15: Bone 10: < 44.56055f, 319.2188f, 24.25781f >
Frame 15: Bone 11: < 296.7188f, 349.1016f, 8.789063e-002f >
Frame 15: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 15: Bone 13: < 359.6484f, 46.66992f, 60.9082f >
Frame 15: Bone 14: < 66.62109f, 0.1757813f, 0.1757813f >
Frame 15: Bone 15: < 305.8594f, 29.61914f, 343.916f >
Frame 15: Bone 16: < 299.3555f, 0.0f, 0.0f >
Frame 15: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 15: Bone 18: < 341.2793f, 319.043f, 298.2129f >
Frame 15: Bone 19: < 65.91797f, 0.9667969f, 1.054688f >
Frame 15: Bone 20: < 315.8789f, 345.498f, 7.558594f >
Frame 15: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 16: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 490.0f -3.0f
Frame 16: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 16: Bone 1: < 13.00781f, 0.8789063f, 4.482422f >
Frame 16: Bone 2: < 352.5293f, 3.251953f, 18.89648f >
Frame 16: Bone 3: < 355.166f, 346.1133f, 34.80469f >
Frame 16: Bone 4: < 330.5566f, 289.3359f, 238.7109f >
Frame 16: Bone 5: < 44.56055f, 346.1133f, 270.5273f >
Frame 16: Bone 6: < 293.1152f, 69.3457f, 299.4434f >
Frame 16: Bone 7: < 358.6816f, 16.25977f, 6.152344f >
Frame 16: Bone 8: < 353.1445f, 12.65625f, 333.7207f >
Frame 16: Bone 9: < 337.9395f, 69.25781f, 122.3438f >
Frame 16: Bone 10: < 44.47266f, 320.7129f, 25.3125f >
Frame 16: Bone 11: < 296.6309f, 349.1016f, 0.0f >
Frame 16: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 16: Bone 13: < 359.4727f, 47.37305f, 61.17188f >
Frame 16: Bone 14: < 65.47852f, 8.789063e-002f, 0.1757813f >
Frame 16: Bone 15: < 306.2109f, 28.30078f, 344.9707f >
Frame 16: Bone 16: < 299.2676f, 0.0f, 0.0f >
Frame 16: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 16: Bone 18: < 341.3672f, 318.3398f, 298.3887f >
Frame 16: Bone 19: < 64.16016f, 0.8789063f, 1.054688f >
Frame 16: Bone 20: < 316.9336f, 346.1133f, 7.03125f >
Frame 16: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 17: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 493.0f -1.0f
Frame 17: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 17: Bone 1: < 12.65625f, 0.7910156f, 4.482422f >
Frame 17: Bone 2: < 353.1445f, 3.427734f, 18.89648f >
Frame 17: Bone 3: < 354.8145f, 346.1133f, 34.89258f >
Frame 17: Bone 4: < 329.8535f, 287.9297f, 239.3262f >
Frame 17: Bone 5: < 43.33008f, 346.2891f, 270.791f >
Frame 17: Bone 6: < 292.6758f, 71.54297f, 297.4219f >
Frame 17: Bone 7: < 0.2636719f, 15.99609f, 6.328125f >
Frame 17: Bone 8: < 352.793f, 12.65625f, 333.6328f >
Frame 17: Bone 9: < 338.3789f, 70.04883f, 122.0801f >
Frame 17: Bone 10: < 44.38477f, 321.8555f, 26.10352f >
Frame 17: Bone 11: < 296.543f, 349.1016f, 0.0f >
Frame 17: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 17: Bone 13: < 359.2969f, 47.90039f, 61.43555f >
Frame 17: Bone 14: < 64.51172f, 8.789063e-002f, 0.1757813f >
Frame 17: Bone 15: < 306.5625f, 27.24609f, 345.8496f >
Frame 17: Bone 16: < 299.2676f, 0.0f, 0.0f >
Frame 17: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 17: Bone 18: < 341.4551f, 317.7246f, 298.4766f >
Frame 17: Bone 19: < 62.75391f, 0.8789063f, 0.9667969f >
Frame 17: Bone 20: < 317.7246f, 346.5527f, 6.591797f >
Frame 17: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 18: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 494.0f 0.0f
Frame 18: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 18: Bone 1: < 12.39258f, 0.7910156f, 4.482422f >
Frame 18: Bone 2: < 353.584f, 3.427734f, 18.89648f >
Frame 18: Bone 3: < 354.5508f, 346.1133f, 34.98047f >
Frame 18: Bone 4: < 329.4141f, 287.0508f, 239.7656f >
Frame 18: Bone 5: < 42.45117f, 346.2891f, 270.9668f >
Frame 18: Bone 6: < 292.4121f, 73.21289f, 295.9277f >
Frame 18: Bone 7: < 1.494141f, 15.73242f, 6.416016f >
Frame 18: Bone 8: < 352.5293f, 12.65625f, 333.5449f >
Frame 18: Bone 9: < 338.7305f, 70.48828f, 121.8164f >
Frame 18: Bone 10: < 44.38477f, 322.6465f, 26.63086f >
Frame 18: Bone 11: < 296.543f, 349.1016f, 0.0f >
Frame 18: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 18: Bone 13: < 359.1211f, 48.25195f, 61.52344f >
Frame 18: Bone 14: < 63.89648f, 8.789063e-002f, 0.1757813f >
Frame 18: Bone 15: < 306.7383f, 26.63086f, 346.4648f >
Frame 18: Bone 16: < 299.2676f, 0.0f, 0.0f >
Frame 18: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 18: Bone 18: < 341.4551f, 317.2852f, 298.5645f >
Frame 18: Bone 19: < 61.78711f, 0.7910156f, 0.9667969f >
Frame 18: Bone 20: < 318.3398f, 346.8164f, 6.240234f >
Frame 18: Bone 21: < 299.5313f, 0.0f, 0.0f >
Frame 19: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 495.0f 0.0f
Frame 19: Bone 0: < 270.0f, 336.4453f, 0.0f >
Frame 19: Bone 1: < 12.30469f, 0.7910156f, 4.482422f >
Frame 19: Bone 2: < 353.7598f, 3.515625f, 18.89648f >
Frame 19: Bone 3: < 354.4629f, 346.1133f, 34.98047f >
Frame 19: Bone 4: < 329.2383f, 286.6113f, 239.9414f >
Frame 19: Bone 5: < 42.1875f, 346.377f, 271.0547f >
Frame 19: Bone 6: < 292.2363f, 73.82813f, 295.3125f >
Frame 19: Bone 7: < 1.933594f, 15.64453f, 6.503906f >
Frame 19: Bone 8: < 352.4414f, 12.65625f, 333.5449f >
Frame 19: Bone 9: < 338.8184f, 70.66406f, 121.8164f >
Frame 19: Bone 10: < 44.38477f, 322.9102f, 26.89453f >
Frame 19: Bone 11: < 296.543f, 349.1016f, 0.0f >
Frame 19: Bone 12: < 0.0f, 258.5742f, 270.0f >
Frame 19: Bone 13: < 359.1211f, 48.42773f, 61.61133f >
Frame 19: Bone 14: < 63.7207f, 8.789063e-002f, 0.1757813f >
Frame 19: Bone 15: < 306.8262f, 26.36719f, 346.6406f >
Frame 19: Bone 16: < 299.2676f, 0.0f, 0.0f >
Frame 19: Bone 17: < 0.0f, 54.4043f, 90.0f >
Frame 19: Bone 18: < 341.543f, 317.1973f, 298.5645f >
Frame 19: Bone 19: < 61.52344f, 0.7910156f, 0.9667969f >
Frame 19: Bone 20: < 318.5156f, 346.9043f, 6.152344f >
Frame 19: Bone 21: < 299.5313f, 0.0f, 0.0f >
Every single frame has a rotation and translation (not just the header!).
I loaded this animation without using the translations and it looks quite funny. His arms and legs rotate around a still body, as if he is trying to wiggle free of something.
Sorry for not posting Cloud’s. Barret’s was just easier.
But I can post Cloud’s animations tomorrow. I need sleep now.
L. Spiro
-
Barret/Tifa
(http://bin.mypage.sk/FILES/BARRETT_01.jpg)(http://bin.mypage.sk/FILES/TIFA_01.jpg)
Arise/Red XIII
(http://bin.mypage.sk/FILES/EARITH_01.jpg)(http://bin.mypage.sk/FILES/RED13_01.jpg)
Yufi
(http://bin.mypage.sk/FILES/YUFI_01.jpg)
-
Some of these images are just plain retarded... :o
Are coordinates really that hard to get right??
Well, I guess so since every frame has so much code... :weep:
-
Some of these images are just plain retarded... :o
Are coordinates really that hard to get right??
Well, I guess so since every frame has so much code... :weep:
Heh you showld at least be happy the ARE any images of thiss -.-.
-
Another way to keep the bones on the outside is to clear the depth buffer. That can help you draw the joints.
-
That Tifa looks familiar.
Cyberman, your Barret looks fine.
I can’t tell how the others are wrong.
Mine were wrong because I was working at one bone deeper than I was supposed to be.
But if that was your case also, your shoulders wouldn’t align at the right points, which they do.
That means the numbers you are crunching are probably correct (especially if you compare to mirex’s and mine) but you may be…
I don’t know what could cause those results.
The bones, rotations, etc., are accurate enough that your shoulders landing the right spots (a difficult task in itself) but inaccurate enough that only a few bones are actually going the wrong ways.
I notice particularly that your shoulders align, Aeris’s hair goes the right way, and her toes align to her feet.
Only one wrong rotation is needed to screw all of that up.
But in fact, the only wrong rotations are her left arm elbow and her right leg at the hip.
You should write a bone exporter that shows the information for each bone as I did. Then you can see the values you are getting and hopefully find a way to change them to what they should be.
As for the animation file formats, I went to bed last night and awakened just now.
Upon awakening I checked the file. I got my numbers from RAM.
There are 22 bones and each needs 12 bits per rotation, times 3 rotations and 20 frames.
That’s 1,980 bytes for just the first animation in his file.
According to the “Read_Data_Length†value in sbda, his first frame is entirely packed into 879 bytes.
His first frame is unpacked and requires 99 bytes to store in the file (more for the rotation/translation offsets), leaving the rest of the frames 780 bytes.
This means the animations are either stored as key frames or as offsets from the first frame.
If they are keyed, the engine unpacks each interpolated frame in one go and saves the interpolations for speed during the battle (rather than interpolate every frame of the battle).
Plus there are still the rotations and translations in each frame as well.
I hope that helps in solving the format and I am going to keep researching as I can. Any time I am online, playing a game, hacking, programming, or anything with a computer, it is because I am at work.
L. Spiro
-
qwerty
Well these are images from the playstation data files. I haven't tried animating them yet they may do weird twists ;)
sfx1999
Actually mirex suggestion worked dandy and allowed me to ad the origin angle (the white lines are for the origin) blue lines are the skeleton.
L. Spiro
I believe the animation on the PSX is very similiar to that of the PC just without the extra header in the file as each animation is in a seperate section in the PC version. I think the animation information varies there seems to be some flag information included. The decoding seems to work fine wither PC or PSX though.
-
I may not know what I'm talking about....
But remeber to count the root bone. I don't know what the heck that means, but it fixed a problem in the past.
/Boy I wish I know how to do math......
-
Well i was thinking that some frames could have some bones left out of animation data, probably those which bone rotation is same as in previous frame ... but its just a wild guess
Notice that by the way we read animations now we can read more then one frame for some models .... for example i can read 2 animations for chocobo (standing, and pecking into ground), and 5 or more for the black weapon (was it emerald?)
-
I was thinking some bones may be left out as well but there would need to be a key to determine which bones are missing. Or something to tell the loader.
But you can use the Barret table I posted and check only the frames that have changed, convert them back into hex, and check for those hex values after the end of his first frame (which is 99 bytes, starting on 1F [and shifted 4 bits]). The next frame has to come after 0x82 (from the start of the file).
Compression does not explain why some frames load after the first.
Neither does the idea of frames after the first being stored as offsets of the first.
You can look at the way the translations shift in my post and see if there may be a key-frame pattern.
Then find the frame that looks to be the key, translate the values back into hex, and see if you can find a series of hex in the file right after 0x82 that matches those values.
Also, the value listed in mirex’s document on animations labelled “Rec_B†is almost certainly the number of frames in the animation.
Another thing you can do is translate the values after 0x82 and see if they match any values in my Barret post.
Hopefully all of them will fit into one frame or another, and in sequencial order.
L. Spiro
-
L.Spiro: those barret's values are rip from memory, or are read from file ? Does model look okay when rotated by those values ?
Cyberman: Could you tell me offset where does the animation start in PSX files cloud.lzs and hicloud.lzs please ?
-
They are ripped from memory.
I exported with my own tools, then wrote a script to put the values into code for loading into my program.
Barret looks fine, and it animates perfectly.
It’s just Barret’s normal standing pose.
Unfortunately they are loaded into RAM dynamically and I haven't bothered to track the pointer that points to where they are loaded each time, so after a shut down of the game, I have to find them again.
But I’ve found a lot. Also some enemies (though I haven't exported those ones) and other characters.
I could probably find Cactuer’s animation. It would be pretty easy to study.
Also, Block_A and Rec_B always have the same values, as far as I have seen.
L. Spiro
-
well thats great, comparing values decoded in memory with file could solve how the animations are stored in the file
i thought that cactuar has only 2 frames (running and running) so there aint much to study
-
That’s the point with Cactuer.
A smaller and simpler file should be easier to manage while decoding.
I have revised the animation header format and I will post it later. Work ends in 30 minutes so I will have time to verify my changes and make the fomat description nice and neat at that time.
Plus after work I have to watch the latest Naruto episode, so in a little over an hour I will post.
L. Spiro
-
It’s easiest to see the changes when both are shown together. Here is the original but I don’t know if mirex keeps a more up-to-date one.
struct s_FF7AAanimHdr {
unsigned long rec_a; //0
unsigned long rec_b; //4
unsigned long block_len; //8
unsigned short block_a; //12
unsigned short real_data_len; //14
unsigned short translat[3]; //16
unsigned char u1; //22
} FF7AAanimHdr; //size = 23 bytes
The new one:
struct s_FF7AAanimHdr {
unsigned long rec_a; //0
unsigned long frames_1; //4
unsigned long block_len; //8
unsigned short frames_2; //12
unsigned short real_data_len; //14
unsigned char u1; //16
} FF7AAanimHdr; //size = 17 bytes
Both “rec_b†and “block_a†keep the same values in nearly every model I have seen, so I don’t know which is the CORRECT one, but for now they both depict the number of frames in the animation.
I moved u1 from the bottom and put it over the 3 shorts. Directly after the real data length, there is one byte of unknown information.
I removed the translations because they are actually part of each frame of animation (not just the header).
So, immediately after the “u1†byte, you would see 3 signed shorts, then 36 bits of a rotational offset, also per frame.
The shorts need explanation. It seems they are stored in reverse format, and AT LEAST the middle one (Y) is inverted.
To decode them, you must reverse their bytes.
Cloud’s file shows 00 00 FE 2E 00 00 for these 6 bytes.
After reversing, this is how it looks:
00 00 -> 0
2E FE -> -466
00 00 -> 0
I posted Barret’s data already so I will show it as well.
From sbda, we get:
00 00
FE 12
FF FF
We reverse each short, and get:
00 00 -> 0
12 FE -> -494
FF FF -> -1
These match the data I posted, however the Y coordinate in each seems to be inverted. They should be 466 and 494 by the time they hit final state in RAM, so it seems that not only do you reverse the Y short bytes, you then have to subtract it from 0 to get the final result (note that -1 is the correct final result and it seems only the Y needs to be inverted).
The next 36 bits are the first frame’s rotational offsets, decoded the same way as the rest of the rotations. Changing these values spins the entire model, and each frame has this.
The way this is all stored in RAM:
The first 12 bytes are the rotational offsets.
The next 12 bytes are the translational offsets.
Then each 12 bytes represents the X, Y, and Z of each bone for that frame.
The next frame follows immediately and starts again with the rotational offsets.
The size of each frame in RAM is (iBones * 12 + 24).
I hope all that helps.
L. Spiro
-
I may know what the u1 value is also.
It seems to indicate how many rotations to skip before starting to load the model (and after the 3 rotational offsets).
On most models I have noticed it’s 0, but Red XIII’s doesn’t load correctly so I decided to trace his animation.
His animation actually starts 2 rotations (24 bits) later; that is why his first frame is screwed. And low-and-behold, u1 (in my post; not the old u1) is 2.
Here is Red XII’s first animation data (VERY LONG).
[code]
Frame 0: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 267.0f 118.0f
Frame 0: Bone 0: < 3.164063f, 0.0f, 0.0f >
Frame 0: Bone 1: < 3.164063f, 0.0f, 0.0f >
Frame 0: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 0: Bone 3: < 24.25781f, 358.9453f, 0.0f >
Frame 0: Bone 4: < 349.1016f, 1.054688f, 0.3515625f >
Frame 0: Bone 5: < 311.1328f, 279.1406f, 92.46094f >
Frame 0: Bone 6: < 358.2422f, 243.2813f, 206.3672f >
Frame 0: Bone 7: < 354.0234f, 27.07031f, 345.5859f >
Frame 0: Bone 8: < 16.17188f, 356.1328f, 1.054688f >
Frame 0: Bone 9: < 310.7813f, 82.61719f, 267.5391f >
Frame 0: Bone 10: < 0.3515625f, 117.0703f, 153.2813f >
Frame 0: Bone 11: < 354.7266f, 331.875f, 15.11719f >
Frame 0: Bone 12: < 12.65625f, 1.054688f, 358.9453f >
Frame 0: Bone 13: < 10.19531f, 1.054688f, 0.3515625f >
Frame 0: Bone 14: < 0.3515625f, 0.0f, 0.0f >
Frame 0: Bone 15: < 351.9141f, 349.8047f, 335.3906f >
Frame 0: Bone 16: < 72.77344f, 207.0703f, 190.8984f >
Frame 0: Bone 17: < 44.64844f, 21.44531f, 4.921875f >
Frame 0: Bone 18: < 285.4688f, 177.1875f, 183.1641f >
Frame 0: Bone 19: < 357.1875f, 351.2109f, 18.98438f >
Frame 0: Bone 20: < 329.4141f, 0.703125f, 358.9453f >
Frame 0: Bone 21: < 348.0469f, 8.4375f, 24.96094f >
Frame 0: Bone 22: < 86.83594f, 95.27344f, 108.2813f >
Frame 0: Bone 23: < 40.78125f, 339.6094f, 357.1875f >
Frame 0: Bone 24: < 279.4922f, 178.9453f, 181.4063f >
Frame 0: Bone 25: < 358.5938f, 0.3515625f, 348.3984f >
Frame 0: Bone 26: < 343.8281f, 359.6484f, 1.054688f >
Frame 0: Bone 27: < 29.88281f, 254.8828f, 176.4844f >
Frame 0: Bone 28: < 323.0859f, 345.9375f, 98.08594f >
Frame 0: Bone 29: < 76.64063f, 176.8359f, 176.4844f >
Frame 0: Bone 30: < 300.2344f, 180.0f, 180.0f >
Frame 0: Bone 31: < 342.4219f, 10.89844f, 15.82031f >
Frame 0: Bone 32: < 320.2734f, 0.0f, 0.0f >
Frame 0: Bone 33: < 13.35938f, 180.0f, 180.0f >
Frame 0: Bone 34: < 18.63281f, 14.0625f, 4.570313f >
Frame 0: Bone 35: < 14.0625f, 353.3203f, 358.5938f >
Frame 0: Bone 36: < 18.28125f, 358.2422f, 359.2969f >
Frame 0: Bone 37: < 354.0234f, 347.3438f, 1.40625f >
Frame 0: Bone 38: < 350.5078f, 359.6484f, 0.0f >
Frame 0: Bone 39: < 350.8594f, 355.4297f, 0.703125f >
Frame 0: Bone 40: < 29.88281f, 105.1172f, 28.47656f >
Frame 0: Bone 41: < 35.15625f, 356.4844f, 74.53125f >
Frame 0: Bone 42: < 71.36719f, 0.703125f, 0.703125f >
Frame 0: Bone 43: < 299.8828f, 0.0f, 0.0f >
Frame 0: Bone 44: < 312.1875f, 341.0156f, 344.8828f >
Frame 0: Bone 45: < 300.5859f, 0.0f, 0.0f >
Frame 1: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 266.0f 124.0f
Frame 1: Bone 0: < 3.515625f, 0.0f, 0.0f >
Frame 1: Bone 1: < 2.460938f, 0.0f, 0.0f >
Frame 1: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 1: Bone 3: < 24.96094f, 357.8906f, 0.0f >
Frame 1: Bone 4: < 348.75f, 1.757813f, 0.703125f >
Frame 1: Bone 5: < 311.4844f, 279.8438f, 93.16406f >
Frame 1: Bone 6: < 358.9453f, 243.6328f, 206.3672f >
Frame 1: Bone 7: < 347.3438f, 27.07031f, 345.5859f >
Frame 1: Bone 8: < 9.84375f, 354.375f, 0.703125f >
Frame 1: Bone 9: < 310.0781f, 84.02344f, 267.1875f >
Frame 1: Bone 10: < 0.3515625f, 117.0703f, 153.2813f >
Frame 1: Bone 11: < 348.3984f, 330.8203f, 15.46875f >
Frame 1: Bone 12: < 8.4375f, 359.6484f, 358.9453f >
Frame 1: Bone 13: < 9.84375f, 2.109375f, 0.703125f >
Frame 1: Bone 14: < 359.6484f, 0.0f, 0.0f >
Frame 1: Bone 15: < 352.2656f, 349.4531f, 335.3906f >
Frame 1: Bone 16: < 73.82813f, 207.0703f, 191.25f >
Frame 1: Bone 17: < 44.64844f, 21.44531f, 4.921875f >
Frame 1: Bone 18: < 285.4688f, 177.1875f, 183.1641f >
Frame 1: Bone 19: < 357.1875f, 350.5078f, 18.63281f >
Frame 1: Bone 20: < 330.8203f, 0.703125f, 358.9453f >
Frame 1: Bone 21: < 348.0469f, 8.4375f, 24.96094f >
Frame 1: Bone 22: < 87.1875f, 78.04688f, 91.05469f >
Frame 1: Bone 23: < 40.42969f, 339.6094f, 357.1875f >
Frame 1: Bone 24: < 278.7891f, 178.5938f, 181.4063f >
Frame 1: Bone 25: < 0.0f, 0.0f, 348.3984f >
Frame 1: Bone 26: < 343.4766f, 359.6484f, 1.054688f >
Frame 1: Bone 27: < 29.88281f, 254.8828f, 176.4844f >
Frame 1: Bone 28: < 323.4375f, 342.0703f, 100.5469f >
Frame 1: Bone 29: < 74.17969f, 177.1875f, 177.1875f >
Frame 1: Bone 30: < 299.8828f, 180.0f, 180.0f >
Frame 1: Bone 31: < 342.0703f, 10.89844f, 15.82031f >
Frame 1: Bone 32: < 319.9219f, 0.0f, 0.0f >
Frame 1: Bone 33: < 13.35938f, 180.0f, 180.0f >
Frame 1: Bone 34: < 17.22656f, 15.46875f, 4.570313f >
Frame 1: Bone 35: < 13.35938f, 351.2109f, 357.8906f >
Frame 1: Bone 36: < 18.63281f, 355.4297f, 358.5938f >
Frame 1: Bone 37: < 355.0781f, 347.3438f, 1.054688f >
Frame 1: Bone 38: < 352.2656f, 2.109375f, 359.6484f >
Frame 1: Bone 39: < 354.375f, 357.8906f, 0.3515625f >
Frame 1: Bone 40: < 29.88281f, 105.4688f, 28.82813f >
Frame 1: Bone 41: < 35.15625f, 355.7813f, 74.17969f >
Frame 1: Bone 42: < 74.17969f, 0.703125f, 0.703125f >
Frame 1: Bone 43: < 293.5547f, 0.0f, 0.0f >
Frame 1: Bone 44: < 314.2969f, 342.7734f, 342.7734f >
Frame 1: Bone 45: < 301.6406f, 0.0f, 0.0f >
Frame 2: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 265.0f 130.0f
Frame 2: Bone 0: < 3.867188f, 0.0f, 0.0f >
Frame 2: Bone 1: < 1.054688f, 0.0f, 0.0f >
Frame 2: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 2: Bone 3: < 26.36719f, 356.8359f, 0.0f >
Frame 2: Bone 4: < 348.0469f, 2.8125f, 1.054688f >
Frame 2: Bone 5: < 311.8359f, 280.1953f, 94.21875f >
Frame 2: Bone 6: < 359.6484f, 243.9844f, 206.3672f >
Frame 2: Bone 7: < 343.8281f, 26.71875f, 345.9375f >
Frame 2: Bone 8: < 3.164063f, 352.6172f, 1.054688f >
Frame 2: Bone 9: < 309.7266f, 85.42969f, 266.4844f >
Frame 2: Bone 10: < 1.054688f, 116.7188f, 153.2813f >
Frame 2: Bone 11: < 344.8828f, 330.4688f, 15.46875f >
Frame 2: Bone 12: < 3.515625f, 358.5938f, 358.9453f >
Frame 2: Bone 13: < 9.140625f, 3.164063f, 1.054688f >
Frame 2: Bone 14: < 358.5938f, 0.0f, 0.0f >
Frame 2: Bone 15: < 352.2656f, 349.4531f, 335.3906f >
Frame 2: Bone 16: < 74.88281f, 207.0703f, 191.6016f >
Frame 2: Bone 17: < 44.64844f, 21.44531f, 4.921875f >
Frame 2: Bone 18: < 285.1172f, 177.1875f, 183.1641f >
Frame 2: Bone 19: < 356.8359f, 350.1563f, 18.28125f >
Frame 2: Bone 20: < 332.5781f, 0.3515625f, 358.9453f >
Frame 2: Bone 21: < 348.3984f, 8.789063f, 24.96094f >
Frame 2: Bone 22: < 86.83594f, 58.71094f, 71.71875f >
Frame 2: Bone 23: < 40.07813f, 339.9609f, 357.1875f >
Frame 2: Bone 24: < 277.3828f, 178.5938f, 181.7578f >
Frame 2: Bone 25: < 1.40625f, 0.0f, 348.3984f >
Frame 2: Bone 26: < 342.7734f, 359.6484f, 1.054688f >
Frame 2: Bone 27: < 29.88281f, 254.5313f, 175.7813f >
Frame 2: Bone 28: < 324.1406f, 337.8516f, 103.0078f >
Frame 2: Bone 29: < 71.71875f, 177.5391f, 177.5391f >
Frame 2: Bone 30: < 298.4766f, 180.0f, 180.0f >
Frame 2: Bone 31: < 341.3672f, 10.54688f, 15.82031f >
Frame 2: Bone 32: < 319.5703f, 0.0f, 0.0f >
Frame 2: Bone 33: < 12.65625f, 180.0f, 180.0f >
Frame 2: Bone 34: < 16.875f, 15.46875f, 4.570313f >
Frame 2: Bone 35: < 11.60156f, 350.1563f, 357.8906f >
Frame 2: Bone 36: < 16.875f, 352.9688f, 357.8906f >
Frame 2: Bone 37: < 356.4844f, 348.75f, 0.703125f >
Frame 2: Bone 38: < 354.7266f, 4.570313f, 359.6484f >
Frame 2: Bone 39: < 358.2422f, 0.703125f, 0.0f >
Frame 2: Bone 40: < 29.88281f, 105.4688f, 29.17969f >
Frame 2: Bone 41: < 35.15625f, 355.4297f, 73.82813f >
Frame 2: Bone 42: < 76.28906f, 1.054688f, 1.054688f >
Frame 2: Bone 43: < 286.875f, 0.0f, 0.0f >
Frame 2: Bone 44: < 317.8125f, 344.5313f, 340.3125f >
Frame 2: Bone 45: < 302.6953f, 0.0f, 0.0f >
Frame 3: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 266.0f 136.0f
Frame 3: Bone 0: < 4.921875f, 0.0f, 0.0f >
Frame 3: Bone 1: < 359.2969f, 0.0f, 0.0f >
Frame 3: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 3: Bone 3: < 27.77344f, 355.7813f, 0.0f >
Frame 3: Bone 4: < 347.3438f, 3.515625f, 1.40625f >
Frame 3: Bone 5: < 311.8359f, 280.1953f, 95.27344f >
Frame 3: Bone 6: < 0.703125f, 244.3359f, 206.3672f >
Frame 3: Bone 7: < 343.8281f, 24.96094f, 346.2891f >
Frame 3: Bone 8: < 357.1875f, 350.8594f, 1.757813f >
Frame 3: Bone 9: < 309.375f, 87.1875f, 265.4297f >
Frame 3: Bone 10: < 1.40625f, 116.7188f, 153.2813f >
Frame 3: Bone 11: < 344.1797f, 331.1719f, 15.11719f >
Frame 3: Bone 12: < 359.6484f, 357.1875f, 359.2969f >
Frame 3: Bone 13: < 8.4375f, 4.21875f, 1.40625f >
Frame 3: Bone 14: < 357.1875f, 0.0f, 0.0f >
Frame 3: Bone 15: < 352.6172f, 349.4531f, 335.3906f >
Frame 3: Bone 16: < 75.9375f, 207.0703f, 191.6016f >
Frame 3: Bone 17: < 44.64844f, 21.44531f, 4.921875f >
Frame 3: Bone 18: < 284.7656f, 177.1875f, 183.1641f >
Frame 3: Bone 19: < 356.1328f, 349.4531f, 17.92969f >
Frame 3: Bone 20: < 333.9844f, 0.3515625f, 358.9453f >
Frame 3: Bone 21: < 348.75f, 8.789063f, 24.96094f >
Frame 3: Bone 22: < 86.48438f, 42.1875f, 54.84375f >
Frame 3: Bone 23: < 39.375f, 339.9609f, 357.1875f >
Frame 3: Bone 24: < 275.9766f, 177.8906f, 182.1094f >
Frame 3: Bone 25: < 2.460938f, 359.6484f, 348.3984f >
Frame 3: Bone 26: < 342.4219f, 359.6484f, 1.054688f >
Frame 3: Bone 27: < 29.53125f, 254.1797f, 174.7266f >
Frame 3: Bone 28: < 324.4922f, 333.6328f, 105.8203f >
Frame 3: Bone 29: < 69.96094f, 177.8906f, 177.8906f >
Frame 3: Bone 30: < 296.7188f, 180.0f, 180.0f >
Frame 3: Bone 31: < 341.0156f, 10.54688f, 16.17188f >
Frame 3: Bone 32: < 319.2188f, 0.0f, 0.0f >
Frame 3: Bone 33: < 11.95313f, 180.0f, 180.0f >
Frame 3: Bone 34: < 17.92969f, 14.0625f, 4.570313f >
Frame 3: Bone 35: < 8.789063f, 350.1563f, 358.5938f >
Frame 3: Bone 36: < 13.71094f, 351.2109f, 357.8906f >
Frame 3: Bone 37: < 358.2422f, 351.2109f, 0.3515625f >
Frame 3: Bone 38: < 357.5391f, 6.328125f, 359.6484f >
Frame 3: Bone 39: < 2.109375f, 3.515625f, 0.0f >
Frame 3: Bone 40: < 29.53125f, 106.1719f, 30.23438f >
Frame 3: Bone 41: < 35.50781f, 354.7266f, 73.125f >
Frame 3: Bone 42: < 77.69531f, 1.054688f, 1.054688f >
Frame 3: Bone 43: < 280.5469f, 0.0f, 0.0f >
Frame 3: Bone 44: < 321.6797f, 346.2891f, 338.2031f >
Frame 3: Bone 45: < 303.75f, 0.0f, 0.0f >
Frame 4: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 266.0f 140.0f
Frame 4: Bone 0: < 5.625f, 0.0f, 0.0f >
Frame 4: Bone 1: < 357.1875f, 0.0f, 0.0f >
Frame 4: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 4: Bone 3: < 29.53125f, 354.7266f, 0.0f >
Frame 4: Bone 4: < 346.6406f, 4.21875f, 1.757813f >
Frame 4: Bone 5: < 312.1875f, 280.1953f, 96.32813f >
Frame 4: Bone 6: < 1.40625f, 244.6875f, 206.3672f >
Frame 4: Bone 7: < 346.2891f, 22.85156f, 346.6406f >
Frame 4: Bone 8: < 353.6719f, 349.1016f, 2.109375f >
Frame 4: Bone 9: < 309.0234f, 88.94531f, 264.0234f >
Frame 4: Bone 10: < 2.109375f, 116.3672f, 153.2813f >
Frame 4: Bone 11: < 345.9375f, 332.5781f, 14.76563f >
Frame 4: Bone 12: < 357.1875f, 356.1328f, 359.6484f >
Frame 4: Bone 13: < 7.734375f, 4.921875f, 1.40625f >
Frame 4: Bone 14: < 356.1328f, 0.0f, 0.0f >
Frame 4: Bone 15: < 352.9688f, 349.1016f, 335.3906f >
Frame 4: Bone 16: < 76.64063f, 207.0703f, 191.6016f >
Frame 4: Bone 17: < 44.64844f, 21.44531f, 4.921875f >
Frame 4: Bone 18: < 283.7109f, 176.8359f, 183.5156f >
Frame 4: Bone 19: < 355.4297f, 348.75f, 17.57813f >
Frame 4: Bone 20: < 335.3906f, 0.3515625f, 358.9453f >
Frame 4: Bone 21: < 349.1016f, 9.140625f, 24.96094f >
Frame 4: Bone 22: < 86.13281f, 30.9375f, 43.59375f >
Frame 4: Bone 23: < 39.02344f, 339.9609f, 357.1875f >
Frame 4: Bone 24: < 274.2188f, 177.1875f, 182.8125f >
Frame 4: Bone 25: < 3.515625f, 359.6484f, 348.75f >
Frame 4: Bone 26: < 341.7188f, 359.6484f, 1.054688f >
Frame 4: Bone 27: < 29.53125f, 253.4766f, 173.6719f >
Frame 4: Bone 28: < 324.8438f, 329.4141f, 108.2813f >
Frame 4: Bone 29: < 68.90625f, 177.8906f, 177.8906f >
Frame 4: Bone 30: < 294.9609f, 180.0f, 180.0f >
Frame 4: Bone 31: < 341.0156f, 10.19531f, 16.52344f >
Frame 4: Bone 32: < 318.8672f, 0.0f, 0.0f >
Frame 4: Bone 33: < 10.89844f, 180.0f, 180.0f >
Frame 4: Bone 34: < 19.6875f, 11.60156f, 3.867188f >
Frame 4: Bone 35: < 4.921875f, 350.8594f, 359.2969f >
Frame 4: Bone 36: < 9.492188f, 350.5078f, 358.5938f >
Frame 4: Bone 37: < 0.3515625f, 354.375f, 0.0f >
Frame 4: Bone 38: < 0.703125f, 7.734375f, 0.0f >
Frame 4: Bone 39: < 5.976563f, 5.976563f, 0.703125f >
Frame 4: Bone 40: < 29.53125f, 106.5234f, 31.28906f >
Frame 4: Bone 41: < 35.85938f, 354.0234f, 72.77344f >
Frame 4: Bone 42: < 78.04688f, 1.054688f, 1.054688f >
Frame 4: Bone 43: < 274.9219f, 0.0f, 0.0f >
Frame 4: Bone 44: < 325.5469f, 347.3438f, 336.4453f >
Frame 4: Bone 45: < 304.1016f, 0.0f, 0.0f >
Frame 5: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 267.0f 143.0f
Frame 5: Bone 0: < 7.03125f, 0.0f, 0.0f >
Frame 5: Bone 1: < 355.0781f, 0.0f, 0.0f >
Frame 5: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 5: Bone 3: < 31.64063f, 354.375f, 0.0f >
Frame 5: Bone 4: < 345.9375f, 4.921875f, 1.757813f >
Frame 5: Bone 5: < 312.1875f, 279.4922f, 97.73438f >
Frame 5: Bone 6: < 1.40625f, 244.6875f, 206.3672f >
Frame 5: Bone 7: < 350.1563f, 20.39063f, 346.6406f >
Frame 5: Bone 8: < 355.7813f, 348.0469f, 2.109375f >
Frame 5: Bone 9: < 309.0234f, 90.70313f, 262.6172f >
Frame 5: Bone 10: < 2.460938f, 116.0156f, 153.2813f >
Frame 5: Bone 11: < 349.4531f, 334.3359f, 14.76563f >
Frame 5: Bone 12: < 358.9453f, 355.7813f, 359.2969f >
Frame 5: Bone 13: < 6.679688f, 5.273438f, 1.757813f >
Frame 5: Bone 14: < 355.7813f, 0.0f, 0.0f >
Frame 5: Bone 15: < 353.6719f, 349.1016f, 335.3906f >
Frame 5: Bone 16: < 77.34375f, 206.3672f, 191.25f >
Frame 5: Bone 17: < 44.29688f, 21.09375f, 4.921875f >
Frame 5: Bone 18: < 282.6563f, 176.4844f, 183.8672f >
Frame 5: Bone 19: < 354.375f, 348.3984f, 17.22656f >
Frame 5: Bone 20: < 336.4453f, 0.3515625f, 358.9453f >
Frame 5: Bone 21: < 349.4531f, 9.140625f, 24.96094f >
Frame 5: Bone 22: < 85.78125f, 24.60938f, 36.91406f >
Frame 5: Bone 23: < 38.67188f, 339.9609f, 357.1875f >
Frame 5: Bone 24: < 272.8125f, 175.7813f, 184.5703f >
Frame 5: Bone 25: < 3.867188f, 359.2969f, 348.75f >
Frame 5: Bone 26: < 341.3672f, 359.6484f, 1.054688f >
Frame 5: Bone 27: < 29.17969f, 252.7734f, 172.6172f >
Frame 5: Bone 28: < 325.1953f, 325.8984f, 110.3906f >
Frame 5: Bone 29: < 68.90625f, 177.8906f, 177.8906f >
Frame 5: Bone 30: < 292.8516f, 180.0f, 180.0f >
Frame 5: Bone 31: < 341.0156f, 9.84375f, 16.875f >
Frame 5: Bone 32: < 318.1641f, 0.0f, 0.0f >
Frame 5: Bone 33: < 9.84375f, 180.0f, 180.0f >
Frame 5: Bone 34: < 22.5f, 7.734375f, 2.8125f >
Frame 5: Bone 35: < 0.703125f, 352.6172f, 0.0f >
Frame 5: Bone 36: < 3.867188f, 350.8594f, 359.2969f >
Frame 5: Bone 37: < 2.460938f, 358.2422f, 0.0f >
Frame 5: Bone 38: < 3.867188f, 8.085938f, 0.703125f >
Frame 5: Bone 39: < 9.140625f, 7.734375f, 1.40625f >
Frame 5: Bone 40: < 29.17969f, 107.2266f, 32.34375f >
Frame 5: Bone 41: < 36.21094f, 353.6719f, 72.42188f >
Frame 5: Bone 42: < 76.99219f, 1.054688f, 1.054688f >
Frame 5: Bone 43: < 271.4063f, 0.0f, 0.0f >
Frame 5: Bone 44: < 329.4141f, 348.3984f, 335.3906f >
Frame 5: Bone 45: < 304.4531f, 0.0f, 0.0f >
Frame 6: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 269.0f 144.0f
Frame 6: Bone 0: < 8.085938f, 0.0f, 0.0f >
Frame 6: Bone 1: < 352.9688f, 0.0f, 0.0f >
Frame 6: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 6: Bone 3: < 33.75f, 354.0234f, 359.6484f >
Frame 6: Bone 4: < 344.8828f, 4.921875f, 1.757813f >
Frame 6: Bone 5: < 312.1875f, 278.7891f, 99.14063f >
Frame 6: Bone 6: < 0.703125f, 244.3359f, 206.3672f >
Frame 6: Bone 7: < 354.375f, 17.92969f, 346.2891f >
Frame 6: Bone 8: < 2.460938f, 346.2891f, 0.703125f >
Frame 6: Bone 9: < 309.0234f, 91.75781f, 261.2109f >
Frame 6: Bone 10: < 2.109375f, 116.3672f, 153.2813f >
Frame 6: Bone 11: < 353.6719f, 336.0938f, 14.76563f >
Frame 6: Bone 12: < 3.515625f, 355.4297f, 358.9453f >
Frame 6: Bone 13: < 5.976563f, 5.625f, 1.757813f >
Frame 6: Bone 14: < 355.4297f, 0.0f, 0.0f >
Frame 6: Bone 15: < 354.0234f, 348.75f, 335.3906f >
Frame 6: Bone 16: < 77.34375f, 205.6641f, 190.1953f >
Frame 6: Bone 17: < 43.94531f, 21.09375f, 4.921875f >
Frame 6: Bone 18: < 281.25f, 176.1328f, 184.2188f >
Frame 6: Bone 19: < 353.3203f, 348.3984f, 17.22656f >
Frame 6: Bone 20: < 337.1484f, 0.3515625f, 358.9453f >
Frame 6: Bone 21: < 349.8047f, 9.492188f, 24.96094f >
Frame 6: Bone 22: < 85.78125f, 21.79688f, 34.45313f >
Frame 6: Bone 23: < 38.67188f, 339.9609f, 357.1875f >
Frame 6: Bone 24: < 271.0547f, 168.75f, 191.25f >
Frame 6: Bone 25: < 3.515625f, 358.9453f, 349.1016f >
Frame 6: Bone 26: < 340.6641f, 359.6484f, 1.054688f >
Frame 6: Bone 27: < 28.82813f, 252.4219f, 171.2109f >
Frame 6: Bone 28: < 325.1953f, 324.1406f, 111.4453f >
Frame 6: Bone 29: < 70.3125f, 177.8906f, 177.8906f >
Frame 6: Bone 30: < 291.4453f, 180.0f, 180.0f >
Frame 6: Bone 31: < 342.0703f, 9.492188f, 17.57813f >
Frame 6: Bone 32: < 317.1094f, 0.0f, 0.0f >
Frame 6: Bone 33: < 8.4375f, 180.0f, 180.0f >
Frame 6: Bone 34: < 25.66406f, 2.8125f, 1.40625f >
Frame 6: Bone 35: < 356.1328f, 354.7266f, 0.3515625f >
Frame 6: Bone 36: < 358.2422f, 351.9141f, 0.3515625f >
Frame 6: Bone 37: < 4.21875f, 2.460938f, 0.3515625f >
Frame 6: Bone 38: < 6.679688f, 8.085938f, 1.054688f >
Frame 6: Bone 39: < 11.25f, 8.789063f, 1.757813f >
Frame 6: Bone 40: < 28.82813f, 107.9297f, 33.75f >
Frame 6: Bone 41: < 36.5625f, 353.6719f, 72.42188f >
Frame 6: Bone 42: < 74.17969f, 0.703125f, 0.703125f >
Frame 6: Bone 43: < 270.7031f, 0.0f, 0.0f >
Frame 6: Bone 44: < 331.875f, 348.75f, 334.6875f >
Frame 6: Bone 45: < 304.1016f, 0.0f, 0.0f >
Frame 7: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 274.0f 134.0f
Frame 7: Bone 0: < 10.54688f, 0.0f, 0.0f >
Frame 7: Bone 1: < 349.4531f, 0.0f, 0.0f >
Frame 7: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 7: Bone 3: < 37.26563f, 355.0781f, 359.2969f >
Frame 7: Bone 4: < 343.125f, 3.867188f, 1.40625f >
Frame 7: Bone 5: < 311.4844f, 275.625f, 101.6016f >
Frame 7: Bone 6: < 358.9453f, 243.6328f, 206.3672f >
Frame 7: Bone 7: < 4.21875f, 13.71094f, 344.1797f >
Frame 7: Bone 8: < 6.328125f, 345.9375f, 0.0f >
Frame 7: Bone 9: < 309.375f, 92.8125f, 258.3984f >
Frame 7: Bone 10: < 1.40625f, 116.7188f, 153.2813f >
Frame 7: Bone 11: < 4.21875f, 339.6094f, 15.46875f >
Frame 7: Bone 12: < 4.921875f, 356.4844f, 358.5938f >
Frame 7: Bone 13: < 4.21875f, 4.21875f, 1.054688f >
Frame 7: Bone 14: < 357.5391f, 0.0f, 0.0f >
Frame 7: Bone 15: < 354.7266f, 348.3984f, 335.3906f >
Frame 7: Bone 16: < 75.9375f, 203.2031f, 187.7344f >
Frame 7: Bone 17: < 42.89063f, 20.74219f, 4.921875f >
Frame 7: Bone 18: < 277.3828f, 173.6719f, 186.3281f >
Frame 7: Bone 19: < 350.8594f, 349.1016f, 17.22656f >
Frame 7: Bone 20: < 335.7422f, 0.3515625f, 358.9453f >
Frame 7: Bone 21: < 350.5078f, 9.84375f, 24.96094f >
Frame 7: Bone 22: < 87.1875f, 35.50781f, 48.16406f >
Frame 7: Bone 23: < 38.67188f, 339.9609f, 357.1875f >
Frame 7: Bone 24: < 271.4063f, 8.085938f, 351.9141f >
Frame 7: Bone 25: < 0.3515625f, 358.9453f, 350.1563f >
Frame 7: Bone 26: < 340.3125f, 359.6484f, 1.054688f >
Frame 7: Bone 27: < 28.125f, 251.0156f, 168.75f >
Frame 7: Bone 28: < 324.1406f, 325.8984f, 109.6875f >
Frame 7: Bone 29: < 77.69531f, 176.4844f, 176.4844f >
Frame 7: Bone 30: < 289.3359f, 180.0f, 180.0f >
Frame 7: Bone 31: < 345.9375f, 8.789063f, 18.63281f >
Frame 7: Bone 32: < 314.6484f, 0.0f, 0.0f >
Frame 7: Bone 33: < 6.328125f, 180.0f, 180.0f >
Frame 7: Bone 34: < 27.07031f, 357.8906f, 358.9453f >
Frame 7: Bone 35: < 352.2656f, 357.5391f, 0.3515625f >
Frame 7: Bone 36: < 352.6172f, 353.3203f, 1.054688f >
Frame 7: Bone 37: < 5.625f, 5.976563f, 0.703125f >
Frame 7: Bone 38: < 8.789063f, 7.03125f, 1.054688f >
Frame 7: Bone 39: < 12.65625f, 9.140625f, 2.109375f >
Frame 7: Bone 40: < 28.125f, 108.9844f, 36.21094f >
Frame 7: Bone 41: < 37.26563f, 354.0234f, 72.42188f >
Frame 7: Bone 42: < 63.98438f, 0.3515625f, 0.703125f >
Frame 7: Bone 43: < 279.4922f, 0.0f, 0.0f >
Frame 7: Bone 44: < 332.9297f, 348.3984f, 335.0391f >
Frame 7: Bone 45: < 301.6406f, 0.0f, 0.0f >
Frame 8: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 281.0f 117.0f
Frame 8: Bone 0: < 13.35938f, 0.0f, 0.0f >
Frame 8: Bone 1: < 345.2344f, 0.0f, 0.0f >
Frame 8: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 8: Bone 3: < 42.1875f, 357.5391f, 359.2969f >
Frame 8: Bone 4: < 340.6641f, 1.757813f, 0.3515625f >
Frame 8: Bone 5: < 310.7813f, 270.7031f, 105.1172f >
Frame 8: Bone 6: < 358.2422f, 243.2813f, 206.3672f >
Frame 8: Bone 7: < 16.17188f, 9.140625f, 340.6641f >
Frame 8: Bone 8: < 2.8125f, 348.3984f, 0.703125f >
Frame 8: Bone 9: < 310.0781f, 93.51563f, 254.8828f >
Frame 8: Bone 10: < 0.3515625f, 117.0703f, 153.2813f >
Frame 8: Bone 11: < 17.22656f, 343.8281f, 17.57813f >
Frame 8: Bone 12: < 0.3515625f, 359.6484f, 359.2969f >
Frame 8: Bone 13: < 1.757813f, 2.109375f, 0.3515625f >
Frame 8: Bone 14: < 1.40625f, 0.0f, 0.0f >
Frame 8: Bone 15: < 355.4297f, 348.0469f, 335.3906f >
Frame 8: Bone 16: < 73.125f, 200.7422f, 184.9219f >
Frame 8: Bone 17: < 40.78125f, 20.03906f, 4.921875f >
Frame 8: Bone 18: < 272.1094f, 155.3906f, 204.6094f >
Frame 8: Bone 19: < 347.6953f, 350.5078f, 17.57813f >
Frame 8: Bone 20: < 332.5781f, 0.3515625f, 358.9453f >
Frame 8: Bone 21: < 351.5625f, 10.19531f, 24.60938f >
Frame 8: Bone 22: < 87.89063f, 107.5781f, 120.9375f >
Frame 8: Bone 23: < 38.67188f, 339.9609f, 357.1875f >
Frame 8: Bone 24: < 274.5703f, 2.8125f, 357.5391f >
Frame 8: Bone 25: < 354.7266f, 358.2422f, 351.5625f >
Frame 8: Bone 26: < 339.6094f, 359.6484f, 1.054688f >
Frame 8: Bone 27: < 27.07031f, 249.6094f, 165.5859f >
Frame 8: Bone 28: < 322.0313f, 331.1719f, 105.4688f >
Frame 8: Bone 29: < 88.94531f, 53.4375f, 53.4375f >
Frame 8: Bone 30: < 286.875f, 180.0f, 180.0f >
Frame 8: Bone 31: < 351.9141f, 8.4375f, 20.39063f >
Frame 8: Bone 32: < 311.4844f, 0.0f, 0.0f >
Frame 8: Bone 33: < 3.164063f, 180.0f, 180.0f >
Frame 8: Bone 34: < 26.71875f, 352.6172f, 356.8359f >
Frame 8: Bone 35: < 349.1016f, 0.703125f, 0.0f >
Frame 8: Bone 36: < 347.6953f, 355.7813f, 1.054688f >
Frame 8: Bone 37: < 6.328125f, 9.492188f, 1.054688f >
Frame 8: Bone 38: < 10.19531f, 5.273438f, 1.054688f >
Frame 8: Bone 39: < 12.65625f, 8.4375f, 1.757813f >
Frame 8: Bone 40: < 27.07031f, 110.3906f, 39.375f >
Frame 8: Bone 41: < 38.67188f, 355.0781f, 73.125f >
Frame 8: Bone 42: < 47.10938f, 0.3515625f, 0.3515625f >
Frame 8: Bone 43: < 297.0703f, 0.0f, 0.0f >
Frame 8: Bone 44: < 332.2266f, 346.9922f, 336.4453f >
Frame 8: Bone 45: < 297.0703f, 0.0f, 0.0f >
Frame 9: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 286.0f 103.0f
Frame 9: Bone 0: < 15.82031f, 0.0f, 0.0f >
Frame 9: Bone 1: < 342.4219f, 0.0f, 0.0f >
Frame 9: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 9: Bone 3: < 44.29688f, 0.0f, 0.0f >
Frame 9: Bone 4: < 339.6094f, 0.0f, 0.0f >
Frame 9: Bone 5: < 310.4297f, 267.1875f, 106.875f >
Frame 9: Bone 6: < 358.2422f, 243.2813f, 206.3672f >
Frame 9: Bone 7: < 22.5f, 8.4375f, 339.2578f >
Frame 9: Bone 8: < 355.4297f, 352.2656f, 1.757813f >
Frame 9: Bone 9: < 310.4297f, 92.8125f, 253.125f >
Frame 9: Bone 10: < 0.3515625f, 117.0703f, 153.2813f >
Frame 9: Bone 11: < 22.85156f, 345.9375f, 18.98438f >
Frame 9: Bone 12: < 352.9688f, 3.164063f, 359.2969f >
Frame 9: Bone 13: < 0.703125f, 0.0f, 0.0f >
Frame 9: Bone 14: < 3.515625f, 0.0f, 0.0f >
Frame 9: Bone 15: < 356.1328f, 347.6953f, 335.3906f >
Frame 9: Bone 16: < 71.01563f, 199.6875f, 183.8672f >
Frame 9: Bone 17: < 39.72656f, 19.6875f, 4.921875f >
Frame 9: Bone 18: < 272.1094f, 24.60938f, 335.3906f >
Frame 9: Bone 19: < 345.2344f, 351.5625f, 17.92969f >
Frame 9: Bone 20: < 330.4688f, 0.703125f, 358.9453f >
Frame 9: Bone 21: < 351.9141f, 10.54688f, 24.60938f >
Frame 9: Bone 22: < 86.48438f, 140.625f, 153.9844f >
Frame 9: Bone 23: < 39.375f, 339.6094f, 357.1875f >
Frame 9: Bone 24: < 275.625f, 2.109375f, 357.8906f >
Frame 9: Bone 25: < 350.8594f, 357.5391f, 352.6172f >
Frame 9: Bone 26: < 339.2578f, 359.6484f, 1.054688f >
Frame 9: Bone 27: < 26.01563f, 248.5547f, 163.125f >
Frame 9: Bone 28: < 320.625f, 335.7422f, 102.3047f >
Frame 9: Bone 29: < 79.80469f, 4.21875f, 4.570313f >
Frame 9: Bone 30: < 284.7656f, 180.0f, 180.0f >
Frame 9: Bone 31: < 355.0781f, 8.085938f, 21.09375f >
Frame 9: Bone 32: < 310.0781f, 0.0f, 0.0f >
Frame 9: Bone 33: < 1.054688f, 180.0f, 180.0f >
Frame 9: Bone 34: < 26.71875f, 348.3984f, 354.7266f >
Frame 9: Bone 35: < 346.6406f, 3.867188f, 359.2969f >
Frame 9: Bone 36: < 344.1797f, 358.5938f, 0.3515625f >
Frame 9: Bone 37: < 6.679688f, 11.60156f, 1.40625f >
Frame 9: Bone 38: < 10.54688f, 3.164063f, 0.703125f >
Frame 9: Bone 39: < 11.60156f, 7.03125f, 1.40625f >
Frame 9: Bone 40: < 26.01563f, 111.4453f, 41.83594f >
Frame 9: Bone 41: < 39.72656f, 356.1328f, 73.82813f >
Frame 9: Bone 42: < 34.10156f, 0.3515625f, 0.3515625f >
Frame 9: Bone 43: < 311.1328f, 0.0f, 0.0f >
Frame 9: Bone 44: < 331.5234f, 345.9375f, 337.5f >
Frame 9: Bone 45: < 293.5547f, 0.0f, 0.0f >
Frame 10: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 288.0f 96.0f
Frame 10: Bone 0: < 16.52344f, 0.0f, 0.0f >
Frame 10: Bone 1: < 342.4219f, 0.0f, 0.0f >
Frame 10: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 10: Bone 3: < 43.24219f, 2.109375f, 0.703125f >
Frame 10: Bone 4: < 340.3125f, 358.5938f, 0.0f >
Frame 10: Bone 5: < 310.4297f, 266.4844f, 106.1719f >
Frame 10: Bone 6: < 358.5938f, 243.6328f, 206.3672f >
Frame 10: Bone 7: < 18.98438f, 13.35938f, 341.7188f >
Frame 10: Bone 8: < 346.9922f, 355.7813f, 1.40625f >
Frame 10: Bone 9: < 310.4297f, 90.35156f, 254.1797f >
Frame 10: Bone 10: < 0.703125f, 117.0703f, 153.2813f >
Frame 10: Bone 11: < 17.92969f, 344.5313f, 17.92969f >
Frame 10: Bone 12: < 346.6406f, 6.679688f, 358.5938f >
Frame 10: Bone 13: < 1.40625f, 358.2422f, 0.0f >
Frame 10: Bone 14: < 3.164063f, 0.0f, 0.0f >
Frame 10: Bone 15: < 355.7813f, 348.0469f, 335.3906f >
Frame 10: Bone 16: < 69.96094f, 200.0391f, 183.8672f >
Frame 10: Bone 17: < 40.07813f, 19.6875f, 4.921875f >
Frame 10: Bone 18: < 272.1094f, 21.44531f, 338.5547f >
Frame 10: Bone 19: < 344.5313f, 351.9141f, 18.28125f >
Frame 10: Bone 20: < 329.0625f, 0.703125f, 358.9453f >
Frame 10: Bone 21: < 351.5625f, 10.19531f, 24.60938f >
Frame 10: Bone 22: < 85.78125f, 144.1406f, 157.8516f >
Frame 10: Bone 23: < 40.42969f, 339.6094f, 357.1875f >
Frame 10: Bone 24: < 274.5703f, 2.8125f, 357.5391f >
Frame 10: Bone 25: < 349.4531f, 357.1875f, 352.2656f >
Frame 10: Bone 26: < 339.6094f, 359.6484f, 1.054688f >
Frame 10: Bone 27: < 26.01563f, 248.2031f, 162.4219f >
Frame 10: Bone 28: < 320.2734f, 338.2031f, 100.5469f >
Frame 10: Bone 29: < 75.9375f, 3.164063f, 3.164063f >
Frame 10: Bone 30: < 283.0078f, 180.0f, 180.0f >
Frame 10: Bone 31: < 353.6719f, 7.734375f, 21.44531f >
Frame 10: Bone 32: < 310.7813f, 0.0f, 0.0f >
Frame 10: Bone 33: < 0.3515625f, 180.0f, 180.0f >
Frame 10: Bone 34: < 28.125f, 345.2344f, 352.9688f >
Frame 10: Bone 35: < 345.9375f, 6.328125f, 358.5938f >
Frame 10: Bone 36: < 341.7188f, 1.757813f, 359.6484f >
Frame 10: Bone 37: < 6.328125f, 12.65625f, 1.40625f >
Frame 10: Bone 38: < 9.84375f, 0.703125f, 0.0f >
Frame 10: Bone 39: < 9.140625f, 4.921875f, 0.703125f >
Frame 10: Bone 40: < 26.01563f, 111.7969f, 42.53906f >
Frame 10: Bone 41: < 40.07813f, 357.1875f, 74.17969f >
Frame 10: Bone 42: < 28.125f, 0.0f, 0.3515625f >
Frame 10: Bone 43: < 318.1641f, 0.0f, 0.0f >
Frame 10: Bone 44: < 331.5234f, 344.5313f, 338.5547f >
Frame 10: Bone 45: < 291.0938f, 0.0f, 0.0f >
Frame 11: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 289.0f 90.0f
Frame 11: Bone 0: < 16.875f, 0.0f, 0.0f >
Frame 11: Bone 1: < 343.4766f, 0.0f, 0.0f >
Frame 11: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 11: Bone 3: < 40.07813f, 4.21875f, 1.40625f >
Frame 11: Bone 4: < 341.7188f, 356.8359f, 359.6484f >
Frame 11: Bone 5: < 310.0781f, 266.4844f, 103.7109f >
Frame 11: Bone 6: < 359.2969f, 243.9844f, 206.3672f >
Frame 11: Bone 7: < 10.19531f, 21.09375f, 344.5313f >
Frame 11: Bone 8: < 337.8516f, 0.3515625f, 0.0f >
Frame 11: Bone 9: < 310.7813f, 86.83594f, 256.2891f >
Frame 11: Bone 10: < 1.40625f, 116.7188f, 153.2813f >
Frame 11: Bone 11: < 8.085938f, 341.7188f, 16.17188f >
Frame 11: Bone 12: < 339.9609f, 10.89844f, 356.4844f >
Frame 11: Bone 13: < 2.8125f, 356.4844f, 359.6484f >
Frame 11: Bone 14: < 1.757813f, 0.0f, 0.0f >
Frame 11: Bone 15: < 355.0781f, 348.0469f, 335.3906f >
Frame 11: Bone 16: < 69.60938f, 200.7422f, 184.5703f >
Frame 11: Bone 17: < 41.13281f, 20.39063f, 4.921875f >
Frame 11: Bone 18: < 271.4063f, 40.42969f, 319.5703f >
Frame 11: Bone 19: < 344.8828f, 351.9141f, 18.63281f >
Frame 11: Bone 20: < 328.0078f, 0.703125f, 358.9453f >
Frame 11: Bone 21: < 351.2109f, 9.84375f, 24.96094f >
Frame 11: Bone 22: < 85.07813f, 143.4375f, 156.7969f >
Frame 11: Bone 23: < 41.83594f, 339.6094f, 357.1875f >
Frame 11: Bone 24: < 272.1094f, 5.976563f, 354.375f >
Frame 11: Bone 25: < 349.4531f, 356.8359f, 351.2109f >
Frame 11: Bone 26: < 339.9609f, 359.6484f, 1.054688f >
Frame 11: Bone 27: < 25.66406f, 248.2031f, 162.0703f >
Frame 11: Bone 28: < 319.9219f, 339.9609f, 99.84375f >
Frame 11: Bone 29: < 73.82813f, 2.8125f, 2.8125f >
Frame 11: Bone 30: < 280.8984f, 180.0f, 180.0f >
Frame 11: Bone 31: < 349.8047f, 6.679688f, 21.44531f >
Frame 11: Bone 32: < 313.2422f, 0.0f, 0.0f >
Frame 11: Bone 33: < 0.0f, 180.0f, 180.0f >
Frame 11: Bone 34: < 28.82813f, 343.125f, 351.5625f >
Frame 11: Bone 35: < 346.2891f, 8.4375f, 357.8906f >
Frame 11: Bone 36: < 341.3672f, 4.570313f, 358.5938f >
Frame 11: Bone 37: < 5.273438f, 12.65625f, 1.054688f >
Frame 11: Bone 38: < 8.085938f, 358.2422f, 359.6484f >
Frame 11: Bone 39: < 5.976563f, 2.109375f, 0.3515625f >
Frame 11: Bone 40: < 25.66406f, 112.1484f, 42.89063f >
Frame 11: Bone 41: < 40.42969f, 358.2422f, 74.88281f >
Frame 11: Bone 42: < 24.25781f, 0.0f, 0.3515625f >
Frame 11: Bone 43: < 323.0859f, 0.0f, 0.0f >
Frame 11: Bone 44: < 331.5234f, 343.4766f, 339.6094f >
Frame 11: Bone 45: < 288.6328f, 0.0f, 0.0f >
Frame 12: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 288.0f 88.0f
Frame 12: Bone 0: < 16.52344f, 0.0f, 0.0f >
Frame 12: Bone 1: < 345.2344f, 0.0f, 0.0f >
Frame 12: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 12: Bone 3: < 36.5625f, 5.625f, 1.757813f >
Frame 12: Bone 4: < 343.4766f, 355.4297f, 359.6484f >
Frame 12: Bone 5: < 310.0781f, 267.1875f, 101.25f >
Frame 12: Bone 6: < 0.3515625f, 244.3359f, 206.3672f >
Frame 12: Bone 7: < 0.703125f, 28.125f, 345.5859f >
Frame 12: Bone 8: < 329.7656f, 4.570313f, 357.5391f >
Frame 12: Bone 9: < 310.7813f, 83.67188f, 259.1016f >
Frame 12: Bone 10: < 1.757813f, 116.3672f, 153.2813f >
Frame 12: Bone 11: < 357.8906f, 338.5547f, 15.11719f >
Frame 12: Bone 12: < 335.3906f, 15.11719f, 354.375f >
Frame 12: Bone 13: < 4.570313f, 355.0781f, 359.6484f >
Frame 12: Bone 14: < 0.0f, 0.0f, 0.0f >
Frame 12: Bone 15: < 354.375f, 348.3984f, 335.3906f >
Frame 12: Bone 16: < 69.60938f, 201.7969f, 185.2734f >
Frame 12: Bone 17: < 42.1875f, 20.74219f, 4.921875f >
Frame 12: Bone 18: < 271.0547f, 137.4609f, 222.5391f >
Frame 12: Bone 19: < 345.2344f, 351.9141f, 18.98438f >
Frame 12: Bone 20: < 326.9531f, 0.703125f, 358.9453f >
Frame 12: Bone 21: < 350.5078f, 9.492188f, 24.96094f >
Frame 12: Bone 22: < 85.07813f, 140.625f, 154.3359f >
Frame 12: Bone 23: < 42.89063f, 339.6094f, 356.8359f >
Frame 12: Bone 24: < 270.7031f, 164.5313f, 195.4688f >
Frame 12: Bone 25: < 349.8047f, 356.8359f, 349.8047f >
Frame 12: Bone 26: < 340.3125f, 359.6484f, 1.054688f >
Frame 12: Bone 27: < 25.66406f, 248.2031f, 162.4219f >
Frame 12: Bone 28: < 319.5703f, 341.0156f, 99.14063f >
Frame 12: Bone 29: < 73.47656f, 2.8125f, 2.8125f >
Frame 12: Bone 30: < 279.8438f, 180.0f, 180.0f >
Frame 12: Bone 31: < 345.9375f, 5.976563f, 21.09375f >
Frame 12: Bone 32: < 315.7031f, 0.0f, 0.0f >
Frame 12: Bone 33: < 0.0f, 180.0f, 180.0f >
Frame 12: Bone 34: < 29.53125f, 342.7734f, 351.5625f >
Frame 12: Bone 35: < 348.0469f, 9.84375f, 357.8906f >
Frame 12: Bone 36: < 342.7734f, 7.03125f, 357.8906f >
Frame 12: Bone 37: < 3.867188f, 11.60156f, 0.703125f >
Frame 12: Bone 38: < 5.625f, 355.7813f, 359.6484f >
Frame 12: Bone 39: < 2.109375f, 359.6484f, 0.0f >
Frame 12: Bone 40: < 25.66406f, 111.7969f, 42.53906f >
Frame 12: Bone 41: < 40.42969f, 358.9453f, 75.58594f >
Frame 12: Bone 42: < 23.20313f, 0.0f, 0.3515625f >
Frame 12: Bone 43: < 325.8984f, 0.0f, 0.0f >
Frame 12: Bone 44: < 330.8203f, 342.4219f, 340.6641f >
Frame 12: Bone 45: < 287.2266f, 0.0f, 0.0f >
Frame 13: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 286.0f 87.0f
Frame 13: Bone 0: < 15.82031f, 0.0f, 0.0f >
Frame 13: Bone 1: < 346.9922f, 0.0f, 0.0f >
Frame 13: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 13: Bone 3: < 33.39844f, 6.328125f, 1.40625f >
Frame 13: Bone 4: < 344.8828f, 354.7266f, 359.2969f >
Frame 13: Bone 5: < 310.0781f, 267.8906f, 99.14063f >
Frame 13: Bone 6: < 1.054688f, 244.6875f, 206.3672f >
Frame 13: Bone 7: < 354.375f, 32.34375f, 344.8828f >
Frame 13: Bone 8: < 325.8984f, 7.03125f, 355.4297f >
Frame 13: Bone 9: < 311.1328f, 81.5625f, 260.8594f >
Frame 13: Bone 10: < 2.109375f, 116.0156f, 153.2813f >
Frame 13: Bone 11: < 351.5625f, 336.7969f, 14.41406f >
Frame 13: Bone 12: < 333.6328f, 16.875f, 352.9688f >
Frame 13: Bone 13: < 5.976563f, 354.7266f, 359.2969f >
Frame 13: Bone 14: < 358.9453f, 0.0f, 0.0f >
Frame 13: Bone 15: < 354.0234f, 348.75f, 335.3906f >
Frame 13: Bone 16: < 69.60938f, 202.5f, 186.3281f >
Frame 13: Bone 17: < 42.89063f, 21.09375f, 4.921875f >
Frame 13: Bone 18: < 272.8125f, 163.8281f, 196.5234f >
Frame 13: Bone 19: < 346.2891f, 351.9141f, 19.33594f >
Frame 13: Bone 20: < 326.6016f, 0.703125f, 358.9453f >
Frame 13: Bone 21: < 349.8047f, 9.492188f, 24.96094f >
Frame 13: Bone 22: < 85.07813f, 138.1641f, 151.875f >
Frame 13: Bone 23: < 43.59375f, 339.6094f, 356.8359f >
Frame 13: Bone 24: < 272.8125f, 176.1328f, 184.2188f >
Frame 13: Bone 25: < 350.5078f, 356.8359f, 349.1016f >
Frame 13: Bone 26: < 340.6641f, 359.6484f, 1.054688f >
Frame 13: Bone 27: < 26.01563f, 248.5547f, 163.125f >
Frame 13: Bone 28: < 319.9219f, 342.4219f, 98.4375f >
Frame 13: Bone 29: < 74.53125f, 2.8125f, 2.8125f >
Frame 13: Bone 30: < 280.1953f, 180.0f, 180.0f >
Frame 13: Bone 31: < 343.125f, 5.625f, 20.74219f >
Frame 13: Bone 32: < 317.4609f, 0.0f, 0.0f >
Frame 13: Bone 33: < 1.054688f, 180.0f, 180.0f >
Frame 13: Bone 34: < 29.53125f, 344.5313f, 352.2656f >
Frame 13: Bone 35: < 350.8594f, 10.19531f, 358.5938f >
Frame 13: Bone 36: < 345.9375f, 8.789063f, 357.8906f >
Frame 13: Bone 37: < 2.109375f, 9.140625f, 0.3515625f >
Frame 13: Bone 38: < 2.8125f, 354.0234f, 359.6484f >
Frame 13: Bone 39: < 358.2422f, 356.8359f, 0.0f >
Frame 13: Bone 40: < 26.01563f, 111.4453f, 41.83594f >
Frame 13: Bone 41: < 40.07813f, 359.2969f, 75.9375f >
Frame 13: Bone 42: < 24.96094f, 0.0f, 0.3515625f >
Frame 13: Bone 43: < 326.6016f, 0.0f, 0.0f >
Frame 13: Bone 44: < 329.4141f, 341.7188f, 341.3672f >
Frame 13: Bone 45: < 287.2266f, 0.0f, 0.0f >
Frame 14: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 284.0f 89.0f
Frame 14: Bone 0: < 14.0625f, 0.0f, 0.0f >
Frame 14: Bone 1: < 349.8047f, 0.0f, 0.0f >
Frame 14: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 14: Bone 3: < 31.28906f, 5.976563f, 1.054688f >
Frame 14: Bone 4: < 345.9375f, 355.0781f, 359.2969f >
Frame 14: Bone 5: < 310.0781f, 269.6484f, 97.38281f >
Frame 14: Bone 6: < 1.40625f, 244.6875f, 206.3672f >
Frame 14: Bone 7: < 352.2656f, 33.39844f, 344.5313f >
Frame 14: Bone 8: < 326.25f, 7.03125f, 355.7813f >
Frame 14: Bone 9: < 311.1328f, 80.50781f, 262.2656f >
Frame 14: Bone 10: < 2.460938f, 116.0156f, 153.2813f >
Frame 14: Bone 11: < 350.1563f, 335.3906f, 14.41406f >
Frame 14: Bone 12: < 336.4453f, 15.46875f, 354.0234f >
Frame 14: Bone 13: < 6.679688f, 354.7266f, 359.2969f >
Frame 14: Bone 14: < 358.9453f, 0.0f, 0.0f >
Frame 14: Bone 15: < 353.6719f, 349.1016f, 335.3906f >
Frame 14: Bone 16: < 69.96094f, 203.2031f, 187.0313f >
Frame 14: Bone 17: < 43.24219f, 21.09375f, 4.921875f >
Frame 14: Bone 18: < 274.9219f, 170.5078f, 189.8438f >
Frame 14: Bone 19: < 347.6953f, 351.9141f, 19.33594f >
Frame 14: Bone 20: < 326.6016f, 0.703125f, 358.9453f >
Frame 14: Bone 21: < 349.4531f, 9.140625f, 24.96094f >
Frame 14: Bone 22: < 85.07813f, 135.3516f, 148.7109f >
Frame 14: Bone 23: < 43.59375f, 339.6094f, 356.8359f >
Frame 14: Bone 24: < 274.5703f, 177.5391f, 182.8125f >
Frame 14: Bone 25: < 351.5625f, 357.1875f, 348.75f >
Frame 14: Bone 26: < 341.3672f, 359.6484f, 1.054688f >
Frame 14: Bone 27: < 26.71875f, 249.2578f, 164.8828f >
Frame 14: Bone 28: < 320.2734f, 343.8281f, 97.73438f >
Frame 14: Bone 29: < 77.69531f, 3.515625f, 3.515625f >
Frame 14: Bone 30: < 282.6563f, 180.0f, 180.0f >
Frame 14: Bone 31: < 342.4219f, 5.976563f, 20.39063f >
Frame 14: Bone 32: < 318.1641f, 0.0f, 0.0f >
Frame 14: Bone 33: < 2.8125f, 180.0f, 180.0f >
Frame 14: Bone 34: < 29.17969f, 347.3438f, 353.6719f >
Frame 14: Bone 35: < 354.7266f, 9.140625f, 359.2969f >
Frame 14: Bone 36: < 350.5078f, 9.492188f, 358.5938f >
Frame 14: Bone 37: < 0.0f, 5.976563f, 0.0f >
Frame 14: Bone 38: < 359.6484f, 352.6172f, 0.0f >
Frame 14: Bone 39: < 354.375f, 354.375f, 0.703125f >
Frame 14: Bone 40: < 26.71875f, 110.7422f, 40.07813f >
Frame 14: Bone 41: < 39.375f, 359.2969f, 75.9375f >
Frame 14: Bone 42: < 29.88281f, 0.0f, 0.3515625f >
Frame 14: Bone 43: < 325.1953f, 0.0f, 0.0f >
Frame 14: Bone 44: < 326.6016f, 341.0156f, 342.4219f >
Frame 14: Bone 45: < 288.2813f, 0.0f, 0.0f >
Frame 15: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 280.0f 93.0f
Frame 15: Bone 0: < 11.60156f, 0.0f, 0.0f >
Frame 15: Bone 1: < 352.9688f, 0.0f, 0.0f >
Frame 15: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 15: Bone 3: < 29.17969f, 4.921875f, 0.703125f >
Frame 15: Bone 4: < 346.6406f, 355.7813f, 359.2969f >
Frame 15: Bone 5: < 310.0781f, 271.4063f, 95.97656f >
Frame 15: Bone 6: < 1.40625f, 244.6875f, 206.3672f >
Frame 15: Bone 7: < 351.9141f, 33.39844f, 344.5313f >
Frame 15: Bone 8: < 331.1719f, 5.273438f, 357.1875f >
Frame 15: Bone 9: < 311.1328f, 80.15625f, 264.0234f >
Frame 15: Bone 10: < 2.109375f, 116.3672f, 153.2813f >
Frame 15: Bone 11: < 350.5078f, 334.3359f, 14.76563f >
Frame 15: Bone 12: < 349.4531f, 12.65625f, 357.5391f >
Frame 15: Bone 13: < 7.734375f, 355.4297f, 359.2969f >
Frame 15: Bone 14: < 359.2969f, 0.0f, 0.0f >
Frame 15: Bone 15: < 352.9688f, 349.1016f, 335.3906f >
Frame 15: Bone 16: < 70.3125f, 204.2578f, 187.7344f >
Frame 15: Bone 17: < 43.59375f, 21.09375f, 4.921875f >
Frame 15: Bone 18: < 277.0313f, 173.6719f, 186.3281f >
Frame 15: Bone 19: < 349.8047f, 351.9141f, 19.6875f >
Frame 15: Bone 20: < 326.6016f, 0.703125f, 358.9453f >
Frame 15: Bone 21: < 349.1016f, 9.140625f, 24.96094f >
Frame 15: Bone 22: < 85.42969f, 131.4844f, 145.1953f >
Frame 15: Bone 23: < 43.24219f, 339.6094f, 356.8359f >
Frame 15: Bone 24: < 276.3281f, 178.2422f, 182.1094f >
Frame 15: Bone 25: < 352.6172f, 357.8906f, 348.3984f >
Frame 15: Bone 26: < 342.0703f, 359.6484f, 1.054688f >
Frame 15: Bone 27: < 27.42188f, 250.3125f, 167.3438f >
Frame 15: Bone 28: < 320.625f, 345.5859f, 97.03125f >
Frame 15: Bone 29: < 81.91406f, 5.625f, 5.625f >
Frame 15: Bone 30: < 286.1719f, 180.0f, 180.0f >
Frame 15: Bone 31: < 342.0703f, 7.03125f, 19.33594f >
Frame 15: Bone 32: < 319.2188f, 0.0f, 0.0f >
Frame 15: Bone 33: < 4.921875f, 180.0f, 180.0f >
Frame 15: Bone 34: < 28.82813f, 351.5625f, 356.1328f >
Frame 15: Bone 35: < 358.9453f, 7.734375f, 0.0f >
Frame 15: Bone 36: < 355.7813f, 9.492188f, 359.2969f >
Frame 15: Bone 37: < 357.8906f, 2.109375f, 0.0f >
Frame 15: Bone 38: < 356.4844f, 351.9141f, 0.703125f >
Frame 15: Bone 39: < 350.8594f, 352.6172f, 1.40625f >
Frame 15: Bone 40: < 27.42188f, 109.6875f, 37.61719f >
Frame 15: Bone 41: < 38.67188f, 358.9453f, 75.9375f >
Frame 15: Bone 42: < 37.26563f, 0.3515625f, 0.3515625f >
Frame 15: Bone 43: < 322.3828f, 0.0f, 0.0f >
Frame 15: Bone 44: < 322.7344f, 340.3125f, 343.4766f >
Frame 15: Bone 45: < 290.0391f, 0.0f, 0.0f >
Frame 16: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 277.0f 97.0f
Frame 16: Bone 0: < 9.140625f, 0.0f, 0.0f >
Frame 16: Bone 1: < 356.1328f, 0.0f, 0.0f >
Frame 16: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 16: Bone 3: < 27.07031f, 3.867188f, 0.3515625f >
Frame 16: Bone 4: < 347.6953f, 356.8359f, 359.2969f >
Frame 16: Bone 5: < 310.0781f, 273.5156f, 94.57031f >
Frame 16: Bone 6: < 1.054688f, 244.6875f, 206.3672f >
Frame 16: Bone 7: < 352.9688f, 31.99219f, 344.8828f >
Frame 16: Bone 8: < 349.1016f, 3.164063f, 0.0f >
Frame 16: Bone 9: < 311.4844f, 80.15625f, 265.4297f >
Frame 16: Bone 10: < 1.40625f, 116.3672f, 153.2813f >
Frame 16: Bone 11: < 352.9688f, 333.6328f, 15.11719f >
Frame 16: Bone 12: < 3.164063f, 9.84375f, 359.6484f >
Frame 16: Bone 13: < 8.789063f, 356.4844f, 359.2969f >
Frame 16: Bone 14: < 0.0f, 0.0f, 0.0f >
Frame 16: Bone 15: < 352.6172f, 349.4531f, 335.3906f >
Frame 16: Bone 16: < 70.66406f, 204.9609f, 188.4375f >
Frame 16: Bone 17: < 43.94531f, 21.44531f, 4.921875f >
Frame 16: Bone 18: < 279.4922f, 175.4297f, 184.9219f >
Frame 16: Bone 19: < 351.9141f, 351.9141f, 19.6875f >
Frame 16: Bone 20: < 326.9531f, 0.703125f, 358.9453f >
Frame 16: Bone 21: < 348.3984f, 8.789063f, 24.96094f >
Frame 16: Bone 22: < 85.42969f, 126.5625f, 140.2734f >
Frame 16: Bone 23: < 42.89063f, 339.6094f, 357.1875f >
Frame 16: Bone 24: < 277.7344f, 178.5938f, 181.7578f >
Frame 16: Bone 25: < 353.6719f, 358.5938f, 348.3984f >
Frame 16: Bone 26: < 342.7734f, 359.6484f, 1.054688f >
Frame 16: Bone 27: < 28.47656f, 251.7188f, 170.1563f >
Frame 16: Bone 28: < 321.3281f, 347.3438f, 96.32813f >
Frame 16: Bone 29: < 87.1875f, 15.11719f, 15.11719f >
Frame 16: Bone 30: < 290.3906f, 180.0f, 180.0f >
Frame 16: Bone 31: < 342.0703f, 8.085938f, 18.28125f >
Frame 16: Bone 32: < 319.5703f, 0.0f, 0.0f >
Frame 16: Bone 33: < 7.382813f, 180.0f, 180.0f >
Frame 16: Bone 34: < 27.77344f, 356.8359f, 358.5938f >
Frame 16: Bone 35: < 3.164063f, 5.625f, 0.3515625f >
Frame 16: Bone 36: < 1.40625f, 8.4375f, 0.3515625f >
Frame 16: Bone 37: < 356.1328f, 357.8906f, 0.3515625f >
Frame 16: Bone 38: < 353.6719f, 351.9141f, 1.054688f >
Frame 16: Bone 39: < 348.75f, 351.2109f, 1.757813f >
Frame 16: Bone 40: < 28.47656f, 108.2813f, 34.80469f >
Frame 16: Bone 41: < 37.61719f, 358.5938f, 75.58594f >
Frame 16: Bone 42: < 46.05469f, 0.3515625f, 0.3515625f >
Frame 16: Bone 43: < 318.5156f, 0.0f, 0.0f >
Frame 16: Bone 44: < 318.5156f, 339.9609f, 344.5313f >
Frame 16: Bone 45: < 292.5f, 0.0f, 0.0f >
Frame 17: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 273.0f 103.0f
Frame 17: Bone 0: < 6.679688f, 0.0f, 0.0f >
Frame 17: Bone 1: < 359.2969f, 0.0f, 0.0f >
Frame 17: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 17: Bone 3: < 25.66406f, 2.460938f, 0.3515625f >
Frame 17: Bone 4: < 348.3984f, 357.8906f, 359.6484f >
Frame 17: Bone 5: < 310.4297f, 275.625f, 93.51563f >
Frame 17: Bone 6: < 359.6484f, 243.9844f, 206.3672f >
Frame 17: Bone 7: < 355.4297f, 30.23438f, 345.2344f >
Frame 17: Bone 8: < 10.19531f, 1.40625f, 2.109375f >
Frame 17: Bone 9: < 311.1328f, 80.50781f, 266.4844f >
Frame 17: Bone 10: < 0.703125f, 117.0703f, 153.2813f >
Frame 17: Bone 11: < 355.7813f, 333.2813f, 15.11719f >
Frame 17: Bone 12: < 10.19531f, 7.382813f, 0.0f >
Frame 17: Bone 13: < 9.492188f, 357.8906f, 359.6484f >
Frame 17: Bone 14: < 0.703125f, 0.0f, 0.0f >
Frame 17: Bone 15: < 352.2656f, 349.4531f, 335.3906f >
Frame 17: Bone 16: < 71.01563f, 205.6641f, 189.1406f >
Frame 17: Bone 17: < 44.29688f, 21.44531f, 4.921875f >
Frame 17: Bone 18: < 281.9531f, 176.1328f, 183.8672f >
Frame 17: Bone 19: < 354.0234f, 351.5625f, 19.6875f >
Frame 17: Bone 20: < 327.3047f, 0.703125f, 358.9453f >
Frame 17: Bone 21: < 348.0469f, 8.4375f, 24.96094f >
Frame 17: Bone 22: < 85.78125f, 120.9375f, 134.2969f >
Frame 17: Bone 23: < 42.1875f, 339.6094f, 357.1875f >
Frame 17: Bone 24: < 278.7891f, 178.5938f, 181.4063f >
Frame 17: Bone 25: < 355.0781f, 359.2969f, 348.0469f >
Frame 17: Bone 26: < 343.125f, 359.6484f, 1.054688f >
Frame 17: Bone 27: < 29.17969f, 253.125f, 172.6172f >
Frame 17: Bone 28: < 322.0313f, 348.3984f, 95.97656f >
Frame 17: Bone 29: < 87.53906f, 161.3672f, 161.3672f >
Frame 17: Bone 30: < 294.6094f, 180.0f, 180.0f >
Frame 17: Bone 31: < 342.4219f, 9.140625f, 17.22656f >
Frame 17: Bone 32: < 319.9219f, 0.0f, 0.0f >
Frame 17: Bone 33: < 9.84375f, 180.0f, 180.0f >
Frame 17: Bone 34: < 26.01563f, 1.757813f, 0.703125f >
Frame 17: Bone 35: < 7.382813f, 2.8125f, 0.3515625f >
Frame 17: Bone 36: < 7.03125f, 6.679688f, 0.703125f >
Frame 17: Bone 37: < 354.7266f, 354.375f, 0.703125f >
Frame 17: Bone 38: < 351.5625f, 352.9688f, 1.054688f >
Frame 17: Bone 39: < 347.3438f, 350.8594f, 2.109375f >
Frame 17: Bone 40: < 29.17969f, 107.2266f, 32.34375f >
Frame 17: Bone 41: < 36.5625f, 357.8906f, 75.23438f >
Frame 17: Bone 42: < 54.84375f, 0.3515625f, 0.3515625f >
Frame 17: Bone 43: < 313.9453f, 0.0f, 0.0f >
Frame 17: Bone 44: < 315.0f, 339.2578f, 345.9375f >
Frame 17: Bone 45: < 295.3125f, 0.0f, 0.0f >
Frame 18: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 270.0f 108.0f
Frame 18: Bone 0: < 4.921875f, 0.0f, 0.0f >
Frame 18: Bone 1: < 1.757813f, 0.0f, 0.0f >
Frame 18: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 18: Bone 3: < 24.25781f, 1.054688f, 0.0f >
Frame 18: Bone 4: < 349.1016f, 358.9453f, 359.6484f >
Frame 18: Bone 5: < 310.7813f, 277.3828f, 92.8125f >
Frame 18: Bone 6: < 358.5938f, 243.6328f, 206.3672f >
Frame 18: Bone 7: < 357.8906f, 28.125f, 345.2344f >
Frame 18: Bone 8: < 18.63281f, 359.6484f, 1.757813f >
Frame 18: Bone 9: < 311.1328f, 80.85938f, 267.1875f >
Frame 18: Bone 10: < 0.3515625f, 117.0703f, 153.2813f >
Frame 18: Bone 11: < 357.8906f, 332.9297f, 15.11719f >
Frame 18: Bone 12: < 14.0625f, 4.570313f, 359.6484f >
Frame 18: Bone 13: < 9.84375f, 358.9453f, 359.6484f >
Frame 18: Bone 14: < 1.054688f, 0.0f, 0.0f >
Frame 18: Bone 15: < 351.9141f, 349.8047f, 335.3906f >
Frame 18: Bone 16: < 71.71875f, 206.3672f, 189.8438f >
Frame 18: Bone 17: < 44.29688f, 21.44531f, 4.921875f >
Frame 18: Bone 18: < 283.7109f, 176.8359f, 183.5156f >
Frame 18: Bone 19: < 355.7813f, 351.5625f, 19.33594f >
Frame 18: Bone 20: < 327.6563f, 0.703125f, 358.9453f >
Frame 18: Bone 21: < 348.0469f, 8.4375f, 24.96094f >
Frame 18: Bone 22: < 86.13281f, 114.2578f, 127.6172f >
Frame 18: Bone 23: < 41.83594f, 339.6094f, 357.1875f >
Frame 18: Bone 24: < 279.8438f, 178.9453f, 181.4063f >
Frame 18: Bone 25: < 356.4844f, 359.6484f, 348.3984f >
Frame 18: Bone 26: < 343.8281f, 359.6484f, 1.054688f >
Frame 18: Bone 27: < 29.53125f, 254.1797f, 174.7266f >
Frame 18: Bone 28: < 322.3828f, 348.75f, 95.97656f >
Frame 18: Bone 29: < 82.96875f, 173.6719f, 173.6719f >
Frame 18: Bone 30: < 298.125f, 180.0f, 180.0f >
Frame 18: Bone 31: < 342.4219f, 10.19531f, 16.52344f >
Frame 18: Bone 32: < 320.2734f, 0.0f, 0.0f >
Frame 18: Bone 33: < 11.95313f, 180.0f, 180.0f >
Frame 18: Bone 34: < 23.90625f, 6.679688f, 2.8125f >
Frame 18: Bone 35: < 10.54688f, 359.6484f, 0.0f >
Frame 18: Bone 36: < 11.95313f, 4.570313f, 1.054688f >
Frame 18: Bone 37: < 353.6719f, 350.8594f, 1.054688f >
Frame 18: Bone 38: < 350.1563f, 354.7266f, 1.054688f >
Frame 18: Bone 39: < 347.3438f, 351.5625f, 2.109375f >
Frame 18: Bone 40: < 29.53125f, 106.1719f, 30.23438f >
Frame 18: Bone 41: < 35.85938f, 357.5391f, 75.23438f >
Frame 18: Bone 42: < 62.22656f, 0.3515625f, 0.3515625f >
Frame 18: Bone 43: < 309.375f, 0.0f, 0.0f >
Frame 18: Bone 44: < 312.1875f, 339.2578f, 346.6406f >
Frame 18: Bone 45: < 297.4219f, 0.0f, 0.0f >
Frame 19: Rotations/Translations: 0.0f 0.0f 0.0f 0.0f 268.0f 113.0f
Frame 19: Bone 0: < 3.515625f, 0.0f, 0.0f >
Frame 19: Bone 1: < 3.164063f, 0.0f, 0.0f >
Frame 19: Bone 2: < 0.0f, 0.0f, 0.0f >
Frame 19: Bone 3: < 23.90625f, 0.0f, 0.0f >
Frame 19: Bone 4: < 349.1016f, 0.0f, 0.0f >
Frame 19: Bone 5: < 310.7813f, 278.4375f, 92.46094f >
Frame 19: Bone 6: < 358.2422f, 243.2813f, 206.3672f >
Frame 19: Bone 7: < 357.5391f, 27.07031f, 345.5859f >
Frame 19: Bone 8: < 19.6875f, 357.89
-
Guys... you might want to consider putting such a huge code block in a separate text file and linking to it, instead of including it in your post. This page of the topic alone is a near-300k download.
EDIT: Sigh, of course my post ended up on a new page... Right, the PREVIOUS page of the topic alone is a near-300k download.
-
Believe me that is what I wanted to do.
But I do not have anywhere to put it.
I don’t have access to my own site.
Find me free web space and I would definitely put it there instead.
Plus we should really move this to a topic specifically for figuring out these files.
L. Spiro
-
Oh yea that last post is HUGE. But its nice progress :)
L. Spiro: use me trashbin http://bin.mypage.sk, its web uploading interface
-
You could also use 250free.com. They give a fairly decent amount of space (250 MB) and bandwidth (250 Mbit).
-
Alright I'll post links instead of the images as well. I have them set to expire quickly out of Mirex's trash bin though :)
Spiro you aren't coming across too coherently too me.
struct s_FF7AAanimHdr {
unsigned long rec_a; //0
unsigned long rec_b; //4
unsigned long block_len; //8
unsigned short block_a; //12
unsigned short real_data_len; //14
unsigned short translat[3]; //16
unsigned char u1; //22
} FF7AAanimHdr; //size = 23 bytes
struct s_FF7AAanimHdr {
unsigned long rec_a; //0
unsigned long frames_1; //4
unsigned long block_len; //8
unsigned short frames_2; //12
unsigned short real_data_len; //14
unsigned char u1; //16
} FF7AAanimHdr; //size = 17 bytes
All right .. why the moving of u1? is this the 'new' U1 value that is a certain number of rotations that are ignored? Then the frame XYZ offset? I'm not sure that this works right. All the integers in the playstation version are little endian. So this gives me better nasty and weird values. do these new values work for you? How do you discern the frame count per animation?
Cyb
-
Actually I have found that the new u1 value does not actually depict the number of rotations to ignore, but it seems very close. In Red XIII’s animation set, the values are as I showed, but if you do as I mentioned and skip 2 rotations, you get values that are VERY close to what they should be, but down the line they become more and more off.
It could be a key to some type of compression (and most likely is).
I removed the “unsigned short translat[3]; //16†completely from the header because it is actually part of every frame.
And also, they actually come one byte later in the file than previously thought, decoded as I showed.
In other words, since they come one byte later, “u1†is actually the last byte of “translat[3]â€, which is why I moved it to the front of “translat[3]â€.
But after I moved it to the front I then removed “translat[3]†entirely.
As for the frame counts, they are in RAM (the same place I got all my data). Red XIII’s and Barret’s first animations are posted and have 20 frames each. I have checked others as well, but since “rec_b†and “block_a†are always the same I am unsure which one is actually depicting the frame count.
Most likely it is “block_aâ€, since that is the logical place to put the frame count.
If your values are already in little endian, you don’t need to translate them to little endian. Just use them as they are and you should get the values I posted.
L. Spiro
-
Actually I have found that the new u1 value does not actually depict the number of rotations to ignore, but it seems very close. In Red XIII’s animation set, the values are as I showed, but if you do as I mentioned and skip 2 rotations, you get values that are VERY close to what they should be, but down the line they become more and more off.
It could be a key to some type of compression (and most likely is).
I removed the “unsigned short translat[3]; //16†completely from the header because it is actually part of every frame.
And also, they actually come one byte later in the file than previously thought, decoded as I showed.
In other words, since they come one byte later, “u1†is actually the last byte of “translat[3]â€, which is why I moved it to the front of “translat[3]â€.
But after I moved it to the front I then removed “translat[3]†entirely.
As for the frame counts, they are in RAM (the same place I got all my data). Red XIII’s and Barret’s first animations are posted and have 20 frames each. I have checked others as well, but since “rec_b†and “block_a†are always the same I am unsure which one is actually depicting the frame count.
Most likely it is “block_aâ€, since that is the logical place to put the frame count.
If your values are already in little endian, you don’t need to translate them to little endian. Just use them as they are and you should get the values I posted.
L. Spiro
Spiro since I don't know which animation is Barettes normal animation, might it be possible for you to indicate which one this is? I have many possibilities and no way of knowing which one you are looking at (1 of 90 some odd animations). Guessing isn't too helpful in this case :D I tend to use the first animation myself.
I am going to attempt to see if your data is matching mine and what's up.
And here are the results (text list (http://bin.mypage.sk/FILES/temp.txt)), here is a marked up hexdump (A Big JPEG (http://bin.mypage.sk/FILES/Dump.jpg)).
I likely have a misalignment however whats the length of your animation packet? Mine appears to be 879 bytes which can in no way store 20 frames of animation. The first frame matches yours quite nicely however.
Cyb - still puzzled.
-
Maybe the problem is not compression, but a different storage system for rotational information.
-
Yes, mine is the first animation and your first frame matches it fine.
But remember, I got these animations from RAM and not the file.
When it comes to the file, I still don't know how to decode past the first frame, so that is all I can document.
Each frame DOES have a rotational and translational offset, but after the first frame it is stored differently.
So, keep in mind that all I post so far covers the first frame.
Also, about your translations, they are backwards.
You got 4862, which is hex “12 FEâ€
You need hex “FE 12†to get -494.
Since you say the PlayStation values may already be reversed, I don’t think you need to reverse them, but no matter what the case, the final result should be -494.
L. Spiro
-
I remeber reading somewhere that PSX animation can be compressed. I somehow remember this being an issure with FF9 and MGS. In MGS's case it was an interview with So Toyota and how he was able to cram all those moving models around and have room left for the game.
Let us theroize about animation compression for a little bit.
What we know.
1) The system creates a series of distinct frames when it's loaded into memory.
2) The model has diffrent "sets" of animation that are used at differrent times. (Throwing, slashing, running)
3) As a file, the animation starts with a "keyframe" and then unknown data spews past it.
Ok, here's some rules about FF7 on the PSX.
1) Do not do a file access unless you absoluty have to. The PSX is not a fortune teller, It bearly has enough horsepower to keep the texture caches stright. Unneccasary loading/decompression of animation will cause a proformance hit. This would stand to reason that the animations will have to be in memory for the duration of the battle.
2) Only two animations are ever used in seqence (This makes sence later)
3) Animation is threaded round-robin via the Kernel.
4) If the animations are compressed, and you are only using two animations at at a time, and the keyframes are uncomresssed, It could stand to reason that the whole compressed file is in memory, and when you need a particular sequence, that portion is inflated.
5) It could also stand to reason that animations are cached.
So if I were a programmer, I would set up "slots" of animation data in memory. The first slot would always have the "standing" animation. (Let's call this animation the "root" animation")
If I were to issue a command in the battle menu, let's say "attack", I would want to have that animation feched, uncompressed, placed in the next availible slot, and then executed. After Attack, I will return to the root animation, the attack animation data will still be cached in that slot.
If I do a "throw" it will overwrite that last animation.
Now here a neat trick I picked up reversing FF3 (The NES one)....
Do you ever notice that when you do a summon, that your characters dissappear? This isn't an asthetic thing. What the game is doing is flushing out *ALL* the character animimation, model, and texture data to make room for the summon. This leaves the caches the only real link to quickly recreate the battlefield. In the case of FF3NES. There is only so much PPU ram. The characters had to be nuked to make way for the summon graphics. When I was playing with FF6, I noticed that it was deleting all the character graphic object data before a summon as well. In the PSX VRAM. All magic tecture caches, and the "eyeball pack" (Character textures) were deleted from there.
I would suggest you look for the compressed animation data file in memory, that may be your look up table to uncompressing the animation data into each appropoite cache.
Now about compression.
How does one compress animation? Well, it can't be mathmataclly intense, as that would lag the fetch sequence. If I was going to store only a keyframe of data, and then "garbage" after it, the "garbage" in question would only be the data I changed from the previous frame. The easiest way I can think of is to give each joint an ID and then the updated data. You could use relitive repositioning, for example [right_leg: y=+3.34, y=-2.12, z=+6.09] (Which leads to smaller numbers in the data set) or explicet new cooridinates, or a mixture of both. But I doubt that last one.
Anyway that's some food for thought. I might just be talking out my butt again. Heaven forbid I should know what I'm talking about ^_^
-
L Spiro - That is why I said what you have doesn't entirely make sense, there is no reason for them to store anything in big endian since they store everything else in little endian. It's an inconsistancy and thus quite suspect.
Hmm.. if I were to compress this data I think I would use a modified LZS alogo to do it.
In LZS the first byte indicates literal stream data and compressed.
Perhaps it's compressed using something similiar only in this case the numbers included are just the ones that changed?
It's possible they used delta compression? This does limit the rate of change per frame. Maybe 1 signed byte per value? that would give 3 + 23 * 3 bytes or 72 bytes per frame.
In any case for Barret we have
The header is 5 bytes.. I know this is a FACT why?
It has nothing to do with what Spiro has done actually it's just raw data.
The first animation section is 884 bytes in Barret, it's LENGTH is 879 bytes though, this leaves 5 bytes for the header (tada).
The first KEY frame is 110 bytes in size because 6 bytes for the offsets 4.5 * 23 for the rotations.
This leaves 769 for 19 more frames or roughly 40 bytes per frame.
Examining RedXIII we have the following information.
total size is 1720 bytes and the length is 1713 (7 bytes differrence) F is 2 (that little byte that we've been so worried about!). The interesting thought is does this make the header longer (by 2 bytes?) hmmm
The translation and none of the rotation values match Spiro's
It says there are 20 frams though :)
Doing the math the first frame should be
6 + 4.5 * 47 or 218
That leaves 78 bytes per frame
So yes the data is compressed, but how.. is not obvious.
Cyb
-
I have been a busy bee.
2 or more years ago I decided to make a program for hacking RAM since GameHack wasn’t working on Windows® XP.
Until recently it has been a fairly simple project, but it has changed from a newbie—intermediate tool to a newbie—high-end tool.
Searches and things are still simple enough for GameShark® newbies to understand, but templates are much more complicated and take time to learn how to use to their fullest.
I recommend that you (all) get this before it expires (set to one week) from the bin.
Memory Hacking Software (http://bin.mypage.sk/FILES/MemHack.zip)
So, here is what I have done.
This is the Template Editor.
(http://bin.mypage.sk/FILES/Template2.png)
As you can see, I created a very very basic template to describe Cloud’s animation set.
In RAM, only a few of his animations are loaded at a time. I found this out (not to my surprise) while making the template.
Not only that, but between animations, sometimes there are 8 bytes of space, sometimes there are 16 bytes of space, and sometimes there is no space.
Most likely this has to do with the number of animations that AREN’T loaded.
Total, this set occupies 24,080 bytes of RAM, as shown by the Template Editor.
The frames that are loaded into RAM have 20, 20, 12, 10, 6, 6, 2, and 4 total frames. I hardcoded these values into the template (as well as the number of bones Cloud has) but it is possible to set them to a value in RAM (instead of always being 20 until I change it, it will find the value in RAM and use that number to resize itself instead). If I knew where the number of bones in Cloud’s body and the number of frames per animation were stored, I could link the template to those values in RAM instead, but I don’t, so I hardcoded them into the template.
The Hex Viewer shows all of this information to me in a very easy-to-read format which can be changed to suite your needs.
(http://bin.mypage.sk/FILES/HexViewer1.png)
Because I can map the templates over RAM in real-time and see every value as I add them and modify them it is extremely easy to map objects in RAM. This whole animation set took 10 minutes.
Because I defined the parameters of a valid XYZ coordinate to be a float from -360 to 360, the Hex Viewer automatically showed me where values in RAM were not meeting those parameters (shown by red) and I could see instantly that my templates were or where not aligned properly.
What is shown in the picture is the end of Cloud’s animation set. The green line indicates the start of a new chunk. Since Cloud’s animation ends shortly before a new chunk, most likely his is the last animation of the 3 characters in my battle party. I have not verified this.
You will notice something strange about this picture.
Some of Cloud’s bones have -180.0f for rotations.
It seems it is possible for the bones to be rotated backwards, but why?
And how would they be stored in the file if they have a negative rotation?
Or is this some funky trick the Final Fantasy® VII engine does upon loading of the animations? -180 is the same as 180, so what is the point?
You should be able to see already how useful the templates are.
Soon I will add the functionality of exporting. Each data type will export as whatever you define and in any of multiple formats.
You will be able to create the final output format in the same way you use sprintf().
Currently it is possible to export that entire 24,080-byte chunk just by selecting it in the Hex Viewer and right-clicking, but when exporting a template you will have much more control over each individual data item.
This tool should help us finish off Final Fantasy® VII, and I am still working on it to make it better.
I really suggest using it. As I mentioned, putting together that animation template and following all of Cloud’s animations took only 10 minutes and helped me gain understanding of the final format when loaded into RAM.
And you can use templates to describe any format.
In a template (let’s say A), you can assign pointers to other templates (B), and then attach that template (A) to a pointer in RAM.
When doing this, the template will automatically follow dynamic objects in RAM as they move around. Animations are dynamic and are reallocated every time a new battle starts.
If I take the time to find the pointer to Cloud’s animation, I could attach this template to the pointer and not have to worry about finding his animation ever again.
One last word on templates.
I will also make the ability to wrap templates into libraries and send to other people. Currently, it is very rare to get a template working on another computer, but when I have completed that step, it will be very easy for us to share our templates and help each other dig into this game.
Here is the actual software (again)!
Memory Hacking Software (http://bin.mypage.sk/FILES/MemHack.zip)
Here is a tutorial on templates.
Template Tutorial (http://bin.mypage.sk/FILES/Templates.zip)
Here is the RAM dump (all in floats) of the actual area of Cloud’s animations.
Cloud’s Animations (http://bin.mypage.sk/FILES/CloudAnim..txt)
L. Spiro
-
That's really cool.
We however need the native format that the animation is stored in on the original media. I'm not keen on "ripping" data from a game and storing it for later use. (I.E. Let's make a game using cloud's animation. I have his animation data converted into XML we can include)
The problem is it's still a copy of the original data from the original media and a no-no to redistibute.
What you have done is nothing short of amazing though.....
-
I think it will help is break the animation format. I believe ALL of the animation data is compressed somehow, that is why REDXIII rotations are odd. I believe it's time for me to start abusing my playstation debuging software.
Cyb
-
Yes it is illegal to distribute a rip of the original and the original files.
It is not illegal for me to distribute a template library which you can use to see the animation formats as easily as I see them.
I think seeing the uncompressed format in RAM will help crack the compressed file format.
My point isn’t that we can use this to rip and then use the rips in our game(s)/tool(s). I am definitely not suggesting that. This is purely for help in decoding.
So, this program DOES allow ripping, but more usefully it allows very easy browsing of RAM. Looking at RAM is not illegal, and even if it was, that doesn’t seem to stop anyone here.
Anyway, I spent two years on this and I am still spending more. It helps a lot and I want to see it get used.
L. Spiro
-
It seems fairly simple, at least to decompress the first frame of Red XIII’s animation.
It goes by 10 bits instead of 12.
It looks like this:
Bits from 0x1B * 360 / 1024
0000000000 0.0 RXOffset
0000000000 0.0 RYOffset
0000000000 0.0 RZOffset
0000001001 3.1640625
0000000000 0.0
0000000000 0.0
0000001001 3.1640625
0000000000 0.0
0000000000 0.0
0000000000 0.0
0000000000 0.0
0000000000 0.0
0001000101 24.2578125
1111111101 358.9453125
0000000000 0.0
1111100001 349.1015625
0000000011 1.0546875
0000000001 0.3515625
1101110101 311.1328125
1100011010 279.140625
0100000111
1111111011
1010110100
1001001011
1111101111
0001001101
1111010111
0000111110
1111110101
0000000011
1101110100
0011101011
1011111001
0000000001
0010001101
01 Etc.…
The rest of the first frame matches the values I found in RAM exactly.
It seems we will have heavy rewriting to do to get our engines to display these animations.
The “u1†that has caused us so much trouble is a compression key. It can be either 0, 2, or 4, and determines whether the bitcounts are 12, 10, or 8 respectively.
Unfortunately I still can’t get past the first frame.
Using this method leaves the end at 0xCB and 4 bits.
According to RAM, the next translation is 0 266 124, which means 00 00, FE F6, 00 7C should be in RAM somewhere in that area.
But there is no FE F6. No 00 00 either.
L. Spiro
-
The “u1†that has caused us so much trouble is a compression key. It can be either 0, 2, or 4, and determines whether the bitcounts are 12, 10, or 8 respectively.
Like wowow ! I still dont get it how did you found that out ! Nice progress.
-
Heh, that isn’t all.
The first frame is never compressed, which implies all frames after use relative offsets.
After I posted I went back to the hex to verify this, and indeed what I found verifies it to the nearest 80% probability.
I began by creating a table of Cloud’s first two correct frames and then a table of the amount by which each bone changes.
The first translational offset (by file) is -466 and the next correct frame is 461, which translates to the file to be -461. The change is 5, and with his other two translations being 0 and 0, the three displacements together are 0, 5, 0.
So I went to rtda to the first byte after his first frame, and guess what I saw? 00 05 00.
I was just about to go deeper, into the rotations, when power went out. I just got back today and just now have time to post, so here it is.
Anyway, from what I gathered before losing power, the rotations are stored as offsets from the first frame as well, but the bitcount is different. It isn’t 12 or 8. I was just doing the math to check what values it could be when I was forced to stop, so now I am going to go back into it.
I don’t think this is going to take much effort, at least if everything else works as it should. And I didn’t verify the 0 5 0 combination on any other files yet (to test THEIR translational offsets for this pattern) but I had every intention of doing so until losing power.
Well, anyway, I got the clues before losing power, so, now it is time to put them together and solve this riddle.
L. Spiro
P. S. mirex, you should really start using MemHack.exe. And you know, it is only going to get better from here (as I am still adding more and more to it).
-
I have uploaded a new version of MemHack.exe (2.0.1.3).
Memory Hackong Software 2.0.1.3 (http://bin.mypage.sk/FILES/MemHack.zip)
This is because I have added a fairly helpful/important feature to it.
We can now share our templates with each other.
If anyone here maps out an area of RAM, whether it be the item list, Materia list, weapons, characters, monsters, animations, or just basic templates to help us all find information, he or she can post the template and then we can all be able to examine the RAM and either come up with solutions for solving whatever task is at hand more easily, or look over the template to see if it makes sense/describes the data accurately.
Sharing templates is similar to sharing your idea on how it “should†look, and when people put their ideas together, the final solution follows soon after.
It is true here that many things are already mapped, but in fact there are many things yet to be mapped (camera positions, anyone?).
I have not kept a tight list, but I know that animation files are still not fuly mapped, and I know that understanding how they appear in RAM is vital to unlocking them.
That is why I have made a basic (and somewhat newbie) template to describe an animation as it appears in RAM.
It can be found here (http://bin.mypage.sk/FILES/FF7AS.mhtl).
If I had found the pointer to the animation data sets, I would have wrapped that template to the pointer and then just tell the user where the pointer is so he or she can slap this template to the pointer and let the template find the animation sets on its own.
But since I haven’t, I will have to instead describe how I find the animation sets each time.
It is very easy.
Basically, we already know that each character has 3 floats for the translational offset (0, 466, 0 for Cloud). 466 (in this case) is a fairly unique float number, so I do a float search for it.
It returns only about 12 results, and from there it is easy to check each one.
When you are viewing the list of returns, you can check each one manually, but if you right-click the address in the list it will open the RAM Watcher to that address. You will see each of the 466’s, but only one of them is immediately followed by a float of 0.
That is the one that determines Cloud’s first frame of his first animation.
Go up 16 bytes and that is the actual start of that frame.
That is the address where you need to post this template.
Get to the Hex Viewer by hitting Alt-T, H.
Here is the other bad part of this template: I don’t know where the data is that determines how many bones and how many frames per animation, so I can’t make the template size itself to the animation.
If anyone else finds that information, please post an updated template.
Until then, you can adjust the template arrays to make it fit the animation you want, just as I have shown in my screenshot above.
Also, tomorrow I will update the .mhtl format to be able to accept additional text which will be displayed upon loading. That way we can include installation instructions and general notes about the template, packed into the .mhtl file (this change will not affect existing .mhtl files).
I hope this template helps to visually conceive the data in RAM, and that that helps to see how the file becomes that data, and we can crack this code.
I also hope everyone starts using this. It would be beneficial to the community as a whole, being able to share visual ideas of the data we seek.
L. Spiro
-
Sorry im kinda busy right now ... also I dont have FF7 cd's here now ... so looks like hacking PC anims its on you L Spiro.
-
Poor Mirex :)
Well I'm working on the PS1 version (using a debugger by Pixel at The Repository (http://www.romhacking.com/battleground/viewforum.php?f=12&sid=f7855c0fef595e5e6905ca8703e9c02c). I've had to do a lot of tweaking though and since it's a debugger things are, entertaining to say the least with making a tool like Spiros. I'm using XML for the basis to describe structures etc. This has an additional advantage that isn't obvious at first. I can include prior discovered structures within new structures. The hard part will be making the structure building interface. Nothing is easy as they say. Right now I have something that should work 'OK' for viewing templates in parallel with the data.
Cyb
-
I am not sure what you mean by adding priorly discovered structures into new ones.
If my understanding of that is correct, it’s the same as what mine does.
Adding a template inside of a template is the same as adding a structure to a structure.
At least that is my take on your objective.
I could be way misunderstanding, but if that IS what you mean, don’t worry about it. MemHack.exe allows as many templates added to other templates as is possible (given your hardware, RAM, etc.). They can be as recursively deep as you need.
One thing that has yet to be added is the ability to import structures from .h files, or any text files that have valid structures.
It will help a lot when you can convert your existing written-out structures automatically with a click of a button.
Also (this has been intended for a long time) I will eventually add a macro editor, so you can assign macros to data items. It will show the macro, or combination of macros, instead of the number, so it will be easier to decypher values.
L. Spiro
-
I am not sure what you mean by adding priorly discovered structures into new ones.
If my understanding of that is correct, it’s the same as what mine does.
Adding a template inside of a template is the same as adding a structure to a structure.
That works :lol:
At least that is my take on your objective.
I could be way misunderstanding, but if that IS what you mean, don’t worry about it. MemHack.exe allows as many templates added to other templates as is possible (given your hardware, RAM, etc.). They can be as recursively deep as you need.
I think you are misunderstanding this is not a program for dealing with PC programs but playstation programs (IE ones runing on an emulator). I'm just adding a memory viewer is all.
One thing that has yet to be added is the ability to import structures from .h files, or any text files that have valid structures.
Ahh so you have a parser to read that information.
It will help a lot when you can convert your existing written-out structures automatically with a click of a button.
Also (this has been intended for a long time) I will eventually add a macro editor, so you can assign macros to data items. It will show the macro, or combination of macros, instead of the number, so it will be easier to decypher values.
L. Spiro
Well the target is different, as this has nothing to do with viewing PC memory, put PS1 memory instead. Same objective however. I prefer XML for the base description because it's pretty common and interchangable (IE it can be easily used by other people). The 'MACRO' idea is a bit interesting. Especially if you get into types like those on the playstation (fixed point values come to mind).
Cyb
-
I am back... :)
Three quarters after my hard drive crash I finally was motivated enough to rewrite my source code. The only task to do till it is at the same progress as then is to add the TIM converting rountine. This is easy (look at my IOTW at ZFX (http://www.zfx.info/IOTW.php?ID=118)) but very time intensive due to the amount of code to write (palette handling, image size adjustment, FFVII specific swapping of 8-bit images and so on...).
For this reason I decided to look on animations first. But before I am going to reinvent the wheel, can you guys tell me whether you already figured something out about the PSone animation sequences?
Yes, I know that the first frame of the first animation sequence is the only uncompressed one but do you already find out the data structure of it? The posts on the last pages in this thread are confusing.
Here is a little goody for you: :wink:
(http://home.arcor.de/kislinskiy/cloud_weapons.jpg)
From left to right: Buster Sword, Mythril Saber, Hardedge, Butterfly Edge, Enhance Sword, Organics, Crystal Sword, Force Stealer, Rune Blade, Murasame, Nail Bat, Yoshiyuki, Apocalypse, Heaven's Cloud, Ragnarok, Ultima Weapon.
edit: Added link.
edit 2: Added weapon names.
-
This is what I just figured out. I assume that this is nothing new to you. :z
Animation sequences of CLOUD.LZS (24 bones incl. root bone) with a length of 16, 24, 32 and 36 bytes:
01 00 09 00 04 FE 4E FF E7 FF 50 00 FE 41 00 00
01 00 09 00 04 FF 41 FD AE FE 84 00 C1 80 00 00
02 00 13 00 04 FF CB FD D8 FF D2 CE 63 91 FF DB FF EC E0 21 5A 5E 1B 7E
03 00 19 00 04 00 9B FE 6C FC 0C 15 B8 BE 71 FF AF 40 43 F2 B5 DC 29 BB D4 04 AF B9 D3 43 00 00
03 00 1B 00 04 FE A9 FD 42 FB 79 07 1E 4A 80 6A A5 40 12 6F 75 F9 10 14 58 05 C4 0A 13 BF 8F A8
03 00 19 00 04 00 AC FE 57 FA 95 0F 0B EF 14 FF CF 40 71 B7 59 99 C0 69 F0 1E BD BE F6 B0 00 00
03 00 19 00 04 00 C9 FE 4C FB DA 0F 0B F1 6B FF B8 C0 41 F2 B2 70 C3 C1 E0 2C BD FE 46 D8 00 00
05 00 1E 00 04 FF 82 FD 16 FC F7 E3 89 81 01 01 76 44 80 40 9D A2 0F CF A2 92 A2 02 9A 60 15 56 71 EE E8 00
03 00 1C 00 04 FE D7 FD 69 FC B7 FA 1F 35 80 64 86 7F E8 37 7D 56 FA 02 47 00 4F 80 F7 DF A7 EF C1 00 00 00
Analyzing this data let me assume the following file structure:
ushort num
ushort length
byte unknown
byte[length + pad bytes] compressed data
Notice on pad bytes: Files in a LZS archive have to be 4 byte aligned.
num is a count of something. I see that you guess this is the frame count. Are you sure?
An empty animation sequence has a length of 4 bytes and consists of num (0x1A30) and length (0x0000) only.
-
Kislinskiy
Num I believe is the frame count, however 0x1A30 has bothered me for a while, WHAT is it? I've asked myself, on the empty animations. My Guess is this is an impossibly long length.
The first frame also is NOT UNCOMPRESSED, just to let you know. The whole sequence is compressed, this is why some of the characters won't look right when you use the first frame of the first animation sequence. Section1 I am positive has something to do with the animation, I just haven't figured it out.
One of CID's animation sequences is only 11 bytes long this is not enough for a single uncompressed frame even (it is a one frame animation however). It might be they use the first frame of the first animation sequence to start all of them, however the compression technique used will take a bit to figure out, I believe. If you display the first frame of REDXIII you'll find he's been playing twister. This first frame is compressed in some way as I said.
It doesn't appear to be LZS I don't think they would use LZW because it has large memory requirements huffman and shanno fano compression are complicated bitwise compression techniques and slow, unless they found a way to use the MDEC to decode the animations somehow on the playstation. It might be the LZS compression bytes are somewhere else, but unlikely. Delta sigma is possible but has a bit too much overhead. Then there is the 3 16bit offset values.
Cyb
-
Is it gzip/zlib? Or do they not use a 360 degree system?
-
What the-
The first frame is not compressed.
I posted this earlier.
That “u1†byte is a “compression code†for the first frame (and may also have meaning on all frames after).
It determines the number of bits in each rotation is 12, 10, or 8.
THAT is why Red XIII’s animation looks twisted.
“u1†can be either 0, 2, or 4, and the formula for the bitcount per rotation is (12 - u1), which means the bitcount for (u1 = 2) is 10.
Red XIII’s animations have only 10 bits per rotation (on his first few, and then some with only 8).
But regardless of the u1 value, the translations are always 2 bytes each, and for some reason they are in reversed byte order and they are also inverted (-466 is actually 466, and 264 is actually -262).
When translating Red XIII’s animations using 10 bits per rotation instead of 12 you get the following table (which I posted already).
Bits from 0x1B * 360 / 1024
0000000000 0.0 RXOffset
0000000000 0.0 RYOffset
0000000000 0.0 RZOffset
0000001001 3.1640625
0000000000 0.0
0000000000 0.0
0000001001 3.1640625
0000000000 0.0
0000000000 0.0
0000000000 0.0
0000000000 0.0
0000000000 0.0
0001000101 24.2578125
1111111101 358.9453125
0000000000 0.0
1111100001 349.1015625
0000000011 1.0546875
0000000001 0.3515625
1101110101 311.1328125
1100011010 279.140625
0100000111 Etc.…
1111111011 Etc.…
1010110100 Etc.…
1001001011 Etc.…
1111101111 Etc.…
0001001101 Etc.…
1111010111 Etc.…
0000111110 Etc.…
1111110101 Etc.…
0000000011 Etc.…
1101110100 Etc.…
0011101011 Etc.…
1011111001 Etc.…
0000000001 Etc.…
0010001101 Etc.…
01 Etc.…
The formula changes from (X * 360 / 4096) to (X * 360 / 1024) because the maximum number for 10 bits is 1024.
You can decode Red XIII’s entire first frame this way and it is not compressed.
It just has a different decoding key (u1).
L. Spiro
-
That sounds more logical. I can not imagine that animation data should be compressed with an algorithm again. The pad bytes in such a stream also indicate length variable values.
-
Here is an example. This is the 3rd file in CLOUD.LZS. The first animation file without that yet unknown header.
The rotation values with a resolution of 12 bits start at offset 0x5FAD.
The first rotation triple is (000; 0FE; 2E0).
Bone 0: Name: rtam, Parent: -1, Children: 3, Rotations: 0.00000000 0.00000000 0.00000000 Translating: -39.00000000
Bone 1: Name: rtan, Parent: 0, Children: 1, Rotations: 270.00000000 333.10546875 0.00000000 Translating: -163.00000000
...
Related to this post the first rotation value would start at offset 0x5FB3 [(000; 000; 000), (C00, ECE, 000), ...] and ignore the 1st 4 12-bit values. Why? - Could it be that those values are the position/translation of the root bone to handle model movement? PSone coordinates of the battle models are stored in 4 values too. Just a thought.
(http://home.arcor.de/kislinskiy/cloud2.gif)
-
Kislinskiy, I redid the animation structure.
The header of each animation is only 5 bytes long after the block_len and looks like this:
struct s_FF7AAanimHdr {
unsigned long rec_a; //0
unsigned long frames_1; //4
unsigned long block_len; //8
unsigned short frames_2; //12
unsigned short real_data_len; //14
unsigned char bit_count_key; //16
} FF7AAanimHdr; //size = 17 bytes
For every animation file, the first animation DATA starts on 0x15.
The next 6 bytes are part of the first animation frame and they are reverse-ordered inverted unsigned shorts (3).
On Cloud it is:
00 00 = 0
FE 2E = 466
00 00 = 0
Then the rotations follow, with the first rotation being the root bone, and it is not counted as part of the total bones of the animation.
Those 6 bytes plus the root bone plus the model bones are all part of the first frame.
After that things are most likely stored in some form of relational offset of the first frame.
Cloud’s certainly seems that way but Barret’s definitely doesn’t.
So it is most likely another bit-length problem.
L. Spiro
-
Related to this post the first rotation value would start at offset 0x5FB3 [(000; 000; 000), (C00, ECE, 000), ...] and ignore the 1st 4 12-bit values. Why?
The next 6 bytes are part of the first animation frame and they are reverse-ordered inverted unsigned shorts (3).
On Cloud it is:
00 00 = 0
FE 2E = 466
00 00 = 0
Ah, ok. Do you already know what these three values do represent? Perhaps the position/translation of the model as I assumed in my last post?
-
They are a translation for each frame.
But they are stored in a strange and illogical way.
00 00 = 0
FE 2E = 466
00 00 = 0
Why?
Well, FE 2E actually equals 12030.
But 2E FE equals -466 (signed).
In order to get the final final result, this number must then be subtracted from 0.
-466 becomes 466. That is the first translational Y offset of Cloud’s first frame of his first animation.
Also, subtracting the number from 0 only applies to the Y.
The others still need to be reversed (bytewise) but not subtracted from 0.
So, changing these values moves his whole body to whatever position.
The same applies for the first set of rotations (the root bone).
Changing the first rotation will rotate the entire model by the new amount.
L. Spiro
-
I have problems with the correct rotation. Can someone post an image of the first frame of the first animation of ENEMY012.LZS please?
How do you calculate the position of a bone's child? I store the bone length at an identity matrix's z-element (element 43 in DirectX) and multiply that matrix with a matrix containing the bone rotation. Now I store the x-, y- and z-element in a vector and add it to the bone's position. This new vector represents the position of the child.
Due to FFVII uses another coordinate system I have trouble creating the correct rotation matrix.
-
Here is what I got, Note joints are RED and Bones are blue.
Cyan Magenta and Yellow are the X Y Z axis.
(http://bin.mypage.sk/FILES/ENEMY012_01.jpg)
Cyb
-
I don’t have that file but when rotating you have to rotate in the exact order: -Y, X, -Z.
DirectX® matrices aren’t like OpenGL®’s and translating along the Z by the length of the bone does not work the same way.
In fact, rotating as I mentioned above won’t work in DirectX® either.
OpenGL® uses degrees while DirectX® uses radians for one.
But if you know the math to transform your matrices then I won’t post beyond that.
L. Spiro
-
Thanks to both of you. :)
@L. Spiro
I totally forgot that DirectX uses radians. (http://www.areaforen.de/axb/images/smiles/wallbash.gif)
@Cyberman
Can you post EMENY041 please? The last one, I promise. :wink: I think it is more suitable to compare...
My models are twisted.
edit: After analyzing ENEMY165 and ENEMY166 I guess I am a victim of Gimbal Lock... I recode my rotations using quaternions now... -_-
ENEMY041
(http://home.arcor.de/kislinskiy/ENEMY041.jpg)
-
OK, now I use quaternions to prevent Gimbal Locks. But that obviously was not the problem. The problem seems to occur on joint->bone only. There is almost evertime a "90 degree fracture". In addition some model parts are swapped (right arm should actually be left arm etc.).
ENEMY166
(http://home.arcor.de/kislinskiy/ENEMY166.jpg)
ENEMY320
(http://home.arcor.de/kislinskiy/ENEMY320.jpg)
-
Concerning your reversed models issue, it isn’t just some models that are on the opposite sides of where they should be, it is ALL.
The only reason SOME of them DON’t appear to be on the wrong side is because they are symmetrical.
This isn’t a problem when loading the models in OpenGL® but in DirectX® you have to load the models with -Z and -Y vertices/normals.
By this, I mean ONLY the 3-D model files. Not the bones, not anything else.
And be sure to remember to load the normals this way also (which of course does not apply to battle models).
The result of this is that the models will stay on the wrong side, but they will be reversed, so the wrong side becomes the correct side.
This means your models will be perfect mirrors of the originals.
L. Spiro
-
Why +X-Y-Z and not +X+Y-Z? The only difference between a left-handed and a right-handed coordinate system is the direction of the Z-axis. I confusingly get the correct result with +X-Y+Z. Probably only apparently due to wrong rotation. Do you have this "90 degree fractures" too? One more time please, YOU (using OpenGL) convert the rotation values XYZ to ___ and rotate in the order ___.
(http://www.cs.uregina.ca/Links/class-info/405/WWW/Lab3/lab3fig5_1.jpg)
-
In OpenGL®, the code is as follows:
glRotatef( -fY, 0, 1, 0 );
glRotatef( fX, 1, 0, 0 );
glRotatef( -fZ, 0, 0, 1 );
This is for rotations/bones.
Rotated first by -Y, then X, then -Z.
As for the 3-D models, reversing only the Z does not work.
Aside from changing the cull order (a minor problem), the objects become backwards. Cloud’s head, for example, points back.
But I am sure if you manipulate the bones correctly, you can make the joints go the right directions to make everything dandy.
If you did that, the obect wouldn’t be mirrored horizontally (though it may be mirrored vertically).
I will personally pursue this matter to see if there is a winning combination for the bone rotations to counter the affects of only inverting the Z.
As for 90-degree fractures, I have never had that.
L. Spiro
-
I sware, Mirex
If you put an option to export models in Leviathon... :D
-
Matrix Transformations Are Your Friends
...? :o
-
I sware, Mirex
If you put an option to export models in Leviathon...
Its not needed, Unmass & Biturn can export everything you see in Leviathan. Check them out.
-
Yeah well i spent about 4 hours just trying to export cloud 2 a 3ds max file :x Yeah not so easy for me... Maybe someone could upload a few of the famous characters?
-
Try looking into this thread FF7 models to 3ds Max (http://forums.qhimm.com/viewtopic.php?t=2819) for some hints.
-
(http://home.arcor.de/kislinskiy/earith.jpg)
There is still an error in my recursive rotation algorithm. How do you exactly rotate the bones?
I store a matrix in every bone class containing the rotation of the bone.
Matrix = Matrix.RotationAxis(0, 1, 0, -y)
Matrix *= Matrix.RotationAxis(1, 0, 0, x)
Matrix *= Matrix.RotationAxis(0, 0, 1, -z)
My recursive RenderBone Method looks like this Pseudo Code:
RenderBone(Bone bone, Rotation rotation, Position position)
{
rotation *= bone.Rotation
World = rotation
World *= Matrix.Translation(position)
Render()
Matrix matrix = Matrix.Translation(0, 0, bone.NegativeLength)
matrix *= rotation;
position.Add(matrix.Tx, matrix.Ty, matrix.Tz)
if(!bone.IsLeaf)
foreach(Bone child in bone.Children)
RenderBone(child, rotation, position);
}
RenderBone(rootBone, Matrix.Identity, Vector3.Origin)
Rotations, coordinates etc. in this post are in OpenGL format. Bone length is -z.
-
Your setup is completely different from mine so my code will not help much, but I will post it anyway.
VOID FF7Model::AttachBones( LPDIRECT3DDEVICE9 pd3dDevice ) {
mDXStackPointer = 0;
float tempXr, tempYr, tempZr;
dxLoadIdentity();
for ( int I = 0; I < m_iBones; I++ ) {
if ( m_pBone[I].GetParentIndex() == -1 ) {
dxPushMatrix();
dxTranslatef( m_fXTrans, m_fYTrans, m_fZTrans );
tempXr = m_pBone[I].GetXRotation();
tempYr = m_pBone[I].GetYRotation();
tempZr = m_pBone[I].GetZRotation();
dxRotatef( -tempYr, 0, 1, 0 );
dxRotatef( tempXr, 1, 0, 0 );
dxRotatef( -tempZr, 0, 0, 1 );
m_pBone[I].SetMatrix( mDXMatrixStack[mDXStackPointer] );
dxTranslatef( 0, 0, -m_pBone[I].GetLength() );
for ( int J = 0; J < m_pBone[I].GetTotalChildren(); J++ ) {
AttachSubBones( m_pBone[I].GetChild( J ), pd3dDevice );
}
dxPopMatrix();
}
}
}
VOID FF7Model::AttachSubBones( int iIndex, LPDIRECT3DDEVICE9 pd3dDevice ) {
float fTempXr, fTempYr, fTempZr;
fTempXr = m_pBone[iIndex].GetXRotation();
fTempYr = m_pBone[iIndex].GetYRotation();
fTempZr = m_pBone[iIndex].GetZRotation();
dxPushMatrix();
dxRotatef( -fTempYr, 0, 1, 0 );
dxRotatef( fTempXr, 1, 0, 0 );
dxRotatef( -fTempZr, 0, 0, 1 );
m_pBone[iIndex].SetMatrix( mDXMatrixStack[mDXStackPointer] );
dxTranslatef( 0, 0, -m_pBone[iIndex].GetLength() );
for ( int J = 0; J < m_pBone[iIndex].GetTotalChildren(); J++ ) {
AttachSubBones( m_pBone[iIndex].GetChild( J ), pd3dDevice );
}
dxPopMatrix();
}
Here is what you need to know about this code.
I store temp variables for each XYZ rotation, taken from m_pBone.GetXRotation();. GetXRotation() returns the animation rotation for that bone and the animation’s current frame (GetXRotation() returns specifically the X, obviously).
That part explains itself.
I have two functions.
AttachBones() is not recursive; it only walks the root bones.
Any time a root bone has children, it calls AttachSubBones(), which in turn calls itself recursively on all children of that bone’s children.
The matrices need to be pushed and popped correctly to get the correct results, and this is also why there are two seperate functions to handle the walking.
The first function sets up the matrices to their default values, which needs to be done only once (instead of once per recursive call).
The bone rotations don’t carry over by multiplication. They carry over by leaving the world in the same spot as it was when it processes the parent bone (which goes into pushing and popping correctly). Every subsequent rotation and translation is performed from there.
Each bone uses SetMatrix() to store that matrix into the bone itself, so that when it comes time to draw, the world will be set to the stored matrix and the object drawn there.
L. Spiro
-
Just an update on my own project’s progress.
http://bin.mypage.sk/FILES/Enemies.zip
Looking good so far and I am really happy with the results.
The cyclerate in each of those pictures is over 100 with 1280×1024×32 resolution and 6×anti-aliasing.
Though most monitors don’t update that often, so the framerate you SEE is not 100.
I am almost able to put out a playable demo once we figure out these animation file formats.
My project’s official name is “Something Something VII Online†and as you can guess from the shots and the name, it is a “mod†that allows Final Fantasy® VII to be played online.
But I am keeping it mostly underground for now. Let’s not talk TOO much about this, okay?
I talk about it here and there, and release some shots sometimes, but that should be fine as long as it stays on a low level.
I have a demo already ready for testing but it seems no one has the game installed AND has DirectX® 9.0c.
But we really need to work on this animation format so I can get an online Battle Square type demo going. Just battles against people and monsters, enforced and run by the server.
Well I am working on this a lot lately but I will be back on the animation formats soon.
Until then, who else is working on them?
L. Spiro
-
The cyclerate in each of those pictures is over 100 with 1280×1024×32 resolution and 6×anti-aliasing.
Though most monitors don’t update that often, so the framerate you SEE is not 100.
This is really cool. What about burning some of the unused fillrate by adding stencil or depthmap shadows?
-
Hey guys this is code from Leviathan, for displaying the models. Its in OpenGl. Model coordinates & rotations are in default order (i mean not swapped or anything). Hope it helps.
void CF7BwDlg::GlDisplayBoneChildren( int bone_parent )
{
int b;
float f;
for( b=0; b<skelet.bones; b++ )
if (( skelet.bone[ b ].parent == bone_parent ) &&
( skelet.bone[ b ].displayed == false )) {
glPushMatrix();
glRotatef( skelet.bone[ b ].roty, 0.0f, 1.0f, 0.0f );
glRotatef( skelet.bone[ b ].rotx, 1.0f, 0.0f, 0.0f );
glRotatef( skelet.bone[ b ].rotz, 0.0f, 0.0f, 1.0f );
if ( ! m_skel ) {
//displaying skeleton
glBegin( GL_TRIANGLES );
f = skelet.bone[ b ].length / 10;
glColor3f( 1.0f, 0.8f, 0.8f );
glVertex3f( f, 0.0f, 0.0f );
glColor3f( 0.8f, 1.0f, 0.8f );
glVertex3f( -f, 0.0f, 0.0f );
glColor3f( 1.0f, 1.0f, 1.0f );
glVertex3f( 0.0f, 0.0f, skelet.bone[ b ].length );
glColor3f( 0.8f, 1.0f, 0.8f );
glVertex3f( -f, 0.0f, 0.0f );
glColor3f( 0.8f, 0.8f, 1.0f );
glVertex3f( 0.0f, f, 0.0f );
glColor3f( 1.0f, 1.0f, 1.0f );
glVertex3f( 0.0f, 0.0f, skelet.bone[ b ].length );
glColor3f( 0.8f, 0.8f, 1.0f );
glVertex3f( 0.0f, f, 0.0f );
glColor3f( 1.0f, 0.8f, 0.8f );
glVertex3f( f, 0.0f, 0.0f );
glColor3f( 1.0f, 1.0f, 1.0f );
glVertex3f( 0.0f, 0.0f, skelet.bone[ b ].length );
glEnd();
}
if ( ! m_model ) {
//display model
if (( skelet.bone[ b ].model_bound ) &&
( skelet.bone[ b ].model_data_set ))
glCallList( skelet.bone[ b ].partId );
}
skelet.bone[ b ].displayed = true;
glTranslatef( 0.0f, 0.0f, skelet.bone[ b ].length );
GlDisplayBoneChildren( b );
glPopMatrix();
}
}
-
I'm not sure there is anything in this that you guys haven't already replicated in your own viewers, but what the heck....
Here is the binary and source to my own OpenGL-based model viewer for FF7 PSX that I wrote:
http://www.virtualdub.org/other/ff7view.zip
http://www.virtualdub.org/other/ff7viewsrc.zip
As compiled it will expect EARITH.BIN and CLOUD.BIN in the current directory or it will crash (decompress EARITH.LZS and CLOUD.LZS to get these). It will then load and display Aerith, and you can adjust the skeleton. The keys are something like (a)ntialias, (w)ireframe, (t)ranslate, f2/f3 to load and save, (i)k mode, space to switch axes, and [ and ] to change bones. The viewer knows how to load the models as well as the first frame of 12-bit coded anims. There's some really ratty export-to-DXF code in there as well although I don't think it ever worked that well since it couldn't export vertex colors.
Obviously, the viewer isn't polished; I wrote it to make a really high quality image for a T-shirt of Aerith hugging Cloud.