Jump to content

Trixt0r

Members
  • Posts

    118
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Trixt0r

  1. It is not hard to implement a skinning feature like in Spine. Just animating some vertices.

    The problem is saving the skining stuff efficiently in the SCML format, which is very different from Spine's JSON format.

    - Trixt0r

  2. Hey guys,

    I was working on a little JavaFX GUI for the LibGDX texture packer tool. There is already one, but it does not pack all subfolder images into one texture.

    Maybe somebody can use it. This could be useful as long as Spriter does not pack the sprites into an atlas. I tried it with my generic Java api and it works very well. The only thing you need to use it in your environment is a little parser, which is able to read *.atlas files.

    You can either open a gui or call it from command line. Command line usage is described on the github wiki.

    Here you go. To run it, you need the newest Java 8 version.

    - Trixt0r

  3. I can not test it because MEGA is telling me all the time, that there is a problem with this file.

    Please attach a .zip file to your post. This way is much simpler.

    Anyway, this line

    loader.load(handle.file());

    has to be

    loader.load("coin");

    because the libgdx loader will try to load all assets from the given root folder, i.e. the parent folder of your SCML file.

    If you pass a File object as an argument, it will use the parent folder of the given file as root, which does not work on Android, for some strange reason.

    You should avoid using File objects, when working with non-desktop platforms. That's the reason why I you can pass a root folder name instead of a File object.

    -Trixt0r

  4. There should be no problem with linking the assets folder.

    When setting the assets folder as source folder, eclipse will put it into the bin folder during build time, so the assets should be present.

    Can you send me your projects (Android and Desktop)? I will test it on my machine.

    - Trixt0r

  5. Use


    Rectangle rect = getBoundingRectangle(null);
    float width = rect.size.width;
    float height = rect.size.height;
    //Do stuff

    getBoundingRectangle() returns always the same object reference!

    But you should know that calculating the rectangle of a player can give you many different results, because not every animation has the same bounding box.

    You could use boxes in Spriter instead. Those will give you always the same size.

    -Trixt0r

  6. it hangs on to its iterator so it doesn't get GC'd
    I am doing this too in the Player class for objects and bones.
    Personally, I avoid iterators altogether. Of course, in dropping them you'll trade a little elegance but the end result is what matters.
    I also do not like iterators, but using them simplifies the interface for drawing. The drawer takes an iterator and draws everything it offers. This makes it easier for you to control what you want to draw (see CullingTest).
    It would be nice if Spriter had a built in option to strip out all the useless whitespace in either of its xml/json formats, we could then use slightly smaller buffers and it would be faster to parse. So, one experiment would be to strip it yourself beforehand. I'm going to assume the xml parser will be able to manage it.
    Sounds interesting. The xml parser is able to do this, since it is the one from LibGDX ^^.
    Also, are you Atlasing your textures on the fly? (this is not ideal) There's probably an impact there that needs examining.
    Yes, atlases can be generated after parsing and loading all textures. Mabe this will not be necessary anymore in the future because atlas support was planned for Spriter. Maybe it will come with the next build?

    In terms of drawing performance, there could be improved the texture sampling (avoid sampling transparent pixels). But this depends on the evolution of the skinning feature in Spriter. For now this feature is quite buggy and as I read here in the forums not many people are using it, and if they use it, they are exporting their animations to sheets. So I may wait for the skinning implementation. It makes no sense to implement it if the format for skinning may change in the future. Furthermore, the way Spriter is saving skins in SCML is very confusing without having a documentation. And maybe skinning should be more similar to the Spine implementation, which is very flexible compared to the current Spriter version (just a suggestion :)).

    If you guys can improve the library, fork the repo and send me a pull request and I will merge the improved stuff into it.

    - Trixt0r

  7. Oh sorry, I did not see the first post.

    You have to add the gdx.jar and gdx-natives to your classpath. In eclipse it is under Project->Properties->Java Build Path.

    There you should make shure that the library gets exported.

    Maybe you should ask in the LibGDX forums, because the problem has nothing to do with the Spriter library.

    - Trixt0r

  8. boind: I did not get the problem? The Player class has already methods to flip the animation and to check whether it is flipped or not:


    //Flipping:
    player.flipX();
    player.flipY();
    //Or
    player.flip(true, true);

    //And to check whether the player is flipped:
    if(player.flippedX() == -1)//If flipped around x axis
    if(player.flippedX() == 1) //If not flipped around x axis
    //Same for y axis

    This enables the ability to write code a little bit more elegant.

    Let's say you have two methods called right() and left(), indicating that the right resp. the left button of your controller are pressed.

    Then you could change the flipping around the x axis with this line:


    player.flip((player.flippedX() == -1 && right()) || (player.flippedX() == 1 && left()) , false);

    Or for more readability you could create a method which tells whether to flip or not:


    private boolean flipPlayer(){
    return (player.flippedX() == -1 && right()) || (player.flippedX() == 1 && left());
    }
    //In your loop:
    player.flip(flipPlayer(), false);

    The reason why flippedX() and flippedY() return an integer instead of a boolean, is that it removes boilerplate code.

    Let's say you have a character which moves like this

    character.position.x += speed;

    If the methods would return a boolean you would first check with an if/else construction the face direction and then you would move the character:


    if(player.flippedX())
    character.position.x -= speed;
    else
    character.position.x += speed;

    Because the methods return integers you can avoid the condition checking and set the position like this:

    character.position.x += speed*player.flippedX();

    Instead of 4 lines you have only one.

    That is the way I would write a game, because I really do not like writing much code for simple things.

    Btw, the flipping issue greengnom mentioned is already fixed.

    I recommend you guys update your cloned repository more often, in the last few days I made some additions and changes.

    Forgot to mention: The library works also with GWT now.

    - Trixt0r

  9. Hey guys,

    I added a new feature to the library: Attachments.

    The idea behind attachments is that you could attach any 2D object to a specific part of a running animation. For example you could add a particle effect in your game to a sorcerer hand or something like that. You can see how it works in the AttachmentTest. I hope this is a useful thing for you guys.

    As the state of the library seems to be quite bug free, I am currently planning to complete all remaining features, such as meta data and skinning and maybe the new SCML features coming with the B8 release.

    Btw, is someone interested in a JavaFX rendering example?

    If you are in the need for any other new features let me know it.

    -Trixt0r

  10. that could ideally be used to subclass from and provide your more specific instances, i.e. derive from it and then override virtual OnPaint() and that kind of thing.

    That is actually that what the generic Java library does. It is not bound to any game engine or framework. It is plain Java and has no dependencies.

    I don't see the problem of using my library with IKVM. If you want to keep things platform independent, you will use Mono, right? So you will have the IKVM anyway.

    If you do not wan to use IKVM, you could use Sharpen. I already did one port from plaint Java to plaint C# (which is unfortunatley outdated now) and it was really easy (look at my signature).

    Anyway, I would say with IKVM you wouldn't even have to write any code, except the engine specific implementations for a drawer and a loader.

    I just pushed a new commit with complete documentation, so you can have a look at it.

    -Trixt0r

  11. Hi terinfire,

    Yes you could use my Java implementation. With the last major update I managed to remove many bugs and the library works quite well now.

    It is almost feature complete, the missings things are:

    • Meta-Data support (which is quite buggy in Spriter itself)
    • Skins, which are object to change and not very stable

    .

    You could either use IKVM, which will just run the Java bytecode in .NET, as I said in another post, or use sharpen, which converts Java to C# as good as possible (I tried it myself and it works quite well).

    If you give me some more time, I will add documentation to the library and it will be easier to understand what is actually goiing on.

    - Trixt0r

  12. If no one is working on an XNA or Mono game runtime, you could use the generic Java library with the IKVM, which is a VM for .NET. IKVM is shipped with Mono as far as I know and on Microsoft systems you would just add some extra dlls. It works very good. The only thing you have to do is to write a MonoGame/XNA loader and drawer, which is straight forward, if you look at the Java examples. Let me know if anyone is interested and I will upload a new example for XNA and MonoGame on Gitub. The only problem is that the coding style in Java is different from the one in C#. This could be bypassed with some C# wrapper classes.

    - Trixt0r

  13. Big Update:

    During the last weekend I refactored/rewrote the whole library.

    This means that your old code will not work anymore. All old classes are completely gone. I hope this does not affect any important projects you are working on currently (well it breaks some of my private projects, but it does not matter).

    I really did not like the old code, because there was reduntant code and the classes were not readable anymore. Now every class has not more than 300 lines of code (except the XmlReader which is not mine) and there are less classes. With the refactoring I fixed many bugs and I think that now any Spriter animation should be rendered properly.

    The basic usage is now the following:


    //During initialization
    Data data = new SCMLReader("Path to scml file").getSpriterData(); //Parse the scml file and receive usable data
    Loader<?> loader = new YourLoaderImplementation(data); //The loader relies on the loaded data
    loader.load("parent folder of scml file");//Load the resources
    Drawer<?> drawer = new YourDrawerImplementation(loader);
    Player player = new Player(data.getEntity("yourEntity")); //Or use the index

    //During updating and rendering
    player.update();
    drawer.draw(player);

    All old features are still working, but the way you apply them is a little bit different.

    I rewrote all backend tests and dropped the SpriterDemo project.

    I am planning to add more tests based on the libgdx backend, so everyone can checkout a specific feature instead of just running a full blown demo.

    Documentation is missing, but it will follow as soon as possible.

    Edit: Added now an example for Java2D inside a Swing application and some basic tests. More will follow this week.

    - Trixt0r

  14. Is k.info.angle the parent angle? The angle of the current object has to be affected by the inherited angle with currentObject->angle += parentObject->angle (same for the scaling with multiplication). I think you are rotating the wrong x and y values. You do not have to rotate pivot points. Those are just added to the final position.

    And I would do the unmapping before calculating the pivot part. Something like this:


    float x = //initialize this with the value from the scml file saved in the timeline key...
    float y = //initialize this with the value from the scml file saved in the timeline key...
    bool flipped = ((k.info.scaleX < 0) != (k.info.scaleY < 0));

    float angle = k.info.angle; //I hope this is the angle of the parent bone...

    if (flipped)
    angle = -angle;

    float s = (float)sin (angle * SCM::DEG_TO_RAD);
    float c = (float)cos (angle * SCM::DEG_TO_RAD);
    float xnew = (x * c) - (y * s);
    float ynew = (x * s) + (y * c);
    xnew += k.info.x;
    ynew += k.info.y;

    float sprite_x = xnew;
    float sprite_y = ynew;

    float pivotX = k.spriteKey.pivot_x;
    float pivotY = k.spriteKey.pivot_y;

    if (k.spriteKey.useDefaultPivot)
    {
    // get default pivot data from folder/file data
    pivotX = data_objects[0].folders[k.spriteKey.folder].files[k.spriteKey.file].pivotX;
    pivotY = data_objects[0].folders[k.spriteKey.folder].files[k.spriteKey.file].pivotY;
    }
    float offsetX = (pivotX - 0.5f) * img_dims.first; // image x dimension
    float offsetY = (pivotY - 0.5f) * img_dims.second; // image y dimension
    sprite_x -= offsetX*k.info.scaleX;
    sprite_y -= offsetY*k.info.scaleY;

    Mathematically these are two different things. What you are doing is a translation and then a rotation which is not equal to a rotation followed by a translation, i.e. T*R != R*T.

    This is what I am doing in my API.

    I hope this helps somehow.

    -Trixt0r

  15. I was trying to implement interpolation but for some reason the position during interpolation is all screwed up[...]

    OMFG?!! Are you using the newest version? This is definitely not your fault. It is mine.

    Please, send me the scml file (it can contain only the bone structure, if you want to keep your sprites private). Since I implemented curves, things in the SpriterPlayerInterpolator class went wrong and I only tested it with the monster scml file.

    Could you add that to the github project? By default, github projects are licensed as all rights reserved without an explicit license.
    Added.

    Update:

    The library is now able to load points and boxes, but there are missing useful methods for you guys, like collision queries.

    Drawing them is only possible via the debugDraw method (so before debugDrawing objects, you need to call "player.calcBoundingBox(null)").

    Object infos are also getting loaded now and bones are rendered properly.

    I also discovered some new bugs today while testing the SpriterAnimationArtPack. I hope I can fix them as far as possible.

    Roadmap:

    After fixing those bugs and adding some more useful features, like animation listeners, I will begin to refactor many things, cause I really don't like the structure.

    I hope this won't be a big impact on your current projects.

    After this, I will try to add skinning support. I think skinning is more important than sounds for now (sound support is just another reference mapping and could also be used now,

    with some clever directory structure and a modification of the frontend loader class (when loading a file just check the file type)).

    -Trixt0r

  16. My main difference is manipulating the pivot points before the draw, as Shiva only has a centred pivot point.

    I see. It looks like you are drawing some parts without taking into account that the origin of the sprites are centered by your engine. Then you should try to recalculate the final sprite position by moving it half of the width to the left and half of the height to the bottom (or the other way around).

    Somehting like:


    calculate position x, y with pivot points...
    move x by -sprite_width/2
    move y by -sprite_height/2
    render sprite at x,y

    Maybe the y value is a different, since I do not know how your engine draws pixels on the y-axis.

    I think the fact it's missing the targets simply means they should be defaulted, i.e. The map is just the standard images.

    Then a character map with no targets makes no sense to me. Why should Spriter save such a useless character map?

    -Trixt0r

  17. The generateData() method takes quite a long time, because it searches for the maximum amount of bones and objects inside an entity. It scans the whole entity again. This can take a quite long time, if you have many animations. I don't know how I could improve the method, since the SCML file is only saving the bones and objects itself, but has no information about how many an entity actually has. But I could refactor the SpriterKeyFrameProvider.generateKeyFramePool() method, which is basically merging mainline and timelines together. In my opinion this is really redundant since I already parsed the information and don't have to move that information into other objects (by the way, this uses not only much CPU time but also fills the RAM). Anyway, to refactor this, I need much time because I need to think about a good design pattern.

    And I have a new update for you guys: interpolation curves. You are now able to use any kind of curves: instant, linear, quadratic, cubic, quartic, quintic and bézier.

    I did not test the feature very much, but from what I can tell you, it works.

    If you or your animators are creating new keyframes, I recommend you, that you use the "key all" button, to ensure, that every object occurs in every keyframe, even if the object's values aren't changed at all. The library has a problem with this, but I will see what I can do, to fix it.

    The next update will maybe cover boxes and control points, but I can not promise.

    Have fun with the curves!

    - Trixt0r

  18. Hi lucid,

    I am a little bit confused about calculating curved interpolation.

    It is no problem to calculate the curves, saved in the timeline keys.

    But I don't know how to combine them with the curves, saved in the mainline key frames.

    Let's say the mainline looks like this:







    ...
    ...

    and now I am also applying another curve on the root bone, let's say:










    ...

    How do you combine those two curves?

    Another problem is, that I don't know how you apply the x1,y1,x2,y2 values, saved for the bezier curves, to the angle or to the alpha parameter.

    Are you just taking the x-values or y-values or do you have a specific formula?

    Edit: I found a solution for the bezier problem. For anybody who is going to have the same problem: have a look at this post.

    Edit 2: Ok, I solved the other problem on my own. The trick is to interpolate the normalized time t with the mainline key curve.

    Thanks for your help!

    -Trixt0r

×
×
  • Create New...