UI animation engine
Moderators: CEGUI MVP, CEGUI Team
UI animation engine
EDIT by Kulik for the googlers: CEGUI has inbuilt animations since 0.7.2 - viewtopic.php?f=5&t=5049 http://www.cegui.org.uk/wiki/index.php/Animation_System
Hi Everyone,
Recently while working on my Ogre school project I created a small animation engine for CEGUI. It animate CEGUI windows based on keyframes defined in a xml file.
It can animate CEGUI::windows using all CEGUI properties, including
position
size
text
image
alpha, and more
The full source codes and a youtube video sample are found at http://www.gamedboy.com
It is rather painful to animate CEGUI windows in codes, so I hope this would be useful to the community.
Jeffrey
Hi Everyone,
Recently while working on my Ogre school project I created a small animation engine for CEGUI. It animate CEGUI windows based on keyframes defined in a xml file.
It can animate CEGUI::windows using all CEGUI properties, including
position
size
text
image
alpha, and more
The full source codes and a youtube video sample are found at http://www.gamedboy.com
It is rather painful to animate CEGUI windows in codes, so I hope this would be useful to the community.
Jeffrey
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Ok, I found the archive file I had for UIAE.
Be aware that this code is still a third party item written by and copyright Jeffrey Jiang. The package was released by the author under the Creative Commons Attribution-Noncommercial-Share alike 3.0 license.
Please also be aware that I have not had time to test this at the moment, and as such I do not know if it works at all; all the usual disclaimers apply. I am just making it available as a favour to the community since it appears not to be available elsewhere at present.
The file can be downloaded here
I'll try and do some testing sometime soon, in the mean time please feel free to post your experiences (though do not moan and nag - this is not my product, and it appears the author is not responding here at the moment).
CE.
Be aware that this code is still a third party item written by and copyright Jeffrey Jiang. The package was released by the author under the Creative Commons Attribution-Noncommercial-Share alike 3.0 license.
Please also be aware that I have not had time to test this at the moment, and as such I do not know if it works at all; all the usual disclaimers apply. I am just making it available as a favour to the community since it appears not to be available elsewhere at present.
The file can be downloaded here
I'll try and do some testing sometime soon, in the mean time please feel free to post your experiences (though do not moan and nag - this is not my product, and it appears the author is not responding here at the moment).
CE.
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
I'm 99% likely to be spending this weekend on CEGUI related dev work (whoo hoo!) - mainly attacking the outstanding bugs, but I also hope to get time to try this out. I'll post a 'log' of my experiences once I get around to doing it
I don't think it's something we've discussed at any great length.
There is actually the beginnings in the system for a window to have a 'Task' assigned to it, basically to transition from one state to another (or whatever) over time, though this is largely unused at present, and probably needs some expansion / work. There's certainly nothing XML based currently.
A while ago (meaning, years ago) I had some plans to expand the Imageset to support animated image sequences - this is something that may come to fruition, albeit maybe not Imageset based anymore (yes, CE is the master of doublespeak!). What I mean by this is that for the eventual renderer updates, while the Imageset concept will still be present in the system, it will be also possible to reference parts of textures directly, so any animation system would more likely be based on that approach than the current Imageset system (nothing concrete; just my musings).
CE
maori wrote:btw is there any plans to add something like this into cegui itself ?
I don't think it's something we've discussed at any great length.
There is actually the beginnings in the system for a window to have a 'Task' assigned to it, basically to transition from one state to another (or whatever) over time, though this is largely unused at present, and probably needs some expansion / work. There's certainly nothing XML based currently.
A while ago (meaning, years ago) I had some plans to expand the Imageset to support animated image sequences - this is something that may come to fruition, albeit maybe not Imageset based anymore (yes, CE is the master of doublespeak!). What I mean by this is that for the eventual renderer updates, while the Imageset concept will still be present in the system, it will be also possible to reference parts of textures directly, so any animation system would more likely be based on that approach than the current Imageset system (nothing concrete; just my musings).
CE
heya CE
glad to see your feeling better ( i hope i'am right )
i had a go last night to try and get it to work but no joy here i proberbly done something wrong (more than likely ) so if you do get a chance between your dev work pls could you make a basic little tutorial on how and what you did to make it work ie steps needed
Thanks
glad to see your feeling better ( i hope i'am right )
i had a go last night to try and get it to work but no joy here i proberbly done something wrong (more than likely ) so if you do get a chance between your dev work pls could you make a basic little tutorial on how and what you did to make it work ie steps needed
Thanks
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
maori wrote:glad to see your feeling better ( i hope i'am right )
Yeah, I'm on top of the world
Ok. I have spent a little time playing around with uiae and have managed to get it to function.
First a couple of things to be aware of - especially if you did not look at the uiae package yet:
- There are no makefiles / project files provided.
- There is no code example provided (though there is an example animations xml file).
- Documentation is present, though a little sparse
To tackle these points one by one:
Makefiles / Project Files
This is no big issue. The user is free to either make a library or just include all the sources into your app. For the sake of my tests and the example below, I incorporated all the uiae files into my application. All you have to remember is to properly set the include search paths for CEGUI and any other stuff you'll be using, and to add any required libs for the linking stage.
No Example Code
Possible stumbling block for those not used to hacking / figuring out other peoples stuff, though I provide a working example below.
Sparse Documentation
Beggars can't be choosers! There are docs, and where information is maybe lacking, the uiae code is pretty simple to follow; so looking at the uiae code generally yields the answers needed.
Fell at the first hurdle?
Compiling the code gave me my first issue The includes statements, in the files Animation.h and UIAnimationManager.cpp, use the 'cegui' prefix approach:
Code: Select all
#include <cegui/cegui.h>
this is not too much of an issue, at least not for me on linux. The issue I really had was the all lower-case, where we should have had:
Code: Select all
#include <CEGUI/CEGUI.h>
Making these changes allowed the code to compile successfully.
Ok. Now we have the thing building, what do we do with it?
The basic usage of uiae is:
1) Initialise the system by calling:
Code: Select all
uiae::UIAnimationManager::instance();
2) Load one or more xml files containing the animation lists (more on that in a moment):
Code: Select all
animMgr->loadAnimationsFromFile("./sample.xml");
3) Add the CEGUI window that you want to be affected by uiae, specifying an ID string to refer to this window within uiae, and the name of the animation list that contains the animations that you want to use with the specified window:
Code: Select all
animMgr->addWindow(wnd, "1", "misc");
4) Set the animation state for each window registered. What this basically means is specify which animation from the registered animation list you want to be active on the window. The window is referred to by its uiae ID, not it's CEGUI name:
Code: Select all
animMgr->setAnimationState("1", "bounce");
5) Somewhere within your main app loop, you have to call the update function so that the animations update(!). This takes the same input as the CEGUI::System::injectTimePules function, so is easily called in the same location:
Code: Select all
animMgr->update(elapsed / 1000.f);
Now some further explanation.
For this you should refer to the sample.xml file in the uiae distribution, this is the file we loaded in step 2 above.
In step 3 we added window 'wnd' - this is a pointer to a CEGUI::Window. The "1" parameter is a unique ID string that you choose to refer to the Window within uiae. The "misc" is the name of an animation list that has been loaded. If you look in sample.xml, the first animation list defined in there is called "misc" and this is where that came from.
In step 4 we set the animation state. This basically specifies the specific animation from the animation list ("misc" from step 3) that we want to be active at the given moment on the window with uiae ID "1" (which we also specified in step 3). In the code for step 4 we specify "bounce". If you again look at sample.xml, within the animation list named "misc", there is an animation named "bounce" - this is where that came from.
Step 5 is performed, as mentioned, in your main loop and tells the uiae system how much time has passed, in seconds, since the previous call to update.
Final, working code example
Below is the code for a complete working example (well, it works here anyway!). It uses OpenGL/GLUT and is somewhat hacked together, with some nice global variables thrown in for good measure. Most of the code is setup code or code to make the demo run (GLUT callbacks for CEGUI events and rendering). The steps above are commented where they appear in the code. Steps 1 through 4 are in main, while step 5 is in the drawFrame function.
Note also that I hard coded in the resource manager paths from my system. Obviously you may need to change these to be something more appropriate for your own systems!
Code: Select all
#include <GL/glut.h>
#include <CEGUI.h>
#include <CEGUIDefaultResourceProvider.h>
#include <RendererModules/OpenGLGUIRenderer/openglrenderer.h>
#include "UIAnimationManager.h"
// GLUT callback prototypes
void drawFrame(void);
void mouseMotion(int x, int y);
void mouseButton(int button, int state, int x, int y);
void keyChar(unsigned char key, int x, int y);
// super global vars!
bool G_quitFlag = false;
CEGUI::OpenGLRenderer* G_renderer = 0;
uiae::UIAnimationManager* G_animMgr = 0;
int G_lastFrameTime = 0;
// app entry point
int main(int argc, char* argv[])
{
using namespace CEGUI;
// Do GLUT init
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("CEGUI / UIAE Test");
glutSetCursor(GLUT_CURSOR_NONE);
// register callbacks
glutDisplayFunc(drawFrame);
glutMotionFunc(mouseMotion);
glutPassiveMotionFunc(mouseMotion);
glutMouseFunc(mouseButton);
glutKeyboardFunc(keyChar);
// initialise basic CEGUI system
G_renderer = new OpenGLRenderer(1024);
new System(G_renderer);
// initialise the required dirs for the DefaultResourceProvider
DefaultResourceProvider* rp = static_cast<DefaultResourceProvider*>
(System::getSingleton().getResourceProvider());
rp->setResourceGroupDirectory("schemes", "/usr/local/share/CEGUI/schemes/");
rp->setResourceGroupDirectory("imagesets", "/usr/local/share/CEGUI/imagesets/");
rp->setResourceGroupDirectory("fonts", "/usr/local/share/CEGUI/fonts/");
rp->setResourceGroupDirectory("layouts", "/usr/local/share/CEGUI/layouts/");
rp->setResourceGroupDirectory("looknfeels", "/usr/local/share/CEGUI/looknfeel/");
rp->setResourceGroupDirectory("lua_scripts", "/usr/local/share/CEGUI/lua_scripts/");
// set the default resource groups to be used
Imageset::setDefaultResourceGroup("imagesets");
Font::setDefaultResourceGroup("fonts");
Scheme::setDefaultResourceGroup("schemes");
WidgetLookManager::setDefaultResourceGroup("looknfeels");
WindowManager::setDefaultResourceGroup("layouts");
ScriptModule::setDefaultResourceGroup("lua_scripts");
// we will make use of the WindowManager.
WindowManager& winMgr = WindowManager::getSingleton();
// load scheme and set up defaults
SchemeManager::getSingleton().loadScheme("TaharezLook.scheme");
System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");
if(!FontManager::getSingleton().isFontPresent("Commonwealth-10"))
FontManager::getSingleton().createFont("Commonwealth-10.font");
// create root window
DefaultWindow* root = (DefaultWindow*)winMgr.createWindow("DefaultWindow", "Root");
// set root as the active GUI sheet
System::getSingleton().setGUISheet(root);
// create a FrameWindow for the test
FrameWindow* wnd = (FrameWindow*)winMgr.createWindow("TaharezLook/FrameWindow", "TestWindow");
// add the frame window to the root
root->addChildWindow(wnd);
// set window initial position and size
wnd->setPosition(UVector2(cegui_reldim(0.25f), cegui_reldim( 0.25f)));
wnd->setSize(UVector2(cegui_reldim(0.5f), cegui_reldim( 0.5f)));
// set window text
wnd->setText("UIAE Demo Window");
// initialise the uiae system
// *** Step 1 from the artice ***
G_animMgr = uiae::UIAnimationManager::instance();
// load the sample animations that came with uiae
// *** Step 2 from the artice ***
if (G_animMgr->loadAnimationsFromFile("./sample.xml"))
{
// add the FrameWindow to be managed by uiae, using anims from the "misc" list
// *** Step 3 from the artice ***
if (G_animMgr->addWindow(wnd, "1", "misc"))
{
// set window ID "1" to use the "bounce" animation (from the "misc" list).
// *** Step 4 from the artice ***
G_animMgr->setAnimationState("1", "bounce");
}
}
// start loop
glutMainLoop();
return 0;
}
void drawFrame(void)
{
// do time based updates
int thisTime = glutGet(GLUT_ELAPSED_TIME);
float elapsed = static_cast<float>(thisTime - G_lastFrameTime);
G_lastFrameTime = thisTime;
// inject the time pulse (CEGUI and UIAE)
CEGUI::System::getSingleton().injectTimePulse(elapsed / 1000.0f);
// *** Step 5 from the artice ***
G_animMgr->update(elapsed / 1000.f);
// do rendering for this frame.
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 12, 0.0, 0.0, -100, 0.0, 1.0, 0.0);
CEGUI::System::getSingleton().renderGUI();
glFlush();
glutPostRedisplay();
glutSwapBuffers();
// handle quit conditiion
if (G_quitFlag)
{
G_animMgr->cleanup();
// cleanup cegui system
delete CEGUI::System::getSingletonPtr();
delete G_renderer;
// exit
exit(0);
}
}
void mouseMotion(int x, int y)
{
CEGUI::System::getSingleton().injectMousePosition(x, y);
}
void mouseButton(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if (state == GLUT_UP)
{
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
}
else
{
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
}
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_UP)
{
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
}
else
{
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);
}
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_UP)
{
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);
}
else
{
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);
}
break;
}
}
void keyChar(unsigned char key, int x, int y)
{
// extract some keys may be handled via key code and generate those too
switch (key)
{
case 0x08: // backspace
CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::Backspace);
break;
case 0x7F: // delete
CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::Delete);
break;
case 0x1B: // Escape
G_quitFlag = true;
break;
case 0x0D: // CR (Return)
CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::Return);
break;
default:
// inject Character code
CEGUI::System::getSingleton().injectChar(static_cast<CEGUI::utf32>(key));
break;
}
}
Just to reiterate, this is not supposed to be a shining example of how to code - it's just a quick-and-dirty hack that shows uiae in action.
Hope it's useful
CE.
Return to “Offtopic Discussion”
Who is online
Users browsing this forum: No registered users and 5 guests