Z64

Please login or register.

Login with username, password and session length
Advanced search  

News:

Check out and improve the wiki!

Author Topic: Actor joints & matrix & RAM segment shit cracked  (Read 14956 times)

xdaniel

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 295
    • ICQ Messenger - 136250978
    • View Profile
Actor joints & matrix & RAM segment shit cracked
« on: February 05, 2013, 12:12:46 AM »

Crossposting from GCN, http://www.the-gcn.com/topic/1993-actor-code-animation-and-matrices-ram-segments/?p=30251

Documentation etc. forthcoming, as mentioned below.

Quote
Well, EX-FUCKING-CUUUUUUUUSE ME, PRINCESS!
 




And for the moment, I'm so unbelievably sick of matrices, RAM segments, overlay files and all the other shit. Taking a bloody well-deserved break of this for a day or two or three.

Quote
I guess program and source code are forthcoming, but don't expect clean code - the program's was was supposed to become "ZSaten2", but turned into a testbed of sorts when I started work on SorataVSE (see other threads). I will also document this properly, as opposed to just leave it at the code; here's the gist of it, as program/source release and proper documentation will take a bit longer:
 
The "magic" is basically creating the contents for RAM segment 0x0D at runtime, which holds the matrix data for each limb that has a display list attached. I'm preparing the segment by parsing the hierarchy in advance before actually rendering the model. The basic modelview matrix is identity multiplied with the global translation (the first 3 shorts in the rotation index data), then the limbs are parsed starting at #0 and address 0 in segment 0x0D.
 
The limb parsing function makes a local copy of the previously loaded matrix - so at limb #0 the aforementioned (identity * global translation), at the first child (identity * global translation * limb #0), etc., at the first sibling (identity * global translation), and so on - and then generates the current limb's matrix based on its translation and rotation values (depending on selected hierarchy, animation and frame number). Now, if the current limb has a display list to be rendered, it writes the current matrix to the current address in segment 0x0D and then increases the address by 0x40; if it's not supposed to be rendered, the matrix is not written to the segment, the address not increased. Lastly, if there is a child, the function recursively calls itself again, with this limb's matrix as a parameter, to parse the child, and if there's a sibling, it calls itself with the previous matrix as a parameter.
 
The matrix data's format as written to segment 0x0D is explained in the Functions Reference, on the gSPMatrix page.
 
Now the actor's display lists that use gSPMatrix (0xDA) commands - so those with joint vertices connecting two limbs - will happily read the matrix from the segment, which can then be used to transform the vertices loaded by gSPVertex (0x01) commands. My ucode interpreter library thingy has a matrix stack, which is filled/emptied by gSPMatrix and gSPPopMatrix, the matrix at the top of which is taken whenever a vertex gets loaded and applied to the vertex position.
 
What I'm also doing to get any actor display lists to render that do not contain gSPMatrix commands - ex. the whole Stalfos, Saria's body and head, Zelda's body, head and boots if I recall - is that, right before a display list is given to the interpreter library for parsing/rendering, the corresponding matrix is manually pushed onto the matrix stack. Display lists without gSPMatrix commands get the correct matrix, while those with them will get the limb's matrix, then (usually) directly load another limb's matrix for the joint vertices, then reload its own limb's matrix again for the rest of the display list. No need for manual glTranslate/glRotate/glPushMatrix/glPopMatrix in OpenGL, as used in ZSaten and likely every other viewer as well as described on the wiki, anymore.
 
Whew, hope that's making some sense already... again, program, source and some better documentation (probably with an example or so) coming a little later, next week or so at the latest - I hope.

EDIT with download:
Quote

 
Download: http://magicstone.de/dzd/random/ZSaten2-POC.rar
 
Program & library binary (\ZSaten2\ZSaten2\bin\Release\), program source. No library source yet, still very much WIP and will instead be released with SorataVSE in presumably a few months. Potentially buggy proof-of-concept, read and heed the Help/About message.

EDIT, Dark Link fix:
http://magicstone.de/dzd/random/ZSaten2-POC-b.rar
« Last Edit: February 06, 2013, 04:21:46 PM by xdaniel »
Logged
cu xdaniel

Nanami - Desktop:

Kazari - Notebook:

spinout

  • Administrator
  • Sr. Member
  • *****
  • Posts: 309
    • View Profile
    • Email
Re: Actor joints & matrix & RAM segment shit cracked
« Reply #1 on: February 11, 2013, 05:05:23 AM »

Me like. Makes me wish I had more time to play with this game.
Logged
biggrin.gif

SoulofDeity

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Actor joints & matrix & RAM segment shit cracked
« Reply #2 on: February 15, 2013, 10:26:26 PM »

lol, I had completely forgot I made an account on this site until I saw xdaniels post on glitchkill.

Anyway, exactly what does segment 0x0D point to? The actor, the matrix stack, or what? And do you set segment 0x0C to the actor file as well in your renderer?
Logged

xdaniel

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 295
    • ICQ Messenger - 136250978
    • View Profile
Re: Actor joints & matrix & RAM segment shit cracked
« Reply #3 on: February 15, 2013, 11:06:47 PM »

As I said in the post I quoted: "The "magic" is basically creating the contents for RAM segment 0x0D at runtime, which holds the matrix data for each limb that has a display list attached." Segment 0x0D isn't static data, but matrix data that's generated from the limb positions according to the current hierarchy, animation and animation frame.

The matrix data format is described in the Functions Reference: http://naesten.dyndns.org:8080/psyq/man/gsp/gSPMatrix.html

As for segment 0x0C, I don't set it anywhere IIRC, for what is it used again?
Logged
cu xdaniel

Nanami - Desktop:

Kazari - Notebook:

SoulofDeity

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Actor joints & matrix & RAM segment shit cracked
« Reply #4 on: February 15, 2013, 11:52:55 PM »

As I said in the post I quoted: "The "magic" is basically creating the contents for RAM segment 0x0D at runtime, which holds the matrix data for each limb that has a display list attached." Segment 0x0D isn't static data, but matrix data that's generated from the limb positions according to the current hierarchy, animation and animation frame.

So, segment 0x0D pretty much contains the transformation matrices for each bone in the hierarchy? Is there an exact size for this segment, or does it change depending on the actor?

Quote
As for segment 0x0C, I don't set it anywhere IIRC, for what is it used again?
I'm not really sure. I've seen it used somewhere before and always thought it was the actor
Logged

xdaniel

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 295
    • ICQ Messenger - 136250978
    • View Profile
Re: Actor joints & matrix & RAM segment shit cracked
« Reply #5 on: February 16, 2013, 12:15:16 AM »

That's pretty much it, yeah. Also, there's no precise size for segment 0x0D given anywhere, but the data length is (amount of limbs with display lists * size of matrix). So with one transformation matrix being 0x40 bytes in size, and a hierarchy with 10 limbs, 7 of which have display lists attached, results in 0x1C0 bytes of data.

Although AFAIK technically no segment has a true "size" as such, considering how their mapping works on the actual system; a segment is "created" by specifying a RAM base address for it (see gSPSegment), say 0x80567890 for segment 0x06, and it's accessed by calculating the real target address by adding the in-segment address to the base address (ex. 0x06001028 -> 0x80567890 + 0x00001028 = 0x805688B8).

Segment 0x0C might be one that's used for animated texture somewhere - that's probably the main thing the "undocumented" segments are used for. Facial animation on actors is often segment 0x08, maybe scenes/rooms use 0x0C?
Logged
cu xdaniel

Nanami - Desktop:

Kazari - Notebook:

SoulofDeity

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Actor joints & matrix & RAM segment shit cracked
« Reply #6 on: February 16, 2013, 05:37:22 PM »

That's pretty much it, yeah. Also, there's no precise size for segment 0x0D given anywhere, but the data length is (amount of limbs with display lists * size of matrix). So with one transformation matrix being 0x40 bytes in size, and a hierarchy with 10 limbs, 7 of which have display lists attached, results in 0x1C0 bytes of data.
k, so you only count the ones that have display lists  8)

Although AFAIK technically no segment has a true "size" as such, considering how their mapping works on the actual system; a segment is "created" by specifying a RAM base address for it (see gSPSegment), say 0x80567890 for segment 0x06, and it's accessed by calculating the real target address by adding the in-segment address to the base address (ex. 0x06001028 -> 0x80567890 + 0x00001028 = 0x805688B8).
I was just more or less just asking about the minimum size needed to display all actors without going out of range, though with your previous statement, I think a size of 0x400 (16 limbs) might be enough.

Segment 0x0C might be one that's used for animated texture somewhere - that's probably the main thing the "undocumented" segments are used for. Facial animation on actors is often segment 0x08, maybe scenes/rooms use 0x0C?
Idk really, but I think I've seen it used by 0xDE instructions and I know that some actor files contain display lists like Ganondorf.
« Last Edit: February 16, 2013, 05:39:00 PM by SoulofDeity »
Logged

Aeonic Butterfly

  • Newbie
  • *
  • Posts: 1
    • View Profile
    • Email
Re: Actor joints & matrix & RAM segment shit cracked
« Reply #7 on: June 06, 2013, 02:26:08 AM »

Trying to load object_bob using ZSaten2, but it's not working so well.  I keep getting out of memory errors.  Young Zelda loads fine.

For Read Actor, I enter:

object_bob
ovl_En_Daiku_Kakariko

It seemed to load after I left it alone for a while, but it glitched and the rendered died with a giant white box and a red X.

I'm pretty sure its because I'm not so sure what the overlay is, but a little help figuring out which one it is would be nice? :)
« Last Edit: June 06, 2013, 02:37:32 AM by Aeonic Butterfly »
Logged

spinout

  • Administrator
  • Sr. Member
  • *****
  • Posts: 309
    • View Profile
    • Email
Re: Actor joints & matrix & RAM segment shit cracked
« Reply #8 on: June 08, 2013, 06:22:12 AM »

The overlay is probably right, but ZSaten is probably confused as that overlay loads multiple NPCs. Also actor 0x0182 uses object_bob, worth a shot, I guess?
Logged
biggrin.gif