lucid Posted November 16, 2015 Author Report Share Posted November 16, 2015 Added functions startResumePlayback(), and pausePlayback(). Now playback automatically pauses after a non-looping animation completes, and resumes whenever you setCurrentAnimation(). Completed bone debug display, and added an example. Since bones aren't normally in the zOrder where rendering is done Settings::enableDebugBones must be true when creating a new instance for them to work. Then (as with renderDebugPoints and renderDebugBoxes), Settings::renderDebugBones must be true when you want to see them . Added some convenience functions to check the value of a variable without having to retrieve it in a separate step. getStringValue, getIntValue, and getRealValue. Specify either the objectName and a variableName to retrieve the value from an object, or just the variableName to retrieve it from that entity. Attempting to retrieve a value that isn't there will just return 0 or an empty string, and output an error if you have an error callback set. Completed animation blending. To use this just setCurrentAnimation(animationName, blendTimeInMilliseconds). This does work with sub-entities as well, so if you have the same sub-entity on both animations, with a different sub-entity animation on each, those sub-entity animations will also blend. Also, the elapsed time ratio is also blended. What this means is that if you have two animations, for instance a 4 second walk loop, and a 2 second run loop, and each has the same foot forward first, it will sync correctly, and the animation will appear to slow down as it blends towards walk, or speed up as it blends towards run, rather than speed up the walk, or slow down the run to keep them the same length. Please let me know if you run into any issues. Quote Link to comment Share on other sites More sharing options...
conceptgame Posted November 17, 2015 Report Share Posted November 17, 2015 Cool! Really good job. I will now be able to update it to the Clickteam Fusion 2.5 tool. For what I have seen so far it should be straightforward from my existing implementation. Mike at BrashMonkey and lucid 2 Quote Link to comment Share on other sites More sharing options...
Mike at BrashMonkey Posted November 17, 2015 Report Share Posted November 17, 2015 Awesome news. Glad it's useful to you conceptgame! cheers. Quote Link to comment Share on other sites More sharing options...
lucid Posted November 18, 2015 Author Report Share Posted November 18, 2015 Ok. I've tested this with quite a few Spriter projects, and ended up finding and fixing an edge case that wasn't displaying correctly. I also updated the readme with instructions for the recent additions, and added CMake as @labsin suggested, for easier cross-platform usage. The implementation is now essentially complete, but of course please continue to report any bugs and make any suggestions. Also, if anyone gets it working using other engines or xml or json loaders, and you don't mind me linking to your implementation(s) (preferably under the zlib license), please let me know in this thread. cheers! Quote Link to comment Share on other sites More sharing options...
Breush Posted November 18, 2015 Report Share Posted November 18, 2015 @lucid Hey, awesome work! That does fix some animations issues I had left. Thanks! No more problem so far. Oh, in fact, one problem: "SpriterEngine Error: EntityInstance::getFile - file id -1 out of range", any idea why this happens? You should take the pugixml loader from there: https://github.com/Breush/SpriterPlusPlus As my fork won't be useful anymore, I'll just delete it. Well, I might make a final pull request fixing the compiler warnings (signed/unsigned comparisons + constructors reorder). Quote Link to comment Share on other sites More sharing options...
lucid Posted November 18, 2015 Author Report Share Posted November 18, 2015 @Breush Thanks! I added the pugixml loader. As far as the getFile error, if you don't mind, please email me the Spriter project you're using, and I'll see if I can find out what's going on. Quote Link to comment Share on other sites More sharing options...
Breush Posted November 18, 2015 Report Share Posted November 18, 2015 29 minutes ago, lucid said: @Breush Thanks! I added the pugixml loader. As far as the getFile error, if you don't mind, please email me the Spriter project you're using, and I'll see if I can find out what's going on. I found out what the problem was, and it was not SpriterPlusPlus fault but mine.Reason was: I use a "model" image to place the different limbs of my animation correctly in Spriter. However, it becomes useless once in game. So I removed the line "<file id="6" ... />" by hand (back in the day) from the SCML file. But the current loader is guessing the file id, and not reading it, so all files id afterwards where wrong for SpriterPlusPlus. That's it. (Reloading the broken file in Spriter and saving a new version fixed it easily).) lucid 1 Quote Link to comment Share on other sites More sharing options...
Breush Posted November 24, 2015 Report Share Posted November 24, 2015 I wanted to encode a collision box in Spriter using the "box" feature. Can I retrieve the current box bounds in SpriterPlusPlus by its name "hitbox"? And I noticed the box is in the zOrder even if renderDebugBoxes is disable, is this expected behiaviour? Quote Link to comment Share on other sites More sharing options...
lucid Posted November 24, 2015 Author Report Share Posted November 24, 2015 thanks @labsin for the recent commit @Breush, you can use: UniversalObjectInterface *myBox = myEntityInstance->getObjectInstance("hitbox"); you can then use myBox->getPosition() myBox->getAngle(); myBox->getScale(); myBox->getPivot() * myBox->getSize(); as needed. I can probably add something to help get the bounds in another format if needed, but probably not until after the upcoming Spriter release. Since Spriter allows you to set the zOrder for boxes and points, which has come in handy for a couple of users using either or both for spawning objects or displaying non-Spriter items within the zOrder, we've left it in there. If needed I can also add something like the 'enableDebugBones' option in settings for enabling the boxes and points in zOrder. Quote Link to comment Share on other sites More sharing options...
Breush Posted November 25, 2015 Report Share Posted November 25, 2015 @lucid Thank you so much for your answer. Using "getObjectInstance()" seems very logical, I did not see it sooner somehow. However, I'm always getting (0, 0) via myBox->getSize(). (Even after a myEntityInstance->reprocessCurrentTime()). So, I suppose there's a bug. By the way, what's the convention for size and scale: do the size is the effective one (already scaled)? For the zOrder, that's all right, I guess it's not a big overhead. I was just wondering. And, I suppose it would require a Spriter update to enable boxes/points with no zOrder information. Quote Link to comment Share on other sites More sharing options...
Breush Posted December 1, 2015 Report Share Posted December 1, 2015 Just one more remark: you should replace the calls to getObjectInstance(std::string objectName) by getObjectInstance(const std::string& objectName) in order to avoid useless object construction. Quote Link to comment Share on other sites More sharing options...
lucid Posted December 5, 2015 Author Report Share Posted December 5, 2015 On 11/25/2015, 11:27:34, Breush said: @lucid . I'm always getting (0, 0) via myBox->getSize(). (Even after a myEntityInstance->reprocessCurrentTime()). So, I suppose there's a bug. By the way, what's the convention for size and scale: do the size is the effective one (already scaled)? @Breush Sorry for the late reply. I thought I had already replied to this, and been focused on the next version of Spriter itself. I just tested it and I'm not getting the getSize() bug. It gives me the proper dimensions. If you're still having this issue, please email me the file and I'll see what I can find out. The size is the unscaled size. For the current size multiply size and scale; On 12/1/2015, 6:50:41, Breush said: Just one more remark: you should replace the calls to getObjectInstance(std::string objectName) by getObjectInstance(const std::string& objectName) in order to avoid useless object construction. Thanks. Fixed in the latest commit. Quote Link to comment Share on other sites More sharing options...
labsin Posted December 9, 2015 Report Share Posted December 9, 2015 I'm writing a Qt implementation. I also include a documentwrapper using QtDom (a xml library). It seems this library doesn't provide access to xml attributes in a specific order (this is according to xml spec). So I've made a pull request to not expect the attributes to be in the right order. I've also used Valgrind to check for memory leaks and found a bunch of issues. I've added commits for that in the same pull request. Feel free to cherry-pick what you want. I also noticed something strange. In EntityInstanceData::setObjectInstance and other methods of the class, the id's already exist. So if you do ...map.insert(...) it basically does nothing, yet a new object is created in the method that's never deleted. I've added a check and a error message. I didn't check where the double id's came from. Quote Link to comment Share on other sites More sharing options...
lucid Posted December 9, 2015 Author Report Share Posted December 9, 2015 Thanks @labsin . I will look into everything you mentioned. I'm finishing up the next version of Spriter, so I most likely won't get a chance to look into it the next few days. Quote Link to comment Share on other sites More sharing options...
labsin Posted December 10, 2015 Report Share Posted December 10, 2015 I've uploaded my WIP on github under SpriterPlusPlusQt Quote Link to comment Share on other sites More sharing options...
labsin Posted December 11, 2015 Report Share Posted December 11, 2015 My SpriterPlusPlusQt is now in a working state. You should now be able to build and run it. Using it from QML is very easy. I created an example that's more or less the same as the SFML one (creating 100 random entities). Each frame is 10ms, so performance is good. Now I need to add more features (sound, ...) and optimize a bit. Still a question, are there some dimensions on the animation as a whole I could use? A bounding box. lucid 1 Quote Link to comment Share on other sites More sharing options...
Breush Posted December 14, 2015 Report Share Posted December 14, 2015 On 10/12/2015 at 1:46 AM, labsin said: I've uploaded my WIP on github under SpriterPlusPlusQt Good job! Quote Link to comment Share on other sites More sharing options...
jeremyjh Posted December 19, 2015 Report Share Posted December 19, 2015 I've started an integration of SpriterPlusPlus into Cocos2d-X, a new library called Spriter2dX. It does not yet have much platform support (only tested with CMake for Linux) but I will be adding that as I finish integrating this into the game I am developing. I expect to have Android done very soon, other platforms may follow and of course I'll take pull requests for them. I found this pretty easy to do, I think SpriterPlusPlus has a pretty good design for extension points. Cocos2d-X has a very different rendering system than for example SFML - so the ImageFile override had to work considerably differently. In Cocos2dX we don't just render a sprite to the screen, instead each object on the screen has a persistent object in a scene graph which will get rendered in a batch. So to work in the SpriterPlusPlus model I have each CCImageFile manage a pool of cocos2d::Sprite objects that it will position for a single tick. I have an example where I ported shamelessly robbed SpriterPlusPlus's example and its able to run 100 Grey Guy animations at about 50 fps on my laptop, haven't tried it with a real GPU. Quote Link to comment Share on other sites More sharing options...
labsin Posted December 20, 2015 Report Share Posted December 20, 2015 5 hours ago, jeremyjh said: I've started an integration of SpriterPlusPlus into Cocos2d-X, a new library called Spriter2dX. It does not yet have much platform support (only tested with CMake for Linux) but I will be adding that as I finish integrating this into the game I am developing. I expect to have Android done very soon, other platforms may follow and of course I'll take pull requests for them. I found this pretty easy to do, I think SpriterPlusPlus has a pretty good design for extension points. Cocos2d-X has a very different rendering system than for example SFML - so the ImageFile override had to work considerably differently. In Cocos2dX we don't just render a sprite to the screen, instead each object on the screen has a persistent object in a scene graph which will get rendered in a batch. So to work in the SpriterPlusPlus model I have each CCImageFile manage a pool of cocos2d::Sprite objects that it will position for a single tick. I have an example where I ported shamelessly robbed SpriterPlusPlus's example and its able to run 100 Grey Guy animations at about 50 fps on my laptop, haven't tried it with a real GPU. Great to see the CMake changes getting used by someone. I had the same problem with the qt 5 screne graph port. With the added problem that the nodes need to be created from a separate thread when asked to by the renderer. I solved it by relying on the zOrder returned by the sprite entity. This seems to be reliable. And the vectors aren't removed when they change so it's safe to keep the pointer to it. Quote Link to comment Share on other sites More sharing options...
lucid Posted December 20, 2015 Author Report Share Posted December 20, 2015 On 12/11/2015 at 7:00 PM, labsin said: My SpriterPlusPlusQt is now in a working state. You should now be able to build and run it. Using it from QML is very easy. I created an example that's more or less the same as the SFML one (creating 100 random entities). Each frame is 10ms, so performance is good. Now I need to add more features (sound, ...) and optimize a bit. Still a question, are there some dimensions on the animation as a whole I could use? A bounding box. Awesome work, @labsin. The reason there isn't a bounding box function is that the bounding box for an animation as a whole would change with the framerate. It wouldn't be an extreme change, but a few pixels of clipping on an engine relying on it would be noticeable. 6 hours ago, jeremyjh said: I've started an integration of SpriterPlusPlus into Cocos2d-X, a new library called Spriter2dX. It does not yet have much platform support (only tested with CMake for Linux) but I will be adding that as I finish integrating this into the game I am developing. I expect to have Android done very soon, other platforms may follow and of course I'll take pull requests for them. @jeremyjh Excellent. 7 hours ago, jeremyjh said: Cocos2d-X has a very different rendering system than for example SFML - so the ImageFile override had to work considerably differently. In Cocos2dX we don't just render a sprite to the screen, instead each object on the screen has a persistent object in a scene graph which will get rendered in a batch. So to work in the SpriterPlusPlus model I have each CCImageFile manage a pool of cocos2d::Sprite objects that it will position for a single tick. 1 hour ago, labsin said: I had the same problem with the qt 5 screne graph port. With the added problem that the nodes need to be created from a separate thread when asked to by the renderer. I solved it by relying on the zOrder returned by the sprite entity. This seems to be reliable. And the vectors aren't removed when they change so it's safe to keep the pointer to it. @labsin and @jeremyjh . Since it's already come up twice, I added sprites (SpriteObjectInfo) to the ObjectFactory. I'm not sure if this will or would have eased the process, but the idea would be that you could create your SpriteObjectInfo to contain a reference or pointer to your engine or framework's persistent objects. Then you can override ::render(), and get all of the information you need there. This should hopefully reduce the steps and workarounds needed for systems with persistent objects. Please let me know if this would help the situation, and/or if there needs to be some additional information passed to the constructor to make it useful. Quote Link to comment Share on other sites More sharing options...
jeremyjh Posted December 20, 2015 Report Share Posted December 20, 2015 I think this is a good idea @lucid - I will give it a try as I think it will be cleaner code and may also make certain features easier should I decide to try to implement them, such as integrating the Cocos2d Physics system. lucid 1 Quote Link to comment Share on other sites More sharing options...
jeremyjh Posted December 21, 2015 Report Share Posted December 21, 2015 Are triggers a supported feature yet? If so I am kind of confused by them, it seems playEventTriggers() will play the triggers every time its called, regardless of if we've reached that point in the animation. playTrigger() is getting called every tick. Quote Link to comment Share on other sites More sharing options...
conceptgame Posted December 29, 2015 Report Share Posted December 29, 2015 Hi lucid, I am working on the CF25 and I am facing again against the same problem. I solved it with my old implementation but this time with the new implementation I cannot figure out which part I missed. The windows port on Clickteam Fusion 2.5 is based on Direct3D that is why I needed to change this to have left handed convention: void TransformProcessor::transformChildObject(UniversalObjectInterface *childObject) const { point parentScale = parentObject->getScale(); childObject->setScale(multiply(childObject->getScale(), parentScale)); if (parentScale.x*parentScale.y < 0) { childObject->setAngle( - childObject->getAngle()); } childObject->setAngle(childObject->getAngle() + parentObject->getAngle()); childObject->setAlpha(childObject->getAlpha()*parentObject->getAlpha()); point childPosition = childObject->getPosition(); point preMult = multiply(childPosition, parentScale); // Left Handed rotation in CF2.5 (Direct3D convention) // p'x = p.x * c + p.y * s; // p'y = -p.x * s + p.y * c; childPosition.x = (preMult.x * angleCos) + (preMult.y * angleSin); childPosition.y = -(preMult.x * angleSin) + (preMult.y * angleCos); childObject->setPosition(add(childPosition, parentObject->getPosition())); } In settings.cpp, I have set the following: bool Settings::reverseYOnLoad = true; bool Settings::reversePivotYOnLoad = true; bool Settings::reverseAngleOnLoad = false; Did I forget something obvious? At the moment it looks like this (top left it is another object): Quote Link to comment Share on other sites More sharing options...
labsin Posted December 29, 2015 Report Share Posted December 29, 2015 1 hour ago, conceptgame said: ... In settings.cpp, I have set the following: bool Settings::reverseYOnLoad = true; bool Settings::reversePivotYOnLoad = true; bool Settings::reverseAngleOnLoad = false; ... Instead of changing the values in the engine, you can overwrite them in your implementation with calling the following somewhere: SpriterEngine::Settings::reverseYOnLoad = true; Quote Link to comment Share on other sites More sharing options...
lucid Posted December 29, 2015 Author Report Share Posted December 29, 2015 6 hours ago, conceptgame said: Did I forget something obvious? At the moment it looks like this (top left it is another object): Which animation is that? Also it looks like the legs are in the normal position - does the animation play stably, or is there constant rotation and flipping of the whole character? 6 hours ago, conceptgame said: // Left Handed rotation in CF2.5 (Direct3D convention) // p'x = p.x * c + p.y * s; // p'y = -p.x * s + p.y * c; Is this code used somewhere? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.