PDA

View Full Version : Spriter - Tool for making 2d animations easier



Daikrys
02-04-2012, 11:56 PM
hey guys,

i found this project (http://www.brashmonkey.com/spriter.htm) at kickstarter and it comes kinda handy when you animate 2d sprites
it work well with Inkscape but should work with any other graphic program so you should try it out

normally i would post it under tools but due to the challenge it fits better here :)

WILL
03-04-2012, 02:24 AM
Cool idea! Thanks for the post. :)

Ingemar
04-04-2012, 11:02 AM
MS only (and they don't even say it). That limits the fun IMHO.

wagenheimer
14-07-2012, 02:14 AM
Spriter is very promising, but still is a bit far of being totally usable!

There is something similar already available for ZenGL : CoolSprite Editor, and it is already very usable. With some small improvements it would be the definitive tool for doing these kind of animations! The original post is in Russian, but Google Translator can help! =)
http://translate.google.com/translate?sl=ru&tl=en&js=n&prev=_t&hl=pt-BR&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F%2Fzengl.org%2Fforum%2Findex.php%2Ftop ic%2C297.0.html

Here is something I'm doing using it (for my next super secret project) . :P


http://www.youtube.com/watch?v=4e1H-BECBFg&feature=player_embedded

Here a small video showing how to use the editor!

http://www.youtube.com/watch?v=_n6NztXA5xo

wagenheimer
02-03-2013, 03:48 AM
Well... Unfortunately Spriter seems to be delayed and Cool Sprite editor is not updated anymore.

But... Spine were funded on Kickstarter, and it is already very superior to Spriter and Cool Sprite. http://www.kickstarter.com/projects/esotericsoftware/spine

http://www.youtube.com/watch?v=1hRFEYFfDFs

There is already some runtimes for it ready for use (https://github.com/EsotericSoftware/spine-runtimes), and there is a lot more of runtimes coming (unfortunately no Pascal runtimes planned for it).

Anyone interested in start porting the libgdx runtime of Spine to Pascal? I will try to start it soon and some help would be very appreciated! My idea is keep the source free to be easily usable on popular Pascal Engines (ZenGL, Phoenix, Asphyre...).

Carver413
02-03-2013, 02:49 PM
I am working on some simular stuff for 3d for the explorer project. sort of a gijo kind of setup.

Dan
07-03-2013, 09:01 PM
hi, thanks for bringing this spine tool to my attention. I have made a complete pascal runtime port for it. I still need to kill all the memory leaks but that may take a couple of days at most.
unlike the existing runtimes for spine I did not bind it to any one graphics framework, so anyone can use it with their favorite pascal framework.
I have attached a small demo rendered using my g2mp game framework.

wagenheimer
08-03-2013, 03:19 AM
Awesome news Dan!

Thanks a lot for creating the runtime! I can't wait to test it! =)

Your example works like a charm! =)

Dan
08-03-2013, 04:38 AM
you are welcome, I will upload the runtime some time this weekend. if anyone knows of similar tools that enhance the game development I would be happy to create pascal support for it.

Dan
08-03-2013, 11:24 AM
ok here it is: http://gen2gdk.com/files/SpinePascal.rar
if anyone is interested I can make the demos with pure opnegl and direct3d. at the moment there is only one demo that uses g2mp.
Here is how much code I had to write to make it work with g2mp:


TG2SpineTexture = class (TSpineTexture)
public
Texture: TG2Texture2D;
constructor Create(const TextureName: AnsiString);
destructor Destroy; override;
function GetWidth: Integer; override;
function GetHeight: Integer; override;
end;

TG2SpineTextureLoader = class (TSpineTextureLoader)
public
function LoadTexture(const TextureName: AnsiString): TSpineTexture; override;
end;

TG2SpineRender = class (TSpineRender)
public
procedure Render(const Texture: TSpineTexture; const Vertices: PSpineVertexArray); override;
end;

...

//TG2SpineTexture BEGIN
constructor TG2SpineTexture.Create(const TextureName: AnsiString);
begin
inherited Create;
Texture := TG2Texture2D.Create;
Texture.Load(TextureName);
end;

destructor TG2SpineTexture.Destroy;
begin
Texture.Free;
inherited Destroy;
end;

function TG2SpineTexture.GetWidth: Integer;
begin
Result := Texture.RealWidth;
end;

function TG2SpineTexture.GetHeight: Integer;
begin
Result := Texture.RealHeight;
end;
//TG2SpineTexture END

//TG2SpineTextureLoader BEGIN
function TG2SpineTextureLoader.LoadTexture(const TextureName: AnsiString): TSpineTexture;
begin
Result := TG2SpineTexture.Create(TextureName);
end;
//TG2SpineTextureLoader END

//TG2SpineRender BEGIN
procedure TG2SpineRender.Render(const Texture: TSpineTexture; const Vertices: PSpineVertexArray);
var pv: PSpineVertexArray absolute Vertices;
begin
g2.PicQuadCol(
pv^[0].x, pv^[0].y, pv^[1].x, pv^[1].y,
pv^[3].x, pv^[3].y, pv^[2].x, pv^[2].y,
pv^[0].u, pv^[0].v, pv^[1].u, pv^[1].v,
pv^[3].u, pv^[3].v, pv^[2].u, pv^[2].v,
G2Color(Round(pv^[0].r * $ff), Round(pv^[0].g * $ff), Round(pv^[0].b * $ff), Round(pv^[0].a * $ff)),
G2Color(Round(pv^[1].r * $ff), Round(pv^[1].g * $ff), Round(pv^[1].b * $ff), Round(pv^[1].a * $ff)),
G2Color(Round(pv^[3].r * $ff), Round(pv^[3].g * $ff), Round(pv^[3].b * $ff), Round(pv^[3].a * $ff)),
G2Color(Round(pv^[2].r * $ff), Round(pv^[2].g * $ff), Round(pv^[2].b * $ff), Round(pv^[2].a * $ff)),
TG2SpineTexture(Texture).Texture, bmNormal, tfLinear
);
end;
//TG2SpineRender END

as you can see it's almost nothing compared to the size of the runtime code itself (~2700 lines).

I have only tested the runtime with the fpc. I think it should work with delphi as well, but if you have any problems please let me know.
I will later make a runtime for the smart mobile studio.

wagenheimer
08-03-2013, 11:57 AM
Thanks a lot Dan! =)... I will try to use it with ZenGL Engine. I will post the code here as soon I get it working!

It would be interesting to post about it on official forum, http://esotericsoftware.com/forum/viewforum.php?f=3, and if possible put it on https://github.com/!

wagenheimer
08-03-2013, 02:55 PM
There is some incompatibilities with Delphi 2010.

- Overloaded methods should explicitly use the overload clause.
- I had to add .Items in some places, by example need to change SpineTextures.[i] to SpineTextures.Items[i]
- Incompatible type Char and AnsiChar on lines like these one : _Chars[i] := Chr(b); I fixed it using _Chars[i] := AnsiChar(Chr(b)); but I don't know for sure if this is correct! =)

Everything else seems to be working well on Delphi 2010!

Everything else but the draw routine is working with ZenGL already! I'm not 100% sure but It seems ZenGL does not have a function to draw a array of vertices, but only to draw triangles pr2d_TriList. I think I will also need to use tess_Triangulate to convert from vertices to triangles but all of this mess with my head, probably I will need some help from Andrey! =)

Dan
08-03-2013, 03:15 PM
thanks for testing it with delphi, when I have the time I will try it as well.
the rendering method is quite simple, the array always consists of 4 vertices and the vertex format is:


TSpineVertexData = packed record
x, y, u, v, r, g, b, a: Single;
end;

so you really just need to draw a quadrangle or basically two triangles.

wagenheimer
08-03-2013, 03:43 PM
Hummm... we are getting closer! =)



var
pv: PSpineVertexArray absolute Vertices;
p, t: array of zglTPoint2D;
begin
SetLength(p, 6);
// first triangle
p[0].x := pv^[0].x;
p[0].y := pv^[0].y;
p[1].x := pv^[1].x;
p[1].y := pv^[1].y;
p[2].x := pv^[2].x;
p[2].y := pv^[2].y;
// second triangle
p[3].x := pv^[1].x;
p[3].y := pv^[1].y;
p[4].x := pv^[2].x;
p[4].y := pv^[2].y;
p[5].x := pv^[3].x;
p[5].y := pv^[3].y;
pr2d_TriList(@Texture, @p[0], nil, 0, length(p) - 1, $FFFFFF, 255, FX_BLEND or PR2D_FILL);

SetLength(t, 6);
// first triangle
t[0].x := pv^[0].u;
t[0].y := pv^[0].v;
t[1].x := pv^[1].u;
t[1].y := pv^[1].v;
t[2].x := pv^[2].u;
t[2].y := pv^[2].v;
// second triangle
t[3].x := pv^[1].u;
t[3].y := pv^[1].v;
t[4].x := pv^[2].u;
t[4].y := pv^[2].v;
t[5].x := pv^[3].u;
t[5].y := pv^[3].v;
pr2d_TriList(@Texture, @p[0], @t[0], 0, length(p) - 1, $FFFFFF, 255, FX_BLEND or PR2D_FILL);

Dan
08-03-2013, 03:56 PM
the second triangle should be 0,2,3 because the vertices are passed in clockwise order

wagenheimer
08-03-2013, 05:16 PM
Thanks Dan! =)

Ohh yes! It is working now! =)



var
pv: PSpineVertexArray absolute Vertices;
vert, text: array of zglTPoint2D;
begin
//Vertices
SetLength(vert, 6);
// first triangle
vert[0].x := pv^[0].x;
vert[0].y := pv^[0].y;
vert[1].x := pv^[1].x;
vert[1].y := pv^[1].y;
vert[2].x := pv^[2].x;
vert[2].y := pv^[2].y;
// second triangle
vert[3].x := pv^[0].x;
vert[3].y := pv^[0].y;
vert[4].x := pv^[2].x;
vert[4].y := pv^[2].y;
vert[5].x := pv^[3].x;
vert[5].y := pv^[3].y;

//Texture
SetLength(text, 6);
// first triangle
text[0].x := pv^[0].u;
text[0].y := 1-pv^[0].v;
text[1].x := pv^[1].u;
text[1].y := 1-pv^[1].v;
text[2].x := pv^[2].u;
text[2].y :=1- pv^[2].v;
// second triangle
text[3].x := pv^[0].u;
text[3].y := 1-pv^[0].v;
text[4].x := pv^[2].u;
text[4].y := 1-pv^[2].v;
text[5].x := pv^[3].u;
text[5].y := 1-pv^[3].v;

pr2d_TriList(nil, @vert[0], @text[0], 0, length(vert) - 1, $FFFFFF, 255, FX_BLEND);
pr2d_TriList(TG2SpineTexture(Texture).Texture, @vert[0], @text[0], 0, length(vert) - 1, $FFFFFF, 255, FX_BLEND or PR2D_FILL);

Dan
09-03-2013, 05:51 PM
alright I have ported the runtime to smart mobile studio: http://gen2gdk.com/g2mp/spine/
enjoy=)

Dan
10-03-2013, 11:44 AM
I have fixed all the delphi incompatibilities. the download link is still the same.

User137
10-03-2013, 02:56 PM
TSpineVertexData = packed record
x, y, u, v, r, g, b, a: Single;
end;

Is there any speed benefit in using single type for color channels? Because this takes 12 bytes less data per vertex:

TSpineVertexData = packed record
x, y, u, v: Single;
r, g, b, a: byte;
end;

Dan
10-03-2013, 06:47 PM
manipulating floats is a lot faster than integer types in this case. suppose you want to multiply two colors with floats you can do just that multiply them, with bytes you'll need to convert them to floats, multiply and convert them back.
also 12 bytes per vertex is not a major loss, since every attachment only has 4 vertices=)

czar
10-03-2013, 09:12 PM
Spriter is very cool. I am working with Brashmonkey at the moment. He is creating my artwork for me and spriter is great when you want o be able to reskin characters, or have characters swap out different equipment etc.

Dan, your Spine port looks very good.

Dan
24-04-2013, 10:26 AM
I have updated the spine runtime to support the new export format. the animations are now exported with the skeleton file and are loaded with it. http://gen2gdk.com/files/SpinePascal.rar
wagenheimer, if you port the spine example to zengl I will include it in the archive.

phibermon
24-04-2013, 12:29 PM
Jink does have a 2D engine inside it with an editor along the lines of spine. Spine is far more polished however and looks like it's got quite a good uptake so I think I'll add a plugin myself at some stage since there's now a public format for 2D armature animations!

Does spine allow you to reference your source images by filename or does it pack the data with the json/binary? for example if I were to use spine I'd keep my support for vector formats such as SVG, so not only can they be part of an animation but that animation can then be resolution independent.

it's a damn sight easier than handling 3D formats! I'm still having issues with MD5 quaternions in bone space and IQM rest poses

Dan
25-04-2013, 05:20 AM
spine does reference the images by file names. however, it does not use separate images, instead it assumes that all the images are packed into an atlas texture, so an atlas file is required. it can be made to work with separate images with some small changes to the runtime.

wagenheimer
27-04-2013, 05:49 PM
Well...

Here is the ZenGL updated code with an improved example!

You can walk with the goblin with Left/Right keys, can attack pressing Space and can change the Skin (to a Female Goblin) using C key.

This is the first draft of ZenGL code yet, I hope to improve it a lot and I will post any progress here! The next step is use the Mix animations function to provide sweet transition between different animations. =)

I hope to keep updating this ZenGL example to provide a good class for Handling Spine Animations with ZenGL (using Dan's Pascal Headers).

Ps. To create the Packed textures for it, you will need http://www.codeandweb.com/texturepacker and use the LibGDX exporter! I use only packed textures with my games and I created some functions to help ZenGL handling it, I will clean my code and post the code with examples here in forum sometime soon! But Spine already supports it!

Any suggestions is welcomed! =)

Darkhog
10-07-2013, 05:30 AM
I realize this is old thread, but I've found this tool: http://www.kickstarter.com/projects/1457278266/basis-bone-and-sprite-integration-system - it's free and (I think, but not sure) open source. But you should support them by giving them some of your $$$. I knew about it earlier from TIGSource thread, but was in development then yet, so didn't post here. Anyway from what I've played with the tool is very usable although exporting isn't there yet.

Deee
28-04-2020, 04:41 PM
Hi guys, Sorry for digging up this old thread.
I am developing the tool Sprite DLight (http://www.2deegameart.com/p/sprite-dlight.html) (in Lazarus), which generates normal maps for sprites automatically. This allows for pretty awesome dynamic lighting effects in 2D games and is even more awesome in combination with skeletal animation.
There are some challenges when using Spine and Sprite DLight together, like rough joints and the need to recalculate the normals according to the bone rotation.
I was excited to find out there was a Spine Runtime for Pascal and I am hoping to solve some of these with it, however all the old download links here and in the Spine Forum (http://esotericsoftware.com/forum/Pascal-runtime-188?p=61168#p61168) are dead and I can't seem to get in contact with Dan.
So Dan, if you are around, or if anybody still has the old files somewhere, I would greatly appreciate them being made available for download again.

Ñuño Martínez
01-05-2020, 10:35 AM
What a nice tool, Dee. I hope you find the code you need.