o.0 that was fast! And yeah feel free to upload to the model resource. I'll play around with the source tomorrow to merge my bone and weight tests into the models. And add a download button. Shouldn't be too much of an overhaul, mostly just a matter of trying to add it into my hacked-together source code from what I originally wrote.
Edit: And to sort out my brain I'll go ahead and information dump on this thread. Since the meshes are pretty complete and have a pretty good idea of where the bones are, I started looking into animations. Specifically the chest, since it's the simplest for testing purposes. It only has two primitives. And three states, shut, open, and partially closed. The way EBD files work is they have a list of all of the scene actors in a list. So it looks like enemies, npc's, bird and even things like explosions and zenny are in there as well. The start of the EBD file gives the number of actors in the scene, and then for each actor there are four attributes, a flag, a pointer to the mesh, a pointer to the bones and a pointer to the animations. I'm fairly familiar with the mesh at this point, so the next step is to try and look into the other two. And to that effect I traced out the file formats for the animation and bones. The animation one is actually pretty simple and doesn't exactly contain any animations. The file can be viewed here:
docs.google.com/spreadsheets/d/1q8Oe-E-zdTs0DgGreuTcOGr8Y-lBdwOULkG_wetICt4/edit?usp=sharingAnd for the lazy:
Basically at the top in yellow, there are three pointers to the file. 0x0C points to the green section. 0x14 points to the blue section and 0xac points to the purple section. It looks kind of complicated at first, but if we take a look at the blue part, the first byte starts off at 0x00 and goes up to 0x12 (or from 0 to 19 in decimal). Since it's sequential, it's probably the frame number. And following it is always 0x01, which since only the top of the chest (primitive 1) and not the base (primitive 0) moves we can assume this is the bone number. And the last thing that we can notice for each green blue and purple section is that it ends with 0xff (-1, or 255) often used for signaling the end of something in binary. So let's compare this to the bone file, which I have outline here:
docs.google.com/spreadsheets/d/1r-yEK6Xf3FAPXl9RR0UXqJ7rh6vJ2b7MvHBUzzqbXlo/edit?usp=sharingAnd for the lazy (had to down scale to 90% to fit it):
This one might be a little harder to explain as I didn't color code it, but we'll give it a shot. Basically pointers are in yellow, data is in green. So at the top there are four pointers. The first pointer is to the green section right under it. These are the bones for the actual mesh. It looks like the game doesn't use rotation, only position. So basically it's [x 2 byte short][y 2 byte short][z 2 byte short][nop 2 bytes] for each bone. And another thing to mention is that the game seems to ignore the position for the first bone, even if it's set. But in this case we have 0,0,0 for the base bone, and 0,y value,0 for the second bone. So something we would expect since we have the top of the chest sitting on the base of the chest.
Getting back to the pointers at the top, we have one to the yellow section at 0x24, one to the yellow section at 0x34, and one to the yellow section at 0x1b0. So since the animation file didn't actually have any animation, we can compare it with this and we what we get. Well the blue section in the animation file had 19 frames, so when we compare it to the number of pointers in the 0x34 section, we get 19. Cool. And in the purple section we had 17 frame, and if we compare it to the number of pointers at 0x1b0, we get 17. Cool. And lastly we had one frame in the green section and now we have one frame at the 0x24 that has all zero's. So we can form the hypothesis that the first animation information is when the chest is unopen. The second animation contains 19 frame when the top of the chest rotates around the x axis to open. And then the final 17 frames are when the chest closes and stops such that it is still partially open.
So for testing in the game my method is actually pretty crude. I have two sets of the game files. One is the files extracted individually from the game disk and stored directly as files. And the focus is mostly on the CDDAT/DAT directory, which allows me to look at the files and parse out information. For actual testing with the game, I have the disk as a .cue, .bin file as the .bin file is the binary data ripped directly from the disk and the files are all intact and can be edited in the .bin file and run from an emulator directly. So for instance, now I'm working with the file ST09_00.BIN, which is the ruins in front of the arcade. I can then search for that in the bin file, edit and then run the emulator. So what we want to do is write different information to the resting chest and then see what happens.
Hint, this happens:
The full album for my trial and error can be found here:
imgur.com/a/zaAe4To provide a summary, the first several bytes seem to be for the x,y,z position of the base bone and move the entire model when changed. Following that is the x,y,z rotation for the base bone, so the entire model is rotated in one direction or the other when changed. After that is the x,y,z rotation for the top mesh bone alone. Two interesting things to point out is that one, is seems that position is provided only to the base bone, and there is only rotation any bone other than the root bone. And another thing to mention is that there seems to be an inconsistency with the byte use for each transformation. For example one the root bone, both the x and y position transformations work with 2 bytes, but the z position and x rotation seem to be one byte each. Likewise with rotations for the top of the chest seemed to be one byte per axis. Right now I'm just hoping they didn't do something retarded like use 10 bytes and mash them together, as parsing that out wouldn't be too much of a problem, but testing for it would be a pain.
That aside I've only scratched the surface. And the other issue is that even after parsing out the game data, getting it to play nice with three.js still requires trial and error. So I might as well check my sanity at the door.
Edit:
More information when testing with animations. I decided to work with Data the Monkey's animation since it repeats and continues when you talk to him, so it's a lot easier to observe than a lot of other animations. The full outline file is on drive here:
docs.google.com/spreadsheets/d/1LKamhnQvSEQY8DLNUWLIS9MUh6p4CM6Gg0SeMtxn_cI/edit?usp=sharing and a quick picture of what I'll be talking about is here:
Most of the time animations end with 0xFF, like the one labeled "end" at the top. Data has one that ends with 0x80. So the first thing I did was hex-edit the animation from 0x80 to 0xFF, and the animation played once and Data stopped on the last frame. So in the game 0x80 at the end represents and repeating animation and 0xff represents a single play animation. The first byte on the front of ever other dword is the animation number. So in this case Data has 0x42 or 66 frames for his dance animation. To play some more I decided to see if I could loop the animation early, so I changed frame 5 from 0x05010000 to 0x05010080. And this was the result:
And this causes Data to loop the first five frames of his animation and repeat. So the next step is to start commenting things out to see if I can find which values represent translations and rotations, and for what bone.
Edit:
Isolated Y animation of root bone for Data animation:
Isolated X animation of root bone for Data (injected):
The problem with this is for the chest, the x-axis translation was two bytes, where-as with Data it seems to be one byte.
Single Byte Data Root Bone Z Translation:
Two Byte Data Root Bone Z Translation:
Which is really weird, since for Chest, x was 2 bytes, y was 2 bytes and z was 1 byte. And for Data, x is one byte, y is two bytes and z is two bytes. So the next step is to try to set a range of values for x and see about what range of values the game expects.
Edit:
Some tangible progress for anyone following along (nobodies following. I've already accepted that I've lost my sanity and am just talking to myself). I've found that the programmers used 12 bit for translation. I have really no idea why since I think there should be enough room on the disk with sixteen. But what ever 12-freaking-bits, that explains why something were single bytes and somethings were two bytes in my previous testing as somethings just crossed that four byte boundary as I was testing.
So the way I tested this was to assume that the game uses signed bits. Since the animation needs to go in the plus and minus directions on an axis, the most significant bit is going to mark the direction positive or negative. So first I took the animation and replaced everything with 0 so that Data the Monkey didn't move at all for his looping animation. Then I tested in the x-direction one bit at a time to see how he moved. So 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, and 0x80, each time Data moved a little further to the right. So I went onto the next byte, 0x0180, 0x0280, 0x0480, and at 0x0880, I got this:
Data jumped from really far to the right to inside the bushes, really far on the left. So the next step is to see what happens with y and z translations to see if they all use 12 bits. And then start working on rotation to first how many bits they use, and secondly which values correspond to how many radians.
Edit:
Did more testing with Data's animation and confirmed that x, y, and z all use signed 12 bit values. X-axis is to the right unsigned, left signed. Y-axis is down unsigned and up signed. Z-axis is backwards unsigned and forward signed.
Edit:
After more testing found the values for rotation. Looks like they also use 12 bits like translation. The most significant bit 0x800 is 180 degrees and the second most significant bit (0x400) is 90 degrees. So there's no signed or unsigned, basically 0xFFF is 360 degrees and you just divide by that.
Edit:
Needs some more testing to be certain, but I think I have a decent idea of the structure for each animation frame.
Each value is twelve bits or 1.5 bytes insize. Translation X,y,z are appended onto the beginning of each frame, and then it's rx, ry, rz for each bone after that. In this case seven bones (0 - 6), Data himself has eight bones, but the last bone is his face so that's probably why it's been left out. The list of Data's bones is as follows:
0 - Body
1 - Head (without face)
2 - Right Arm
3 - Left Arm
4 - Right foot
5 - Left foot
6 - Tail
7 - Face
Edit:
Never mind, looks like there was translation for Data's arm. But there wasn't any translation on the head. So it could be something to do with the parent-child structure of the bones? And there only being nine dwords per animation frame is still throwing me off. Seems like too few. I'll have to be more careful with my notes and keep going.
Edit:
Never mind again. Looks like I was right the first time. After more testing it looks like I mistook Data's arm rotating around his body for translation. Test looked something like this:
08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation x
80000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation x
00080000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation x (msb)
00800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation y
00000800 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation y
00008000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation y (msb)
00000008 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation z
00000080 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation z
00000000 08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 translation z (msb)
00000000 80000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation x
00000000 00080000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation x
00000000 00800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation x (msb)
00000000 00000800 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation y
00000000 00008000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation y
00000000 00000008 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation y (msb)
00000000 00000080 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation z
00000000 00000000 08000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation z
00000000 00000000 80000000 00000000 00000000 00000000 00000000 00000000 00000000 bone 0 rotation z (msb)
00000000 00000000 00080000 00000000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation x
00000000 00000000 00800000 00000000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation x
00000000 00000000 00000800 00000000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation x (msb)
00000000 00000000 00008000 00000000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation y
00000000 00000000 00000008 00000000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation y
00000000 00000000 00000080 00000000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation y (msb)
00000000 00000000 00000000 08000000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation z
00000000 00000000 00000000 80000000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation z
00000000 00000000 00000000 00080000 00000000 00000000 00000000 00000000 00000000 bone 1 rotation z (msb)
00000000 00000000 00000000 00800000 00000000 00000000 00000000 00000000 00000000 bone 2 rotation x
00000000 00000000 00000000 00000800 00000000 00000000 00000000 00000000 00000000 bone 2 rotation x
00000000 00000000 00000000 00008000 00000000 00000000 00000000 00000000 00000000 bone 2 rotation x (msb)
00000000 00000000 00000000 00000008 00000000 00000000 00000000 00000000 00000000 bone 2 rotation y
00000000 00000000 00000000 00000080 00000000 00000000 00000000 00000000 00000000 bone 2 rotation y
00000000 00000000 00000000 00000000 08000000 00000000 00000000 00000000 00000000 bone 2 rotation y (msb)
00000000 00000000 00000000 00000000 80000000 00000000 00000000 00000000 00000000 bone 2 rotation z
00000000 00000000 00000000 00000000 00080000 00000000 00000000 00000000 00000000 bone 2 rotation z
00000000 00000000 00000000 00000000 00800000 00000000 00000000 00000000 00000000 bone 2 rotation z (msb)
So yeah, it's translation on the base bone followed by rotation for each individual bone.
Edit:
IT'S ALLIIIIIIIIIIIIIIVVVEEEEEEEEEEE!!!!!!!!!