Jump to content

How to flip an animation?


PatS

Recommended Posts

I have my SCML loader and renderer working and can do most anything I need to (scale, move, rotate about the Z axis), except flip the image such that a character that was drawn facing right is now facing left.

I have tried adding a rotate Y 180 degrees operation to the transformation matrix but that did not work.

Can someone who has figured this out tell me how to do this?

TIA

-Pat

Link to comment
Share on other sites

This is probably outside information you'd pass into your SCML draw calls. (aka character information like position and facing direction and stuff)

Drawing the animation flipped can be implemented different ways. This can be a use of different texture coordinates, using a negative scaleX value, etc etc.

Link to comment
Share on other sites

C2tP and Grim

Thanks for your replies.

If I understand your suggestions correctly, each sprite in the animation would be flipped in place. It seems to me that this approach would only work if the sprites in the animation were symmetrical (i.e.the left and right sides were the same). We also need to consider movement, the movement of the right arm would have to be transferred to the left when the character was flipped.

Grim, I have looked at your very nice C++ implementation and notice that you do not offer flipping as an option. Have you tried?

Lucid, are you watching? Can you offer an advice? Did you design it so that the animation could be efficiently flipped in a game?

Regards,

-Pat

Link to comment
Share on other sites

What we mean is a base scaling of the entire sprite, including bone/object positions and everything. You can see it in my implementation as the base_transform (line 2483 in SCMLpp.cpp). The info used to create this transform is provided by the program and is used to position, rotate, and scale the entire sprite dynamically so it fits in a game.

Link to comment
Share on other sites

Hi,

I'll update the documentation for this as well as soon as I can

grimfang is correct, if you implemented bones, treating the entire animation as a child of a 0,0 bone with -1 xScale or -1 yScale would work

if you haven't however, the way it basically works is

flip each sprite the same way the characters is (meaning if the character is xflipped, xflip each sprite, etc)

for xflipping multiply all x values and xscale values by -1, and the same for yflipping and y and yscale values

the tricky part is angles

for that do this

xflip=1 normally, or -1 if flipped;
yflip=1 normally, or -1 if flipped;

if(xflip*yflip==-1)
{
multiply all angles by -1;
}

I'm pretty sure that is correct and I will double check when I continue documentation,

however if it doesn't look right (depending on if your engine uses very high level transformation operations) then instead of multiplying angles by -1, you may need to just take each angle and do

angle=360-angle;

also, please let me know which one works for you

Link to comment
Share on other sites

So I have been experimenting with this today find that setting the X Scale to -1 does not work

To rule out my code, I made the following change to SCMLpp.cpp line 2483

Transform base_transform(x, y, angle, -scale_x, scale_y);

I also tried

Transform base_transform(x, y, angle, scale_x, -scale_y);

When I tried

Transform base_transform(x, y, angle, -scale_x, -scale_y);

It worked! but rarely do we need to flip X and Y.

I have implemented bones, but I also tried reversing all of the angles and subtracting them from 360 as you suggest without success.

Lucid do you have plans for creating something like Jonny's C++ plugin but at a lower level (like C) and tuned for performance? (no disrespect Jonny)

I have been avoiding Jonny's code because it is a bit 'heavy' for the platforms that I target.

I am asking because if it is in the plan, I see no reason to re-invent the wheel

Thanks all

-Pat

Link to comment
Share on other sites

Flipping seems to work okay over here, except that I haven't added lucid's angle suggestion to fix the rotation when one dimension is scaled negatively (this problem only appears because we're not using matrix math). EDIT: It's added now, though uneven scaling (squishing and stretching) isn't perfect.

I take no offense, but do ask others to evaluate code realistically. If a performance issue is really observed, then that's when something needs to be done about it. Please let me know right away if that's the case. A library written in C is very useful for having a common ABI between languages, but it's really not going to have any sort of significant performance benefit. The time needed to develop and maintain it would be higher, as well.

If there's anything in particular that you think is too heavy in SCMLpp, please tell me and I can either improve that or make it more modular so it can be replaced easily. I know the code doesn't look particularly simple right now, but precise feedback always helps.

Link to comment
Share on other sites

as far as a c++ library, there's quite a bit more work to do on Spriter before I can shift my focus away from it full time, and as grimfang said, his library can always be improved, and being open source makes this even more possible. Also adapting what I'm currently using as a c++ library is probably heavier than you would want as well, because it's tailored toward making editing the structures and contains alot of calculations in realtime that done for you in scml.

After the next release I'll definitely split time with updating scml documentation though. And I'll make sure to include this issue as well. Also if you can include a video of what the broken animation looks like reversed, I can probably help you more easily, by breaking my current build so it looks like that.

Also, I think this is probably what you meant, but just in case, you shouldn't reverse the angles AND subtract them

it would be one or the other

Link to comment
Share on other sites

First I tried reversing and then subtracting in 2 different attempts :)

Jonny, I think your code is great, and cannot cite anything specific.

With that said, my personal preference is not to use STL in game code. For me that is the biggest 'red flag'.

I am a real C bigot, so like I said don't take offense, your code is great, I gained a lot of insight from it and it is something that you should be proud of. I could never have written code renders SCML from scratch myself.

-Pat

Link to comment
Share on other sites

Thanks Pat. The STL is definitely avoided on some platforms for good reasons. I'll make it easy to replace for now, then in the future I can consider replacing it permanently. That concern is always in my mind when I write a library, but is usually outweighed by the comprehensive containers that the STL provides.

Link to comment
Share on other sites

Looking my implementation, I don't use many arrays or vectors.

For example my 'object' has a pointer to it's bone, the next and previous object in the current keyframe and a pointer to the corresponding object in the next keyframe.

All of this is setup as the 'animation' is initialized and eliminates the need for any lookups

I can't say this is faster than having arrays but I do know not looking up an object in an array is always faster than looking one up (even if it's indexed). :)

Keep me posted on you flipping code so I can copy it

Thanks

-Pat

Link to comment
Share on other sites

Ok I didn't really check the forums for a few days and seems this thread is still going on here so I'll comment again.

I have working solution to flipping in my engine.

First off, dont flip the bones. keep all the calculations and work flow the same.

You're building the 'object' as a whole, facing the default direction.

(not saying you cant workout the transformations with the bones but this way works too...and i think less error prone if anyone is having trouble doing it the bone way)

In order to flip you only need to flip the actual image object right before you draw.

So you build the object up, do all the animations/tweening and when everything is good to go, you flip.

Here is some pseudo code:


SCMLObject* obj = blahblahblah;

processObject(SCMLObject* obj, ...){

//get current key and next key info for this object

//tween

//add parent's information

if(flip){
obj->x *= -1.0f;
obj->scale_x *= -1.0f;
obj->angle *= -1.0f;
}


Renderer->drawObject(obj);
}

I used the example knight that grimfang has in his sample folder.

RsAVe.png

and flipped:

2pa1K.png

(image link: http://imgur.com/2pa1K,RsAVe)

As you can see they are flipped nicely, and yes the animations are working nicely too.

I hope this works out for you guys too.

-C2tP

Link to comment
Share on other sites

Didn't work for me.

Are you using grim's code to up to that point?

When I try it, the object is off the screen.

If I calculate x = 200, scale_x = 1, angle = 90, the result is -200, -1, and -90

-200 is off the screen

For the angle would it be better to subtract the angle from 360 so 90 would be 270?

In any case since it clearly works for you, the data that you are manipulating at this point must be different than the data that I have.

Can you verify that the code that you posted is correct?

Thanks

-Pat

Link to comment
Share on other sites

No I am using my own personal implementation of scml in my own personal engine.

-200 and -90 are the results you want.

Remember -90 and 270 are the same thing.

The problem you're having lies in the idea of pivot points.

The x and y positions in scml shouldn't be thought of as screen coordinates. They are offsets from the origin.

So if some image is floating to the right 50 pixels, when you flip It should float 50 pixels to the left, aka -50.

This means that the 0,0 point in scml is the *whole* image's pivot point. So you should make your images centered in scml if you can.

If you didn't make your animations centered in the editor, its not a huge deal. Basically you'd be drawing something like you would if you were using sprites.

When you want to draw a sprite centered at positionX, you'd do something like draw(positionX - (width*flip /2))

This would draw the sprite centered at positionX.

This is just an example if you are not using centered pivot points.

Basically long story short, I assume you made your animation to the right of the origin (all objects have positive x values) thus are getting big movements when you flip.

Just offset the draw when flipped by the animation-as-a-whole's width.

Remember, the origin in scml editor can be considered the animation's pivot point.

I'm at work now (using phone) but if ya need ill draw pictures and examples when I get home.

Link to comment
Share on other sites

Aha!

I was setting the screen position in the root bone's parent, so when the value was calculated it's screen position was set

Changing that to set the root bone's parent to 0,0 and applying your code before rendering and the flip works.

Thank you very much!

-Pat

Link to comment
Share on other sites

Cool! Glad you got it working!

Yep gotta be careful when adding the other outside information like screen position. This is the game programming idea of spaces. Need to do all the animation work in "local space" and then shift to "world space."

Congrats on getting working implementation. :D

-C2tP

Link to comment
Share on other sites

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...