Jump to content

Spriter for C# Implementation Completed


Recommended Posts

After all of the effort I went through to figure out how Spriter works (thanks lucid!), I decided to release the code I have to the general public.

https://bitbucket.org/terinfire/spriter-for-c/overview

This has everything you need to read and process where you are.

You can use ScmlLoader object to load an ScmlObject.

After that, you can create a ScmlReference from here, wherein you set the ScmlObject you loaded previously. This now gives you access to that ScmlObject. From here, you can set the entity and animation, run an update, and call GetTimelineObjects(), which will return a list (ordered correctly) of the items you need to draw, along with all of their transforms. You will have to make a few adjustments based on your implementation -- for example, XNA's rotation is clockwise, while Spriter's is counter-clockwise. So you'll have to do something like: 360.0f - result.Angle; the coordinates for the Origin (Pivot X/Y) are also unique and need to be handled differently. Otherwise, everything else is pretty good/solid. I may include a sample project for monogame/XNA with this at some point.

Disclosure:

This works with current files from Spriter b7 release and *only* supports linear transformations/interpolations at the moment. Feel free to copy/borrow/steal the code and do whatever you will with it. It is being released as-is, with no warranties, but you can expect it to get bug-fixes every now and then, since I am using Spriter and intend to make sure I have a concrete implementation.

If you have any questions, feel free to ask. If you would like to include/build a sample project that uses this, let me know, and I will be happy to include it.

UPDATES:

2014.05.05 -- Updated to include a solution and fixed looping animations.

Again, many thanks to lucid for entertaining/assisting my questions and helping me push through them.

Link to comment
Share on other sites

  • 5 weeks later...

Awesome work, thank you! This will probably help me a lot!

But right now I'm having some weird problems, I'm trying to implement this in Otter (otter2d.com) and so far I didn't succeed.

This is how it should look like:

MFp1E77.gif

And this is what I got:

eGmoLaP.gif

Still not sure what I did wrong :( If someone wants to check the code, this is my image component class: http://pastebin.com/5L1LaXzM

I'll post again if I find a solution.

Thanks again!

Link to comment
Share on other sites

just going off of the way it's animating can you try:

multiply all 'y' values in objects by -1 as you load them initially

y=-yFromFile;

and/or

pivoty=1.0-pivotYFromFile;

EDIT:

Also try:

angle=360.0-angleFromFile;

Thanks! That definitely helped! But there's still something wrong that I can't figure out... I'm guessing something with the pivots.

this is how it looks now:

EDIT: I Fixed the default X pivot, better, not not there yet.

jAUFuT4.gif

Link to comment
Share on other sites

Doing the opposite of what you are now with the pivot y (using 1.0-filePivotY or not) doesn't fix it?

It looks like either the y pivots are off, or the y offset for each bone's children is getting miscalculated for some reason.

Can you post the part of the bone code where it unmaps the child from the parent to get the absolute coordinates?

Link to comment
Share on other sites

  • 3 weeks later...
Awesome work, thank you! This will probably help me a lot!

But right now I'm having some weird problems, I'm trying to implement this in Otter (otter2d.com) and so far I didn't succeed.

This is how it should look like:

MFp1E77.gif

And this is what I got:

eGmoLaP.gif

Still not sure what I did wrong :( If someone wants to check the code, this is my image component class: http://pastebin.com/5L1LaXzM

I'll post again if I find a solution.

Thanks again!

Hey, sorry it took me so long to reply... my dog has cancer, so I haven't been checking these forums as religiously as I should be.

Here's what my code looks like (will comment to hopefully give you some idea of the process):


//This calculates the X/Y origin of where we draw... for me, this is the bottom, center.
int X = ( (int) Math.Truncate( pActor.Coordinate.X ) - pCamera.CenteredOn.X ) + pCamera.HalfResolutionWidth;
int Y = ( (int) Math.Truncate( pActor.Coordinate.Y ) - pCamera.CenteredOn.Y ) + pCamera.HalfResolutionHeight;

//This allows for flipping sprites, but I'm not using it right now; it is necessary for my call to render.
//SpriteEffects Effects = ( pActor.State != null && pActor.State.IsLeft ) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
SpriteEffects Effects = SpriteEffects.None;

//ScmlReference is pretty obviously the ScmlReference object we use -- I'm updating this regularly with the time passed
List objects = pActor.ScmlReference.GetTimelineObjects();
//This is the Template of the Sprite... it basically acts as a place to get images, textures, offsets, etc (I use a Spritesheet and compile it all together).
SpriteTemplate template = MapEngine.Instance.SpriteTemplates[0];

//Mandatory sort order piece for drawing
Single SortOrderOffset = SORT_ORDER_OFFSET;

//Let's use the objects we have
foreach ( TimelineObjectReference o in objects )
{
//Get the ScmlFile from the object -- I have to do this because I have a spritesheet
File ScmlFile = GetScmlFile( template.SpriterObject, o.FolderID, o.FileID );
//Get the spritesheet
SpritesheetObject SpriteObject = template.Spritesheet[o.FolderID, o.FileID];

//Let's get the scalar pivot according to the file (where the file should be rotated from)
Vector2 Pivot = GetPivotVector( ScmlFile.PivotX, ScmlFile.PivotY, ScmlFile.Width, ScmlFile.Height );

//Only render if we have an object
if ( SpriteObject != null )
{
Rectangle destination = new Rectangle()
{
X = (int) ( X + o.X ),
Y = (int) ( Y - o.Y ),
Width = SpriteObject.Size.Width,
Height = SpriteObject.Size.Height
};

Rectangle source = new Rectangle()
{
X = SpriteObject.Position.X,
Y = SpriteObject.Position.Y,
Width = SpriteObject.Size.Width,
Height = SpriteObject.Size.Height
};

pSpriteBatch.Draw( template.Texture, destination, source, Color.White, GetRadians( 360f - o.Angle ), Pivot, Effects, pSortOrder + SortOrderOffset );

SortOrderOffset += SORT_ORDER_OFFSET;
}
}

The rest of that should be self-explanatory. If you don't have all of the crazy spritesheets like I do (which require some custom code), you should be able to just access the repository of files and deal with it accordingly. Since I batch everything up, it's a little different. I hope that helps!

Link to comment
Share on other sites

  • 1 month later...

Thank you for your C# implementation!

I'm developing a hobby project on XNA for some time now and decided to switch from my own animation system to Spriter.

I was also having problems similar to saint11, and managed to nail it down a little more.

In addition to fixing the rotation to (360 - Angle), reversing the Y value, and fixing the Pivot.Y, there seems to be a problem with Y offset in case of rotation in parent-child relations. If you open ScmlReference.cs and go into ApplyTransformations( ... ) you can change the following at line 299:


pChildReference.X = (Single) ( ( X * Cos ) - ( Y * Sin ) );
// Original
// pChildReference.Y = (Single) ( ( X * Sin ) - ( Y * Cos ) );
// XNA: Negative Y
pChildReference.Y = (Single) ( ( X * Sin ) + ( Y * Cos ) );

It works for me, I hope it helps.

post-17238-1415983424805_thumb.gifpost-17238-14159834249058_thumb.gif

(Don't mind the ugly red frames and pink dots, the images are placeholders for easy debugging)

This solves most problems. I'm still working on applying scale to the bones (especially negative), but it seems it can be resolved locally, after you get the timeline objects. If I manage to get a functional wrapper class for XNA I can post it later.

Cheers,

Link to comment
Share on other sites

  • 3 weeks later...
Thank you for your C# implementation!

I'm developing a hobby project on XNA for some time now and decided to switch from my own animation system to Spriter.

I was also having problems similar to saint11, and managed to nail it down a little more.

In addition to fixing the rotation to (360 - Angle), reversing the Y value, and fixing the Pivot.Y, there seems to be a problem with Y offset in case of rotation in parent-child relations. If you open ScmlReference.cs and go into ApplyTransformations( ... ) you can change the following at line 299:


pChildReference.X = (Single) ( ( X * Cos ) - ( Y * Sin ) );
// Original
// pChildReference.Y = (Single) ( ( X * Sin ) - ( Y * Cos ) );
// XNA: Negative Y
pChildReference.Y = (Single) ( ( X * Sin ) + ( Y * Cos ) );

It works for me, I hope it helps.

[attachment=1]SpriterWeird.gif[/attachment][attachment=0]SpriterProper.gif[/attachment]

(Don't mind the ugly red frames and pink dots, the images are placeholders for easy debugging)

This solves most problems. I'm still working on applying scale to the bones (especially negative), but it seems it can be resolved locally, after you get the timeline objects. If I manage to get a functional wrapper class for XNA I can post it later.

Cheers,

Looks good!

Are these issues that are problems with my code or with the XNA implementation of it in specific? When I wrote this, most of the code was developed looking at the Java implementation and the pseudo-code left by the admins here. I have my own XNA rendering agent built in specific, but I thought the changes that were necessary were because it was XNA and not because there was a flaw with the code? Let me know -- I'd be happy to patch it!

Link to comment
Share on other sites

  • 2 months later...
  • 1 month later...

Hi LemonLake,

 

I'm not sure if maybe something changed in the implementations or not.  The last time I worked with Spriter, I had only the default stuff they gave, since I've been working on other things in my personal time.  Did Spriter get any upgrades between May and now?  And were those upgrades something you use?  If so, let me know and I'll take a look at it.

 

If you look at the top link, you'll see that I have all of the code uploaded to BitBucket -- so you can actually look at any issues that may be around there.

 

Let me know if you see something that stands out -- would be happy to try to help.

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