Jump to content
Spriter Forums

Generic Java Importer


Discobeard

Recommended Posts

I've been having a bit of trouble manipulating bones at runtime. Currently, I'm using this code in my render loop:

//Update position
player.update(x, y);

//Get torso bone and set angle
SpriterBone torso = player.getBoneByName("Torso");
Vector2 mouseLoc = new Vector2(Gdx.input.getX(), Gdx.input.getY());
Vector2 playerLoc = entity.getComponent(Physics.class).getLocation().toCameraCoords();
float angle = MathUtils.atan2(mouseLoc.y - playerLoc.y, mouseLoc.x - playerLoc.x) * MathUtils.radDeg;
torso.setAngle(angle);

//Render player
spriteBatch.begin();
spriterDrawer.draw(player);
spriteBatch.end();

However, the torso's angle never updates from it's original angle (which is 90 degrees). The player is running an idle animation while I try to do this, but that animation never actually changes the torso in any way, so I'm not sure why the angle won't update. Anyone know what I'm doing wrong?

Link to comment
Share on other sites

  • 2 months later...

Heya, was testing out the plugin seems to work fine except for some reason the ref is null at some times in SpriterObject.java when I change animation.

This causes a nullpointer:


public void setRef(Reference ref){
this.ref = ref;
this.rect.set(ref.dimensions);
}

I changed it to this, it seems to work but i'm not exactly sure how and why the ref is null in the first place, any idea?

	public void setRef(Reference ref){
this.ref = ref;
if(ref == null) return;
this.rect.set(ref.dimensions);
}

Link to comment
Share on other sites

Does this happen with all of your scml files?

I had this happen in the same place but it was because the animations in my scml had different numbers of parts in each keyframe. As long as all keyframes in all animations share the same keyset I seem to be okay.

--

Heya, was testing out the plugin seems to work fine except for some reason the ref is null at some times in SpriterObject.java when I change animation.

This causes a nullpointer:


public void setRef(Reference ref){
this.ref = ref;
this.rect.set(ref.dimensions);
}

I changed it to this, it seems to work but i'm not exactly sure how and why the ref is null in the first place, any idea?

	public void setRef(Reference ref){
this.ref = ref;
if(ref == null) return;
this.rect.set(ref.dimensions);
}

Link to comment
Share on other sites

Sorry guys, for not responding to your questions. I am quite busy now.

@Aniketos: The ref is null in the first place, because the loader is putting a null reference into the texture map and in a next step the actual loaded file reference will replace the the null reference. Are you loading will multiple threads?

@kabb: This is really weird. It should work. Could you send me your whole code?

- Trixt0r

Link to comment
Share on other sites

Ok, I looked into my current version and saw that I already fixed the nullpointer thingy, but did not push it.

The alpha issue is also fixed.

Just pull the new version.

Thank you guys for detecting such bugs.

I will work on the new interplation stuff and character maps as soon as possible.

- Trixt0r

Link to comment
Share on other sites

@Trixt0r: Thanks for the update works like magic :)

Maybe a small suggestion for the next update, I personally added small bit of code in my version of SpriterPlayer which tracks if the animation has been played 1 time and if specific keyframe has been reached. This is handy if lets say you want to play an animation just once or if you want to preform some action mid animation when you reached specific keyframe, lets say you have a fireball spell which you would want to generate a fireball mid animation at specific frame. Anyway something which would give you some more info about the animation.

Link to comment
Share on other sites

  • 2 weeks later...
I will work on the new interpolation stuff and character maps as soon as possible.

Do you have an estimate for the character maps implementation at all?

I am waiting to buy Spriter Pro until I know for sure character maps will work with libgdx. I use libgdx (Java) and char maps are CRUCIAL to my game.

Thank you again for your hard work. You've done some amazing things so far and I can't wait to see char maps included!!! Your demo for libgdx is awesome. Esp the active inverse kinematics!! Well done! Thanks in advance for your reply. There are many of us in the libgdx community who anxiously await your reply.

-Justin C

Link to comment
Share on other sites

Do you have an estimate for the character maps implementation at all?

I could try to implement character maps until the next weekend. I see no chance for me to work on it sooner.

There are many of us in the libgdx community who anxiously await your reply.

:D really? Well, I will try my best to implement the new features asap.

- Trixt0r

Link to comment
Share on other sites

Do you have an estimate for the character maps implementation at all?

I could try to implement character maps until the next weekend. I see no chance for me to work on it sooner.

There are many of us in the libgdx community who anxiously await your reply.

:D really? Well, I will try my best to implement the new features asap.

- Trixt0r

I second this (using Libgdx myself ;) ) !

Link to comment
Share on other sites

I could try to implement character maps until the next weekend. I see no chance for me to work on it sooner.

:D :D :D That is excellent news. Thank you SO much. I can't wait to use this system. To be able to dynamically add an item to my player character on the fly AND have it auto animated is a blessing and one of the most innovative and time saving features a developer could have. Thanks again for your hard work and I'll be anxiously awaiting your work. Cheers! :D

Link to comment
Share on other sites

I really appreciate the amazing amount of effort you put in this generic Importer ^^ you sir desrves a cookie

i have one point that i want to point out , you are using the following code to parse the data :

	public Element parse (InputStream input) throws IOException {
return parse(new InputStreamReader(input, "ISO-8859-1"));
}

Since the parsing occures char by char i assume , is it possible to speed up the parsing if we somehow changed to algorithim to include bufferedreader and invoke the read.line() Method?

something like this :

		BufferedReader BR = new BufferedReader(new InputStreamReader(input, "ISO-8859-1"));

//it does not work since we dealing with char by char
return parse(BR.readLine());

is it possible to do that? i have a a real big Spriter file and i'm looking for a way to speed up loading it , it takes about 4 sec in desktop to load my spriter file and 20 sec on my android galaxy S3

i would very much appreciate it if you have suggestions to speed up reading and parsing the spriter file :)

Link to comment
Share on other sites

I apologize for my upper comment i just realized i made terrible mistake XD

both codes relatively does the same thing (removing readline()) but the real CPU uages comes from the parsing method


@SuppressWarnings("unused")
public Element parse (char[] data, int offset, int length) {

//the long code

return root}

i still wonder if there is away to parse it fast though ;__; 20 sec to load a single spriter is really long

Link to comment
Share on other sites

hey Trixt0r and thx for reading my question ,I came to the conclusion their might be something wrong with the way i'm exporting my project to android , this is what i came up with so far :

----------------------------------------

regarding my project details are the following :

SCML Project 2.21MB

-A single entity with 30 animations diffrent animations

-the images that makes my animations are 100kb in total

-------------------------------------------------------------

it loads extreamlly fast in my pc but in my android it does take ages,,,, what i did is i analyzed the parser further more and while i still get 20 seconds delay , (8 seconds ONLY) are defently from the parser. and 12 seconds are completely unkown to me from where it originates ^^; XD (if 8seconds is fine for 2.21MB file , then i just gotta find the sources for the extra delay)

well i gotta do more testing , seems the issue was mainly in my code before it was from the whole thing lol , still though , thx for giving me some of your time ^^

Link to comment
Share on other sites

You could maybe also test the load time of the FileLoader object. But I think 8 seconds parsing time is okay, if it takes 4 on desktop.

Anyway, I updated the library. As promised, you are now able to use character maps. Implementation was easier than I thought ;).

Character maps can be assigned to any SpriterAbstractPlayer class.

There are two possibilities to assign a character map to a player object:


//1. version just assign a character map to the public field in SpriterAbstractPlayer
player.characterMap = yourCharacterMap;
//2. if your player is a SpriterPlayer instance, just use the setCharacterMap() method
player.setCharacterMap("nameOfYourCharacterMap");

To get a character map, you need an entity from the loaded SpriterData instance and then get a map either via index or by name:


yourSpriterInstance.spriterData.getEntity().get(0).getCharacterMapByName(name);
//or
yourSpriterInstance.spriterData.getEntity().get(0).getCharacterMaps().get(charMapIndex);

The characterMap field of a player instance can be null to behave like Spriter if no map is applied.

If any bugs occur please let me know it, otherwise: Have fun with it!

-Trixt0r

Link to comment
Share on other sites

------------------------------------

regarding The new update Trixt0r, AMAZING JOB XD! really well done and so far it looks flawless :) !! it takes as you said 1 line to change the charachter map XD

player.setCharacterMap("ChangeSword"); did it for me , i really appreciate what you did :D that should cut the loading time for my scml file to half btw lol , coz i had to make 2 copies of each of my animation in the scml coz the char map was not implemented , but now thats solved it is no longer an issue :)

again thank you for the improvments in the library , not the char map only :)

------------------------------------------

More Testing info regarding loading SCML file those who intersted

the following are what i came up with so far , while importing the Spriter SCML file and setting the player there is 3 parts of the code that takes high excution time the more keyframes + animations you have in your project , these following part of codes are the following :

//1 In SCML reader

		public static SpriterData load(InputStream stream) {

XmlReader reader = new XmlReader();
data = new SpriterData();
try {
//The parsing
XmlReader.Element root = reader.parse(stream);
loadFolders(root.getChildrenByName("folder"));
//Loading Entiies takes approx 2/3 of the time you needed to finish the parsing
loadEntities(root.getChildrenByName("entity"));
} catch (IOException e) {
e.printStackTrace();
}
return data;
}

//2 After Trixt0r new library the next part of the code that takes tons of excution time can be found in setEntity in SpriterPlayer

[code]	public void setEntity(Entity entity) {
if (this.entity == entity)
return;
this.entity = entity;
if (!alreadyLoaded(entity)) {

//part 1
this.animations = SpriterKeyFrameProvider.generateKeyFramePool(
this.data, entity);
loaded.put(entity, this);
} else
this.animations = loaded.get(entity).animations;
//Part 2
this.generateData();
}

In general the code is PRETTY fast in all areas EXCEPT for the methods i mentioned above, i hope that someday i might get clues in how to generally improve but for the time being , i'm ok so far XD

---------------------------------------------------

edit : now it takes 8 seconds only to load my file into android after implementing the char map ^^; new size of scnl file 1.15MB;

Link to comment
Share on other sites

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

Link to comment
Share on other sites

Sorry guys, for not responding to your questions. I am quite busy now.

@Aniketos: The ref is null in the first place, because the loader is putting a null reference into the texture map and in a next step the actual loaded file reference will replace the the null reference. Are you loading will multiple threads?

@kabb: This is really weird. It should work. Could you send me your whole code?

- Trixt0r

I ended up figuring out the problem was that I needed to get and use the SpriterModObject for the torso, not the SpriterObject.

Link to comment
Share on other sites

Greeting Trixt0r ,

Thx for the elaboration and the new update!! , i'm going to check it some time this week hopefully :D~

I have one question though:

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

is that the cause of the following error that i get when i have "bounding box object" in my SCML file , or is it because of different error like something is missing in my scml file?

Exception in thread "LWJGL Application" java.lang.RuntimeException: Element object doesn't have attribute or child: folder
at com.brashmonkey.spriter.xml.XmlReader$Element.getInt(XmlReader.java:642)
at com.brashmonkey.spriter.xml.SCMLReader.loadTimelineKeys(SCMLReader.java:314)
at com.brashmonkey.spriter.xml.SCMLReader.loadTimelines(SCMLReader.java:281)

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