Jump to content

terinfire

Members
  • Posts

    21
  • Joined

  • Last visited

Everything posted by terinfire

  1. 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.
  2. 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!
  3. 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!
  4. EDIT: Figured it out! Got looping working!
  5. 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: 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.
  6. If a parent bone has a spin, but the child does not -- how does that affect it? Or what if the parent is a "1" and the child is a "1" or a "-1"? Do we multiply them? So, from what I can tell, the issue I've bumped into is that the child has a default value of "1" (SpatialInfo)? The more I look at it, the more I think I'm just getting confused because of the frustration involved with the outdated ScmlReference page. It looks like Spin is no longer on the Bone/ObjectTimelineKey, but located above it. EDIT: And that was it! GOT IT! Thanks for the help, lucid!
  7. Didn't help. When we interpolate, which spin parameter do we want? The one from the index, or from index + 1 on the timeline keys? I'm literally reading in Spriter -- this is the data from Spriter -- not any of my own data. So the angle will be the exact same representation as it is in the file. I tried reversing the order of the items getting interpolated as well, but that didn't help. The issue seems to occur *somewhere* in the interpolation. Can you maybe look over the algorithm itself one more time and check to see if the process is correct? 1) Find Current Mainline Key (loop through mainline keys, find the LAST one that has time <= current time) 2) (For Bones) Find the Timeline's associated with this Mainline Key. 2.a) Find the TimelineKey associated from this, as well as the next logical TimelineKey (if one exists). 2.b) Get the stacked Bone transformations and store them. 3) (For Objects) Find the Timeline's associated with this Mainline Key. 3.a) Find the TimelineKey associated from this, as well as the next logical TimelineKey (if one exists). 3.b) Get the object and apply parent transformations. The interpolation has to be wrong somewhere. I'm just not sure where. Any help would be appreciated. Maybe the interpolation is correct, but for some reason the order or bones are wrong? I'm not sure. EDIT: Spin appears to be coming back as 1, when it should be 0 -- will double check/investigate further.
  8. Awesome! I'm almost there! I have it rendering perfectly for if it just shows the individual points and doesn't interpolate (unless Progress through either is either a 0 or a 1). I found out that I had an issue wherein I didn't interpolate correctly, so I only had Progress between Primary & Secondary Timeline Key's was a whole number. Now, when I interpolate, (converting it to floating point before it does the division) I seem to be having issues. The arms spin around on the default model like he's going crazy... or doing propeller arms against some bad guy. Kind of a funny effect, but wrong. For the interpolation for angles, the parameters per the SCML (angleA, angleB, int spin, float t) would correspond to (PrimaryTimelineKey.Angle, SecondaryTimelineKey.Angle, PrimaryTimelineKey.Spin, Progress) wherein Progress is... Single Progress = ( (Single) ( Milliseconds - PrimaryTimelineKey.Time ) ) / ( SecondaryTimelineKey.Time - PrimaryTimelineKey.Time ); (Milliseconds is the amount of time that has passed for the animation, and lies between 0 and animation.Length). Do we have to do any weird interpolation on spin? Is there anything special we have to follow for the spin itself? I'm just trying to figure out why my character is going nuts and choppy on a few of the animations... Just for the sake of it, here's the code I have (TimelineObjectReference is essentially a return with all of the data for each "frame" after being transformed): public List GetTimelineObjects() { List results = new List(); if ( Reference != null && EntityID != INVALID && AnimationID != INVALID ) { Animation CurrentAnimation = GetCurrentAnimation(); MainlineKey CurrentMainlineKey = GetCurrentMainlineKey( CurrentAnimation ); List BoneReferences = new List(); for ( int i = 0; i < CurrentMainlineKey.BoneReferences.Count; i++ ) { int TimelineIndex = CurrentMainlineKey.BoneReferences[i].Timeline; int TimelineKeyIndex = CurrentMainlineKey.BoneReferences[i].Key; int NextTimelineKeyIndex = TimelineKeyIndex; if ( NextTimelineKeyIndex < CurrentAnimation.Timelines[TimelineIndex].Keys.Count - 1 ) { NextTimelineKeyIndex++; } TimelineKey PrimaryTimelineKey = CurrentAnimation.Timelines[TimelineIndex].Keys[TimelineKeyIndex]; TimelineKey SecondaryTimelineKey = CurrentAnimation.Timelines[TimelineIndex].Keys[NextTimelineKeyIndex]; TimelineObjectReference Bone; if ( PrimaryTimelineKey == SecondaryTimelineKey ) { Bone = GetTimelineObjectReference( PrimaryTimelineKey.Bone ); } else { Single Progress = ( (Single) ( Milliseconds - PrimaryTimelineKey.Time ) ) / ( SecondaryTimelineKey.Time - PrimaryTimelineKey.Time ); Bone = GetInterpolatedTimelineObjectReference( PrimaryTimelineKey.Bone, SecondaryTimelineKey.Bone, Progress ); } if ( CurrentMainlineKey.BoneReferences[i].Parent != BoneReference.DEFAULT_PARENT ) { Bone = ApplyTransformations( BoneReferences[CurrentMainlineKey.BoneReferences[i].Parent], Bone ); } BoneReferences.Add( Bone ); } for ( int i = 0; i < CurrentMainlineKey.ObjectReferences.Count; i++ ) { int TimelineIndex = CurrentMainlineKey.ObjectReferences[i].Timeline; int TimelineKeyIndex = CurrentMainlineKey.ObjectReferences[i].Key; int NextTimelineKeyIndex = TimelineKeyIndex; if ( NextTimelineKeyIndex < CurrentAnimation.Timelines[TimelineIndex].Keys.Count - 1 ) { NextTimelineKeyIndex++; } TimelineKey PrimaryTimelineKey = CurrentAnimation.Timelines[TimelineIndex].Keys[TimelineKeyIndex]; TimelineKey SecondaryTimelineKey = CurrentAnimation.Timelines[TimelineIndex].Keys[NextTimelineKeyIndex]; TimelineObject PrimaryTimelineObject = PrimaryTimelineKey.Object; if ( PrimaryTimelineKey == SecondaryTimelineKey ) { TimelineObjectReference Object = GetTimelineObjectReference( PrimaryTimelineObject ); if ( CurrentMainlineKey.ObjectReferences[i].Parent != MainlineObjectReference.DEFAULT_PARENT ) { Object = ApplyTransformations( BoneReferences[CurrentMainlineKey.ObjectReferences[i].Parent], Object ); } Object.FileID = PrimaryTimelineObject.File; Object.FolderID = PrimaryTimelineObject.Folder; results.Add( Object ); } else { try { Single Progress = ( ( Milliseconds - PrimaryTimelineKey.Time ) ) / ( SecondaryTimelineKey.Time - PrimaryTimelineKey.Time ); TimelineObject SecondaryTimelineObject = SecondaryTimelineKey.Object; TimelineObjectReference Object = GetInterpolatedTimelineObjectReference( PrimaryTimelineObject, SecondaryTimelineObject, Progress ); if ( CurrentMainlineKey.ObjectReferences[i].Parent != MainlineObjectReference.DEFAULT_PARENT ) { Object = ApplyTransformations( BoneReferences[CurrentMainlineKey.ObjectReferences[i].Parent], Object ); } Object.FileID = PrimaryTimelineObject.File; Object.FolderID = PrimaryTimelineObject.Folder; results.Add( Object ); } catch ( Exception ) { } } } } return results; } //Code for the interpolation, for the sake of it, but is a copy of the ScmlReference stuff on your website public static Single Linear( Single pA, Single pB, Single pPercentComplete ) { return ( ( pB - pA ) * pPercentComplete ) + pA; } public static Single AngleLinear( Single pStartAngle, Single pEndAngle, Single pPercentComplete, Int32 pSpin ) { if ( pSpin == 0 ) { return pStartAngle; } if ( pSpin > 0 ) { if ( ( pEndAngle - pStartAngle ) < 0 ) { pEndAngle += 360; } } else if ( pSpin < 0 ) { if ( ( pEndAngle - pStartAngle ) > 0 ) { pEndAngle -= 360; } } return Linear( pStartAngle, pEndAngle, pPercentComplete ); } And remember -- the Progress (when 0 or 1) seems to render the animation fine -- just choppy (since there is no transition between the frames). It would be nice to release this assembly/code to everyone as soon as I get it "correct" so others can use it. I'll probably include a C#/XNA/MonoGame example of the code, so others can use it, along with notes on how to render/process the result, such that we can avoid a lengthy (and information -- thank you!) discussion again. Thank you, lucid! Hopefully we can nail this down.
  9. OK, sorry -- one more question. I got a little over-excited that at least things were showing up in the correct position. The animations are very choppy. I have a feeling it has something to do with some of the Mainline Key's having points that are not existent in the Timeline. For example, in the main sample that comes with Spriter, the head moves at time=2473, but the legs/arms do not have any key during that time... So I'm not sure how it works. What my process for drawing at the moment is: 1) Find the current animation 2) Find the primary mainline key that it is on 3) Find the secondary mainline key that is next (And we have to interpolate between, should be primary + 1 index) 4*) Loop through the bones and store the transforms in advance (per your advice -- this is good) 5) Loop through the object references in the primary mainline key 5.1) Find the primary timeline key that we are currently on 5.2) Find the secondary timeline key that is next (and we have to interpolate between, should be primary + 1 index) 5.3*) If there is a parent to this (a bone), apply the transformations So, for most of this, as I said, it renders correctly. But I think when it bumps into these points where the mainline (which has 15 items of bone/object's). The timeline with id=0 only has 12 items... I think there is some kind of issue with how to interpret the results for this when looping through the mainline. It's hard to read the SCML and figure out how it's interpolating for these points by hand. The problem *has* to lie here.
  10. So, funny enough, those things seemed to help! Funny, I tried it before and had no luck, but it works now -- so thank you! I just need to fix my actual animation renderer -- seems like I'm going a little too fast through things right now and that it isn't properly tweening it towards the end -- but otherwise, it's pretty good!
  11. So, I've tried to go through the routine of applying the transformations, and it looks like I'm getting "closer." I've attached the image -- I'm using the standard "walking" animation. He appears to be drawn partially upside down and the animation seems to be all kinds of funky... But, it does look closer, at least. Still trying to make sense of some of the specification -- it's really challenging. Is it safe to assume that for each Timeline Key, there will be only ONE object beneath it? Either a bone or an object? Thanks!
  12. Sorry to double post -- but I think I checked out the document you provided. So, the formulas for unmapping (so the parent's scalar values are applied correctly to the child) are in the document. Then is my process otherwise correct? And how about pivot points for bones? So, end of day -- if I built SpatialInfo every frame, the only piece it would need now would be the FolderID/FileID to know WHICH image to paint and where?
  13. That doesn't help me much -- you've made the mud slightly more translucent, but not much. So, let's say I'm doing what you're talking about. I would walk through the MainlineKey's -- bones included. If an object_ref has a parent, that refers to its bone? So, if I see a parent=0, that means to refer to the value in its parent, where the bone_ref id=0? And bones can be connected to bones, but an object_ref is only connected to a bone, yes? So for the example of bone_ref id=1, the parent bone is id=0. And object_ref id=0's parent is bone_ref id=1? Then do all of the values scale down the hierarchy? i.e. if bone_ref id=0 has x = 2, y = 4, and bone_ref id=1 has x = 3, y = 5, the total "scaled" value for bone_ref id=1 is x = 2 + 3 (5) and y = 4 + 5 (9)? And then, would I scale the object_ref referring to parent bone_ref = 1 by the values there? (i.e. x = +5, y = +9) ? Assume I have this correct -- I don't see any information on the bone's point of rotation, etc? When I read, pivot_x/y correspond to the: 0,0 (bottom left) to 1, 1 (top right) of the image -- so if you get .5, .5, that would mean the center of the image -- so if the image is 60 x 50, the center (effectively) for rotating is 30, 25? And how do scale_x/y work? Do they apply to the X/Y coordinates only, or also the width/height? Whew! Sorry, I know this is a lot to ask, but I'm trying very hard to understand how everything works together and how the data correlates. Right now, I have a very ugly mess, and I'd desperately like to make it work!
  14. Alright, maybe I'm an idiot, but I'm *really* struggling with how to draw things. I can take care of the actual drawing, but I think my positioning and angles, etc, are not correct. Is there a process for "drawing" and building up each animation? I understand that we have to tween between animations, i.e. if we're between two key-frames, we need to interpolate what occurs between each -- not a problem. But how do each of the transformations work? At the moment, I have something that looks like HP Lovecraft wrote -- a bunch of bizarre, mangled body parts that are floating around unusually... I'm animating based off of Timeline Objects only -- but I'm assuming at this point that this assumption is wrong. Do I have to find the bones, then find which objects are referenced to them, and then transform the bones, then transform the objects? Is there a clear way on how to look at this, even if pseudo code, i.e. Scan Mainline. Get a Key. Get the two key frames you can potentially be between. Find out the Timeline for each. Get the Timeline Object and then calculate the Linear/Cubic/Quadratic tweened variables between the two and render. (this is what I'm currently doing) Am I missing something? Thank you!!!
  15. Awesome to know, Lucid! Also -- I'm implementing Spriter and having some issues with actually rendering it. Was curious if anyone had any good documentation on how we should read it. It looks like (for the most part) you grab the actual Timeline objects and any other data (like width/height of the object) seems to be coming from the actual Folder/File structure. Aside from that, if we just read the Mainline and run through the keys for objects, that should be enough, right? Or is that incorrect? http://www.brashmonkeygames.com/spriter ... MLGuide(a2).pdf That was the latest I could grab of the spec sheet... Thanks!
  16. Hey, just a quick, wild speculation... I think the z-ordering is wrong. Either you're drawing it incorrectly (in the wrong order) or your code is loading the z_index incorrectly. And maybe some good news for Unity developers (maybe not, though)... I'm working on a generic C# library that loads all of this for you -- you'll still need to draw it, but I'm going to try to get ALL of the guesswork out of it -- i.e. load the SCML file, handle the objects and animate/deform them. You'll still have to render them, but at that point, it'll just be reading the pieces of data in from the current handle you have to an animation/etc, and then draw based on that information. My question is -- does anyone in the Unity side of things know which version of .NET they support? How far up are they? I need to use *at least* 3.0, I believe (because my mapping functions rely on Action. It may even be possible to port it back to .NET 2.0 (if I manually create an Action), but no promises on that -- I haven't done enough exploration into it to see if that'll work. Let me know, if anyone from Unity has some technical knowledge or can hunt it down for me!
  17. OK, while I understand this guy's sentiment, I believe he's asking... Is there a final SCML standard (that the team working on Spriter will be going against)? I have similar issues at the moment -- I'd like to know what I'm building against, to be validated, since I'm working on a generic C# library to load/use it. I've validated against b6.1 -- but I know there's probably more stuff that has intention of being loaded. Any advice/help from the Spriter team?
  18. Thanks for the assistance -- but I actually *just* (as in two minutes ago) finished my library to load the SCML, for the most part. My only concern is that this was done against the b6.1 release -- and I know a new version has been released, possibly with new data structures and the like. Does anyone have any formatted file dumps from b7+ ? I don't care if it's just the SCML, so I can try to validate it and see what I haven't caught yet.
  19. I was hoping to have something that was actually portable, though. It looks like everyone has written something that is bound to a specific technology -- I literally just want something that loads the data and has the correct schema in the format of classes (and that is broken out clearly). I think that it would be something 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. Thoughts?
  20. Hello, I'm looking at the documentation as well and it looks like there's a big gap between what has been released and what is written in the specification. I was hoping on building a C# library on this, but it looks like I have to wait until v.1.0 is out -- which is a little frustrating, since I'd like to get working on things now. In the very least, how much do things change in the SCML object model? I imagine you only really "add" fields in -- you don't actually just completely tear out what works and intend on replacing pieces? Is there anything that will be useful to keep track of what the old and new look like, and specifically, what will need to be added (ala something like a merge tool view of things)? What language are you guys building the tools in? Is there any chance of you just publishing the libraries that you're using already internally? Or, as I hate to ask, is there any time table for when v.1.0 will be ideally released (something even as simple as quarter of the year/etc)? I just don't want to start working on this and have half of my work be pointless and get nuked. Warm regards.
  21. Hey folks, I was planning on writing a C# Spriter implementation, since it seems like there aren't any (aside from a Unity one -- which I may look at). If there are, please direct me so I don't waste my time. Are there any good, complete API's that have been built already in another language? I've seen a number of incomplete/antiquated ones. I'd prefer if there is a more C#-like language (so Java, C++, etc), but I'm partial to anything. That being said, is there a good implementation out there? I'm considering using Trixt0r's Java version, since it looks used the most, but I wasn't sure if someone else had something that was bug-free, etc. I think it'd be easier to read the logic and implement, rather than attempt to guess the logic/rules. I think it'd be easier to implement a library based on someone else's code where the logic is complete, rather than try to implement missing features in another. I was hoping to make this mostly platform independent and provide another way to spawn references to animation -- I don't like the idea of pushing a character THROUGH an animation -- but it makes sense to have some kind of factory to create an instance of an animation, or have a lightweight object that someone can hold within a class, which holds a reference to the real animation and can update itself according to that. Any help is appreciated!
×
×
  • Create New...