Jump to content

Trixt0r

Members
  • Posts

    118
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Trixt0r

  1. Hey guys,

    Sorry for the double post.

    As an experiment I tried and managed to port all my Java code to C#: https://github.com/Trixt0r/SpriterXNATest

    Now there is no need for ikvm. In the repo is still an XNA test. The source code should also run with any other backend since the implementation only uses the "System" and "Generics" namespaces. This means you could create easily a Spriter plugin for e.g. Unity, Playstation Mobile SDK (tested my port here and got the same result as in XNA), or any other game engine which uses C#. ;)

    Maybe I will bring some updates in the repo as the Java library evolves.

    -Trixt0r

  2. Hey guys,

    I worked a little bit further on the library and made some changes in the inverse kinematics handling. If you want to apply inverse kinematics on a player you just need an instance of SpriterIKResolver class, which is an abstract class, means you need a specific algorithm to solve the constraints. Anyway, there is a SpriterCCDResolver class, which does the job for you.

    To apply inverse kinematics create a SpriterIKObject instance and map it to a bone or a sprite with

    yourResolver.mapIKObject(ikObject, boneOrSprite);

    and in your update logic method just call

    yourResolver.resolve(yourPlayer);

    to resolve the whole stuff.

    Before calling resolve(yourPlayer), you need to deactivate all effectors, otherwise the resolver will have no effect on the animation:

    yourResolver.deactivateEffectors(yourPlayer, true);

    If you do not want the resolver to apply IK for some reason, just call:

    yourResolver.activateEffectors(yourPlayer);//Activates all effectors which where mapped before
    //or
    yourResolver.activateAlll(yourPlayer);//To activate all bones, no matter if they were mapped or not

    Play with it around.

    The drawing works also a little bit different now. Your specific drawer needs now to implement drawLine, drawRectangle and setDrawColor. This enables the ability for the AbstractDrawer class to debugDraw an animation for every backend in the same way.

    The FileLoader class gets now notified if all textures have been loaded. You can just reimplement the method finishLoading if necessary (to generate an atlas or whatever).

    Character mapping is not implemented yet, but you can bypass this issue by creating a new loader for each character map and pass the loader to your player. I need an example file to implement the feature. I would really appreciate if someone could upload one, since I do not have Spriter Pro.

    Furthermore I created a little demonstration video, to show you some features of the library:

    The runnable demo can be downloaded via a link in the video description.

    -Trixt0r ;)

  3. @JeffreyWalraven: There is no problem with the library. Your example runs fine for me. Your fault is, that you didn't put the folder name of the scml file into the path name:

    "Spriter-Error-Example/basic.scml"

    and the error occurs because the texture files were not found and thus no references were put into the files map (well this was my fault, because the loader does not throw any exceptions, i'll fix that).

    @aspiretocode: They mean the runtime of your specific game. The LibGDX loader class packs already all loaded textures into an atlas (which was made for testing purposes and is not perfect yet), which was quite easy to implement. Have a look at the code, maybe it can help you to make your own backend specific atlas.

    Anyway. I ported the LibGDX XmlReader. This means now, that the JAXB parsing stuff is no longer needed and parsing scml files should run anywhere (even if you want to port the library to another language ;P).

    For people who did use the GdxSpriter class: Now you should just call

    Spriter.getSpriter("scml file path", yourLoader);

    to get all spriter data and there should not be any problems on Android, HTML5, iOS or any other crazy operating system.

    For people who are working with C# and XNA: I managed to create a library for C#, which allows you to use the Java library with any C# game library. Here is an example for XNA. :D

    I am still fixing things in the library. Please post bugs in this thread or create issues on github, which can help me fixing them.

    - Trixt0r

  4. Hmmm... This error can only occur, if there is no reference created. Did you manipulate the SpriterLoader class or are you using a second thread to load the scml file?

    Could you please post the scml file with its textures, so I can have a closer look on this issue?

    - Trixt0r

  5. Hey guys!

    I was working today a little bit on the plugin and cleaned up my git repo. The maven project is now replaced with a clean eclipse project. I also added a new LibGDX example.

    For people who don't use eclipse and Java:

    Here is a runnable version of the LibGDX example (sorry for the size, but the native files are quite big). You can load new SCML files into the program by pressing CTRL+O (if you don't see any opening dialog, move the window to the left or right, it could be behind the main frame).

    The plugin is still a work in progress and I have to work on the tweening since the new Spriter betas brought new features into the scml file.

    The main problem right now is that the tweening is not working properly for animations with partially keyframed objects and bones. So if you want to work now with the plugin, make sure, that on every keyframe all objects and bones are keyframed otherwise you will get weired effects.

    - Trixt0r

  6. I want just mentoin some things to this topic:

    Implementing inverse kinematics with the Box2D (or any other 2D physics engine) is quite a very nice idea.

    But a step in this direction would make every plug-in too specific. Think of programers which want to use Spriter but do not need any physics engine (or do not want to use one, because of performance issues).

    Or some which want to use a physics engine, but not Box2D.

    I think it is good, if the plugin supports runtime bone/object control. If the plugin supports such a feature, it should be very easy to implement inverse kinematics.

    I already added those two features in the generic java implementation and it was not that hard (have a look at it ;)).

    Moreover I think you would get some performance problems if you connect a physics body to every bone.

    You could e.g. just use some sensors (in Box2D) for the feet or hands (one sensor for a foot/hand) and if the inverse kinematics implementation is general enough, everything should work as you wish.

    Just my opinion, but connecting Box2D bodies to every bone, just to get inverse kinematics working is a bit too much. Correct me if I am wrong.

    - Trixt0r

  7. I created a tool which converts my old animation files (which where created with my bone animation tool for the Game Maker 8.0) into scml files.

    The problem in the current build of Spriter is, that it draws the sprites in the same way it loaded them from the scml file. The "z_index" is not considered when Spriter loads a file. Spriter is just inferring the "z_index" from the order of the objects and this makes the variable "z_index" in the scml file useless. I think Spriter should just infer the "z_index" from the object order, if the objects do not have a "z_index" as an attribute in the scml file. Do you agree?

    I do not know how strong the coupling between the classes in your code is, but to fix this you may need 5 minutes of work (just sort the objects by "z_index", and that's it). And if YOU would fix this problem, you would still support all other scml file generation tools, since this is a Spriter internal issue.

    I will send you the project folder as I get back from university ;) .

    See ya!

  8. Nice work lucid, but I have two things to complain about:

    1. The sprites are not drawn in z-order which was read from file. This problem was still in the alpha release (and I already mentioned it in the bugtracker), but there Spriter has drawn the sprites only per keyframe in the right order, but not in an interpolated frame. Now every key draws the sprites in a wrong order. To show what I mean, here's a picture:

    Here's a snippet of the z_index structure:

    zorder.png































    I think this issue is not that hard to fix (my plugin draws the sprites in a right order :P).

    2. I don't know what you have changed, but this release runs much slower than the first B0 release. This means, that the animations are not played back fluently in my above shown project (which has currently about 40 different animations).

    I hope you can fix those bugs ;)

    See ya!

  9. And the 4th post :mrgreen:

    Hi guys,

    I managed to increase the speed for LibGDX. I modified the SpriterLoader class such that the loader saves the sprites into an atlas. This makes a very big boost. Here is a screenshot:

    benchmarkh.png

    ImageShack.us

    Should be 60 fps at around 930 instances. Without using an atlas, I just get 217 @60fps. I think this is a very big boost. And the core which was executing the application was not on full utilization. So the speed depends on the current graphics card. Anyone who is using LibGDX can get the class here:

    /**************************************************************************
    * Copyright 2013 by Trixt0r
    * (https://github.com/Trixt0r, Heinrich Reich, e-mail: trixter16@web.de)
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    ***************************************************************************/

    package com.spritertest;

    import java.util.Set;

    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.Pixmap;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.Texture.TextureFilter;
    import com.badlogic.gdx.graphics.g2d.PixmapPacker;
    import com.badlogic.gdx.graphics.g2d.Sprite;
    import com.badlogic.gdx.graphics.g2d.TextureAtlas;
    import com.badlogic.gdx.graphics.g2d.TextureRegion;
    import com.badlogic.gdx.utils.Disposable;
    import com.brashmonkey.spriter.file.FileLoader;
    import com.brashmonkey.spriter.file.Reference;

    public class SpriterLoader extends FileLoader implements Disposable{

    private PixmapPacker packer;
    private boolean pack;

    public SpriterLoader(boolean pack){
    this.pack = pack;
    }

    @Override
    public void load(Reference ref, String path) {
    if(packer == null && this.pack) packer = new PixmapPacker(512, 256, Pixmap.Format.RGBA8888, 2, true);
    Pixmap pix = new Pixmap(Gdx.files.internal(path));
    if(packer != null) packer.pack(ref.fileName, pix);

    files.put(ref, this.createSprite(new Texture(pix)));

    pix.dispose();
    }

    private Sprite createSprite(Texture texture){
    texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    TextureRegion region = new TextureRegion(texture,0,0,texture.getWidth(),texture.getHeight());
    Sprite sprite = new Sprite(region);
    sprite.setSize(texture.getWidth(), texture.getHeight());
    return sprite;
    }

    public void generatePackedSprites(){
    TextureAtlas atlas = this.packer.generateTextureAtlas(TextureFilter.Linear, TextureFilter.Linear, false);
    Set keys = this.files.keySet();
    this.disposeNonPackedTextures();
    for(Reference ref: keys){
    TextureRegion texReg = atlas.findRegion(ref.fileName);
    Sprite sprite = new Sprite(atlas.findRegion(ref.fileName));
    sprite.setSize(texReg.getRegionWidth(), texReg.getRegionHeight());
    files.put(ref, sprite);
    }
    }

    private void disposeNonPackedTextures(){
    Set keys = this.files.keySet();
    for(Reference ref: keys)
    files.get(ref).getTexture().dispose();
    }

    @Override
    public void dispose() {
    if(this.pack && this.packer != null) this.packer.dispose();
    else this.disposeNonPackedTextures();
    }

    }

    It would be really nice, if Spriter would calculate the maximum size for a texture to save all sprites per file. Then we would need just one page (texture) for all parts.

    See ya.

  10. T T T Tripple post!!!!!

    Hey guys!

    I almost finished with the plugin (well from my point of view ^^) and added some new cool features.

    I created a wiki, which explains you, how to use the plugin: Wiki.

    What's left: Support for inverse kinematics. I will try to implement the CCD algorithm and let users the ability to change the algorithms via an interface or an abstract class.

    For performance: I noticed that using an atlas can give you a quite big performance boost (especially in LibGDX). Running animations without drawing textures runs quite well. On my machine I get 60 fps with about 400 to 500 instances of a SpriterPlayer (with 15 bones and 14 objects). So if you run into some performance issues, try to pack the loaded textures into an atlas, because I can not do it for every framework.

    See ya!

    Edit: Inverse kinematics is supported now. I implemented an ISpriterIKResolver interface, which can be used to implement other algorithms. A SpriterPlayerIK uses this interface, so if you want IK in your game, use this player. I already implemented the CCD algorithm.

  11. Hey guys,

    sorry for the double post. I worked again a little bit on the spriter plugin and fixed the some transition issues between two animations, and modified the SpriterDrawer class.

    Now it is possible to change the sprites for a whole entity. Basically you have to add an extra loader and let the Spriter class load the extra textures and store them in the new loader:

    loader = new SpriterLoader();
    loader2 = new SpriterLoader();
    drawer = new SpriterDrawer(loader,spriteBatch);
    Spriter spriter = FatSpriter.getSpriter("data/monster/basic.scml", loader);
    Spriter.getSpriter("data/monster_mod/basic.scml", loader2);

    And if you want to change the skin, you just have to assign the other loader to your drawer:

    drawer.loader = loader2;

    This is just a temporary solution. I have to work a little on the structure, so that you have the ability to change just bodyparts and not the whole body.

    I hope I can finish this soon.

    If you have wishes for other features, let me know, I will try to implement them.

    See ya!

  12. Yes, I already implemented such a feature in the Generic Java Plugin (which is not perfect yet -.-).

    I don't think Spriter needs this feature because if you create extra animations for the tweening between two animations, you spend more space (yes some bytes, haha) on the hdd and you will need to code more since you need to distinguish between the last and the new animation.

    If your plugin has this feature already you don't have to care about such problems. You only need to change the animations by the object's state and say on which speed you want to tween the animations. The rest should be taken by the plugin. And the calculation effort should be the same as on a normal animation since the plugin should calculate the transformation between two keyframes.

    A problem, which Spriter and the plugins can't bypass, is that, as Mike already mentioned, the order of your objects. So every animation needs the same bone/object structure otherwise you will get very weird animation tweenings.

  13. Hi grofie,

    thanks for the reply. I cleaned up the repo (I think...).

    If you use LibGDX you won't need to distinguish which Spriter class you have to use, just use GdxSpriter.java.

    GdxSpriter is always using the internal file system. If you don't like it, you can change getSpriter and pass a FileHandle object, which points to the scml file, instead of the file path.

    If you are not using LibGDX you can use the Spriter class. But beware! JAXB does run on a desktop system fine, but it may be that it is not supported on an other system like on Android. That's why I had to re-implement the SCML parser for LibGDX. So if you run into parsing problems, you will have to implement your own parser for the specific platform (it's quite easy, you can have a look into the private methods in GdxSpriter.java).

    You mentioned the whole animation stuff runs on android emulator very slow, but it runs also on a normal cell phone slow (I tested the monster animation on my Sony Xperia Sola, 1GHz dual core).

    Well, if I run just one SpriterPlayer instance, I get 62 fps, that's good. But if you have about 10 players at runtime, the fps drops down to 30-35. So beware, if you want to run this on slow devices, my friends. You have either to reduce the number of objects and bones for an animation or run your game on 30 fps. Maybe I can figure out some performance issues.

    On my desktop computer the situation is much better. I get 60 fps while running 217 instances of SpriterPlayer at a 3GHz core. On a 2GHz core the whole thing runs at 60 fps while running about 100 SpriterPlayer instances. I think that is ok, if you don't plan to create games á la Little Fighter 2 with massive gang fights :D. Otherwise your games have to support mutlithreading.

    Trixt0r out!

×
×
  • Create New...