Jump to content

Missing something around transforms, maybe something else...?


Recommended Posts

Hey guys,

I've played around with Spriter on and off for a few years but never really done much with it, but recently I decided to try and throw something together to get an animation loaded and playing in pixi.js. After weeks of playing around and a bunch of googling, I have... something... but I'm not 100% sure what's wrong with my implementation here. Any pointers in the right direction would be great!

116892285-9517d080-ac27-11eb-9a56-77dfa6

  • Everything seems offset by 180 degrees, not entirely sure why though.
  • Arms and legs appear to be positioned on the opposite sides.
  • Hands and feet are attached to the wrong appendages.
  • Interpolating between the first and second keyframes causes all object to scale and rotate in a bizarre (but consistent) manner, all other frames play as expected given the above issues.

Given the last point, I'm making a major assumption my my interpolation methods are all working fine and this is just a display-specific set of issues (I get the same even if I just return the state of the first keyframe never update the animation state).

From my searches and some experimentation I've made a few other assumptions:

  • All bones excluding the first bone in the bone_refs array have their parent's transform values applied to them.
  • All object_refs have the parent bone transform values applied.
  • All Sprites have the same physical parent (flattened scene graph).

I've used the SpriterDotNet repo too to try and help me solve some problems but I'm not sure it will help solve the problems I currently face. I also tried playing around with the existing spriter.js and spriter.ts implementations but I couldn't even get the demo loading and running; looking at the demo source there's also a hell of a lot of set up and not even sure how much of it is even necessary to get something working.

 

Here's my function that applies the parent bone state to the children (bones, objects):

    private applyParentProps(child: IBoneState | ISpriteState, parent: IBoneState): void {
        const x = child.x * parent.scale_x;
        const y = child.y * parent.scale_y;

        const parentAngle = fromDegrees(parent.angle);
        const sin = Math.sin(parentAngle);
        const cos = Math.cos(parentAngle);

        child.x = ((x * cos) - (y * sin)) + parent.x;
        child.y = ((x * sin) - (y * cos)) + parent.y;

        child.scale_x *= parent.scale_x;
        child.scale_y *= parent.scale_y;

        if (child.angle != null) {
            child.angle = Math.sign(parent.scale_x * parent.scale_y) * (child.angle + parent.angle) % 360;
        }
    }

This just manipulates the data structure for the child. For the objects (Sprites), I use this method to handle applying that data structure:

    private applyState(component: Component, state: ISpriteState): void {
        // `this._bones` is just the array of bone data interpolated for the current time.
        // `state` is the object data interpolated for the current frame.
        this.applyParentProps(state, this._bones[state.parent]);

        component.position.set(state.x, state.y);
        component.scale.set(state.scale_x, state.scale_y);

        if (state.z_index != null) {
            component.zIndex = state.z_index;
        }

        if (state.angle != null) {
            component.rotation = fromDegrees(state.angle);
        }

        // Update the texture.
        if (state.file != null && state.folder != null) {
            const fileData = SpriterCache.getFile(state.folder, state.file);

            if (component.name !== fileData.name) {
                component.name = fileData.name;
                component.texture = TextureCache[fileData.name];
                component.width = fileData.width;
                component.height = fileData.height;

                component.pivot.set(
                    fileData.pivot_x * fileData.width,
                    fileData.pivot_y * fileData.height
                );
            }
        }
    }

 

Am I missing something super obvious? Am I being dumb here?

Thanks in advance :)

Link to comment
Share on other sites

Well, that's solved part of my issue, thanks :) I feel so dumb that it was THAT obvious! Was kinda hoping one thing would solve all my problems but I still can't seem to figure out why the legs and arms appear to have their positions swapped.

117534158-30be8d80-afe8-11eb-994e-6b6eb4
 

I'm wondering if they're just parented to the incorrect bones... somehow... or whether I'm applying transformations to bones that I shouldn't be?

Link to comment
Share on other sites

4 hours ago, brinsleylogic said:

117534158-30be8d80-afe8-11eb-994e-6b6eb4

Ah.  I either created and lost, or never got around to creating a little set of gifs that showed common issues like this, and how to solve them.   If I remember correctly this could be the texture coordinates being reversed in that engine?

Try changing every pivot point to 

(pivot.x, 1.0 - pivot.y)

as you load it (essentially flipping the pivot on the y axis).

Link to comment
Share on other sites

26 minutes ago, lucid said:

Ah.  I either created and lost, or never got around to creating a little set of gifs that showed common issues like this, and how to solve them.   If I remember correctly this could be the texture coordinates being reversed in that engine?

Try changing every pivot point to 


(pivot.x, 1.0 - pivot.y)

as you load it (essentially flipping the pivot on the y axis).

I had a play around with the pivot, positional and scale values. Look like I needed to invert the `y` and `scale_y` values too but it's looking good!

117542838-34ffa080-b012-11eb-927a-e943a5

Animation doesn't look as smooth as I'd expect but that's something I'll definitely be able to debug and fix. Thanks for the help mate; I can't explain how many headaches this has caused me :D

Link to comment
Share on other sites

I didn't know whether I should start a new topic, but I'm still battling with some key-framer interpolation logic. I've intermittently had an issue where it seems the sprites just seem to retrieve weird coordinates:

118242610-6dc9ca80-b495-11eb-8c4a-ae3044

I've managed to finally figure out what this is caused by: `parent` is different from one key-frame to the next, for example:

Frame 0:

118242859-aa95c180-b495-11eb-9904-b5754f

Frame 1:

118243021-e0d34100-b495-11eb-94c1-08f273

 

Any suggestions on how to handle interpolation between these frames? At the moment I'm applying the parent transform to the child in my rendering layer, but I guess maybe I should do this at some point before the interpolation?

I'm hoping to avoid that to keep it as performant as possible, though I guess I could test whether the parent id is different between the key frames and only apply the transform pre-interpolation if different?

Just thinking out loud but I welcome any insight others may have on this problem :)

Thanks.

 

EDIT:

After looking more carefully at the hierarchies I noted that the hierarchies are actually the same - it's the ordering that's different, which seems to be interfering with something on my end. Although, I guess the different-parent-between-frames scenario is still something that should be catered for?

Edited by brinsleylogic
More info added.
Link to comment
Share on other sites

  • 1 month later...
  • 2 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...