rufaswan/Web2D_Games

About the integrity of the quad file

Opened this issue · 8 comments

quqr commented

Hi, rufaswan,

I'm working on a program that converts *.quad to Spine json and have some issues during the development process.

  1. I've noticed some keyframes seems have no image ("Momohime_Battle.mbs.v55.quad" ->"IDLE_A [LOOP] [MIX]"), like this :
1716821166267

Was there something missing from the quad file or were these keyframes discarded during development by Vanillaware?

  1. When I attempted to crop images using the program, I found that some images could not be cropped as they lacked a srcquad and did not seem to display in the quad player. Is there a reason for their absence?
1716821202686
  1. Some quad files need to be linked to other quad files. It's easy to link them, but I'm not sure how to arrange the layers correctly. ("Momohime_Battle.mbs.v55.quad" + "Momohime_Katana_a.mbs.v55.quad")

Looking forward to your response!

Hi quqr! Nice work on converting QUAD to Spine2D format! I was wondering is it even possible because fundamentally they are both very different format.

  1. So far, the files I tested are the ones with obvious MBS + FTX pairs. Momohime_Battle.mbs doesn't have obvious FTX to pair with, so it is possible you are using wrong FTX textures. I would suggest you to use Momohime_Battle_drm.mbs instead to make sure you are always using the correct textures.

  2. That is correct. Not all layer are textures data, the can also be vertex color / fogquad only. That's why it doesn't have srcquad.

Here is an example - Gwendlyne's slash effect are vertex color only. And they are not using normal blending mode, but addition blending mode.
quad v0.2

I already reverse PS2 Odin Sphere main executable for all 6 blending modes in the game (but 4 of them are unused). I haven't reverse blending modes for other consoles yet, so they only have normal blending mode. Quad Player doesn't draw them in TEX mode, but you can still see them in LINE mode to confirm they exists.

  1. Sorry I don't know. Linking to other quad files, and anything related to that are all currently under research. I am hoping for a breakthrough on it for upcoming v0.6 update.

Good luck for your QuadToSpine project!

quqr commented

Thank you for your reply.

Converting quad to Spine2D format is completely possible. Although the quad file lacks some data needed by Spine, it can be inferred from the existing data. (Such as the lack of bone length, rotation, FK, IK, etc., but can be solved by Mesh, it can be driven by vertices, which is exactly the same as dstquad.)

The animation part is the most troublesome thing. The animation part of quad file is completely different from that of Spine, and the animation of quad file needs to be reconstructed to adapt to Spine. The Spine import may fail if the animation is too complicated. I am trying to solve this problem.

Now I know that connecting different Quads is a very difficult thing to do.
For example, "Momohime_Battle.mbs.v55.quad" can be connected to Momohime_katana__B.mbs.v55.quad ", "Momohime_Katana_a.mbs.v55.quad", "Momohime_katana_A.MBs.v55.quad",
"Momohime_Katana_a_B.mbs.v55.quad", Momohime_Katana_c.mbs.v55.quad ".

In Unity, I use the animation derived from "Momohime_battal.mbs.v55.quad" as a layer, and "Momohime_katana_BCb.mbs.v55.quad" as a layer. I found that "Katana" is either in front of "Battle" or behind it, and it doesn't seem to have anything to do with one of the layers inside "Katana". I guess there might be a parameter that controls the order of "Katana" before or after "Battle".

1717132530441 1717132544016

Hope your work goes well and look forward to your next update.

quqr commented

Hello, how are you doing?

I recently resolved the issue with the skin and now it can be changed to different skins.

0720.2.mp4

The animation is based on the movement of vertex images and does not appear to use bones. I cannot find any information about bones in the quad file, such as bone length or parent-child relationships. Although this can be resolved using spine2d mesh, there are still some issues.

0720.1.mp4

Therefore, I would like to know if there is a way to obtain bone data.

Great work!

Bones information, such as bone length or parent-child relationships, doesn't even exists in the original Vanillaware FMBS file. The best you can do is to fake it, by connecting all animation tracks to the root (0,0).

The original FMBS file is converted to .FMBS.v55 file first, which is just FMBS in text format. You can get an idea how the original file looks like before I convert it to .QUAD.

Good luck!

quqr commented

Hello, how are you doing?

I've been thinking for a long time, and it seems impossible to build complete bones, which is quite unfortunate.
Recently, I've been working on some details regarding quad files to enhance the animation in my program.
However, I've encountered a few issues:

  • A skeleton may consist of multiple bones, meaning a full animation comprises several smaller animations.
    When I attempt to build a full animation, some animations conflict and display simultaneously.
    Due to these timing conflicts, I enabled only the first animation, which appears to work well.
1724853589774 1724853601401
  • The "blend_id" has confused me. Where is "DST"? I retained "blend_id = 0" and ignored the others to avoid displaying some erroneous layers.

  • Additionally, the "fogquad" has four RGBA values. Are these the colors of the four vertices of the image?

  • The "animation matrix", it seems unnecessary. I'm not sure what it's used for.

Looking forward to your response!

Congratulation on your v0.3.2 release!

A skeleton may consist of multiple bones, meaning a full animation comprises several smaller animations.
When I attempt to build a full animation, some animations conflict and display simultaneously.
Due to these timing conflicts, I enabled only the first animation, which appears to work well.

Agree. The animation for each track need to be sync'd. Most likely it is controlled by those int32 bitflags, which I have no idea what it is doing - by observing the sprite in-game and reading the ASM code.

Then again, I probably sucks at reading ASM code to begin with...

The "blend_id" has confused me. Where is "DST"? I retained "blend_id = 0" and ignored the others to avoid displaying some erroneous layers.

blend_id should refer to "Blend Object" for the exact blending formula used. By default, blending is disabled, so blend_id is -1. You can use it to draw background/wallpaper first, like drawing skybox before start drawing 3D models.

SRC is the RGBA pixel from the texture, and DST is the RGBA pixel from the canvas/screen.

Additionally, the "fogquad" has four RGBA values. Are these the colors of the four vertices of the image?

They are vertex colors when texture is not used.

You can try the sample quads on the "Example" section. I wrote them manually when testing/debugging new feature.

The "animation matrix", it seems unnecessary. I'm not sure what it's used for.

It was explained in my "Skeleton" update:

https://www.vg-resource.com/thread-38430-post-668074.html#pid668074

The animation matrix (which is from Scale, Rotate and Move) has the XY to assemble during animation. Without animation matrix, the sprite looks like this:

okoi

And then Vanillaware also interpolate them during animation.

Looking forward for v0.3.3 soon!

quqr commented

Hello, sorry to bother you again.

Recently I've been working on animation matrix and at first I thought it was just animation matrix times dst but it's not that simple. I looked at the source code of your QuadPlayer, but the more I read, the more I got confused.

code

  • mat4 can be the animation matrix, which is A = 4x4 matrix, and dst is B = 4x2 matrix, but the function "quad_multi4() "It's not a matrix function that handles AxB. What's going on here?

  • xyz is four 3D points, but dst is four 2D points. I guess the "perspective_quad()" function is similar to the MVP matrix in computer graphics?

I tried to refactor the above code into my program, but it failed, and the results were not good.
1726062279594
code2

  • I guess the function "Q.gl.draw_keyframe()" completes the next steps, but I don’t know WebGL. Also, my knowledge of JavaScript is quite limited. I can’t understand what’s inside this function at all.

  • By the way, why does dst need such complex transformations? Why not achieve the desired effect through some simple linear transformations? Perhaps Vanillaware wants to achieve animation curves this way, as I haven’t found any information about animation curves in the quad files.

  • Also, there are no animation events or similar things. How do they handle related logic during animation playback? (For example, in 13 Sentinels, when the protagonist summons the mecha, there are effects triggered when “START” appears, but I haven’t seen these effects in QuadPlayer).

1726317724504
  • The hitboxes in the animation seem too complex. Do they really implement hitboxes in the game like in QuadPlayer? I guess not, as it would consume a lot of resources to determine collisions. They might merge hitboxes to form a single hitbox. I tried to merge these hitboxes, but got stuck in the theoretical stage, and I didn't really want to calculate those complicated formulas.
1726317855113

In Figure 2, you can see that the drawing order of the layers is incorrect. After you remind me, I finally found the reason for this problem that has puzzled me for a long time, which is closely related to the animation track. At first I thought a complete animation was composed of a single key animation. Therefore, I determined the layer order based on this key animation, but this is not the case. A complete animation may contain multiple key animations

The problem is that the order in which layers are drawn for later animations overrides the order in which layers are drawn for earlier animations when traversing through them.

Looking forward to your reply!

Hey! How is v0.3.3 going?

mat4 can be the animation matrix, which is A = 4x4 matrix, and dst is B = 4x2 matrix, but the function "quad_multi4() "It's not a matrix function that handles AxB. What's going on here?

That is incorrect. 4x2 matrix is [x,x,x,x,y,y,y,y] , and a quad is [x,y,x,y,x,y,x,y], so it is like 4 vec2. They are not the same.

So what quad_multi4() do is mat4 * vec2 for 4 vec2 of a quad. You will get 4 vec4 as result, but you'll keep XY only, ZW is dropped.

Then those 4 XY set is returned as a transformed "quad".

xyz is four 3D points, but dst is four 2D points. I guess the "perspective_quad()" function is similar to the MVP matrix in computer graphics?

perspective_quad() is to convert dstquad from vec2 XY to vec3 XYZ for perspective rendering, like this:

https://rufaswan.github.io/Web2D_Games/webgl_test/quad-perspective-xy.tpl.html

I guess the function "Q.gl.draw_keyframe()" completes the next steps, but I don’t know WebGL. Also, my knowledge of JavaScript is quite limited. I can’t understand what’s inside this function at all.

Q.gl.draw_keyframe() is just GL abstract layer to draw a keyframe by using the right vertex/fragment shader (aka program). Then set all the correct shader values for attrib, uniform, texture, viewport and such. It is more on OpenGL knowledge than JavaScript.

The hitboxes in the animation seem too complex. Do they really implement hitboxes in the game like in QuadPlayer? I guess not, as it would consume a lot of resources to determine collisions. They might merge hitboxes to form a single hitbox. I tried to merge these hitboxes, but got stuck in the theoretical stage, and I didn't really want to calculate those complicated formulas.

Comparing to number of hitbox from a fighting game, it is pretty reasonable.

https://wiki.gbl.gg/w/Vampire_Savior/Morrigan

Also remember it is on 3D rendering engine, where you'll need to do collisions test between 2 triangles in 3D space. It can be anything from walkmesh, moving platforms, objects, ramps, spiral staircase, etc.

That also reminds me the slowdown/lag issue on PS2 Odin Sphere.

By the way, why does dst need such complex transformations? Why not achieve the desired effect through some simple linear transformations? Perhaps Vanillaware wants to achieve animation curves this way, as I haven’t found any information about animation curves in the quad files.

Also, there are no animation events or similar things. How do they handle related logic during animation playback? (For example, in 13 Sentinels, when the protagonist summons the mecha, there are effects triggered when “START” appears, but I haven’t seen these effects in QuadPlayer).

In Figure 2, you can see that the drawing order of the layers is incorrect. After you remind me, I finally found the reason for this problem that has puzzled me for a long time, which is closely related to the animation track. At first I thought a complete animation was composed of a single key animation. Therefore, I determined the layer order based on this key animation, but this is not the case. A complete animation may contain multiple key animations

The problem is that the order in which layers are drawn for later animations overrides the order in which layers are drawn for earlier animations when traversing through them.

Since these questions are animation related, so I'll answer them in one go.

Vanillaware animation data is in MBS files, and it starts from PS2 Grim Grimoire and evolved over time with a bunch of new features added.

Vanillaware MBS file is made up from a bunch of sections, so I label them s0, s1, s2, ..., s9, sa (= s10), sb (= s11).

Originally MBP/MBS file has only 11 sections (so from s0 to sa), but since Odin Sphere Remake, Vanillaware added a new section (sb), and it seems to be animation related. I don't know how to read those data, nor I can run/debug those games that has them.

This for MBS versions reference

https://github.com/rufaswan/Web2D_Games/blob/master/tools/psxtools/znote_vanillaware.txt

Since MBS just evolves, I can figure those data by matching them. Like match PS2 Grim Grimoire with PS4 Grim Grimoire.

The current target is to support games BEFORE Odin Sphere Remake on Vita/PS3/PS4. 13 Sentinels, Unicorn Overlord are all low priority right now.

So the current progress is:
PS2 - has PCSX2 debugger. Can work on it.
NDS - has no$cash debugger. Can work on it.
PSP - has PPSSPP debugger. Can work on it.
Wii - need to compile special Dolphin debugger from source. GCC compile failed with error.
VITA - my computer doesn't meet minimal requirement.
PS3/PS4/PS5 - nothing to work with
XBox S/X - nothing to work with
Switch - Nintendo Cease and Desist, nothing to work with.

In any case, the ripping project is not in a hurry. As long as Vanillaware is well and alive and still making games, the project will continue.

Good luck!