OpenGL Exported animation from Blender to my game is kind of distorted.(+gif)

Recommended Posts

Guys, I animated some FPS arms model in Blender 2.77, because I need it for my game. But when I load it into my game using the Assimp Library, it is messed up.

(click on picture)

[attachment=33095:fpshandsmessedup.gif]

Some say it is because of Blender's vertex weight issues, others say that it doesn't export to collada properly. And I can't use .fbx because assimp has a really bad support for it. Guys, any suggestions are welcome. I spent 20+ hours on this, and if I figure out the reason why this happens maybe I can find a way to fix it.

The interesting thing is that when I use open3mod which is the assimp model viewer, there aren't distortions, but when I use assimp library in openGL to load the model, it loads really bad, and models from the internet are working fine that's why my guess is that the problem is in Blender, not in my code, I don't why this happens, really.

Edited by codeBoggs

Share on other sites

* what is the format of your export ?

* maybe a link to this file ?

* any code maybe ?

Also, if this works fine with the assimp model viewer, then it certainly means that there is a bug somewhere in your code. Compare both your code and the one in the assimp loader.

Share on other sites
what is the format of your export ?

maybe a link to this file ?

any code maybe ?

All the code for the animation loading is maybe more than 1000 lines, that's why I won't post it here, but I do all the loading using assimp and other animated models I download from the internet work perfectly fine, so it can't be the code ( it's mostly from tutorials ). pretty sure it's blender's fault but I don't know exactly what the reason for this is.

Edited by codeBoggs

Share on other sites

_Silence_, you were right. My code was the problem. There is a problem in the blender collada exporter which is connected with blender's vertex weight stuff, because the rig seems messed up, but that distortion I have that starts from the finger is because of my code here.

I tried to optimize this:

const aiNodeAnim* Model::FindNodeAnim(const aiAnimation* pAnimation, const string NodeName)
{
for (uint i = 0 ; i < pAnimation->mNumChannels ; i++)   //Go through all animation channels stored by assimp
{
const aiNodeAnim* pNodeAnim = pAnimation->mChannels[i];    //Get the name of the current animation channel

if (string(pNodeAnim->mNodeName.data) == NodeName)  //Check if the nodeName is the same with the channel name
{
return pNodeAnim; //If it's the same, return the channel
}
}

return NULL;
}


This code finds the proper animation based on the node's name. The big problem with this code is that it searches for the same animations hundreds of time per second and it does very expensive string comparisons and this lowers my fps brutally. But when I use this code, the above animations works perfectly fine although the fps is slow.

But my idea was to store everything in a map container and just use it, instead of comparing strings all the time.

That's why I changed the code to this:

const aiNodeAnim* Model::FindNodeAnim( const aiAnimation* pAnimation, const string NodeName )
{
uint numChannels = pAnimation->mNumChannels;

if( nodeAnimMapping.size() < numChannels ) //If the map contains less elements than the number of channels in the model, then fill the map
{
for ( uint i = 0 ; i < numChannels ; i ++ )
{
const aiNodeAnim* pNodeAnim = pAnimation->mChannels[i];

if ( string( pNodeAnim->mNodeName.data ) == NodeName )
{
if( nodeAnimMapping.find( NodeName ) == nodeAnimMapping.end() ) //If the name is not in the map, add it
{
nodeAnimMapping[ NodeName ] = i;
}
return pNodeAnim;
}
}
nodeAnimMapping[ NodeName ] = numChannels + 10; //Else just put random number that I won't need and return NULL
return NULL;
}
else
{
int nodeIndex = nodeAnimMapping[ NodeName ];
if( nodeIndex < numChannels ) // If the map container is full
{
const aiNodeAnim* pNodeAnim = pAnimation->mChannels[ nodeIndex ]; //Find the animation from the map container
return pNodeAnim;
}
else if( nodeIndex > numChannels )
{
return NULL;
}
}
}

This code is a big optimization, and it works for most models, but not for this one I showed in the .gif. This means there is something wrong with this code, but I don't know what is it.

Share on other sites

I see. You can maybe store your animations inside an std::map for example.

Share on other sites

If the original code is working, go back to the original code. The original code is solid code; just stop calling it over and over again.

You should be running this in a game loop that draws one frame buffer per loop.

I haven't used Assimp yet, but I have written a program that takes animation data for the standard Humanoid Armature in Blender and plays it back as a stick figure. And my program allowed you to select which animation you wanted to play back from the file. So, I'm sure Assimp is doing basically the same thing.

But you don't want this code to run every frame. You want this function to be called when it's time to move to a new animation. That's probably once, and then again when you want to play a different animation, not every frame. This is the "change the animation" code, not the "play the animation" code. Depending on how many animations the file contained, this could be a fairly expensive look-up. Just the fact that it is string based makes it a bit of an ugly lookup. But calling animations by name is easier than by number. All you are trying to do here is to get a pointer to the correct animation by supplying the animation's name; you need that once - not in a loop. So, use something to trigger this call when needed.

If there is only one animation in the file, you may not even need a loop here and can just pick the first one.

But I would probably stick with this. If you call this in your Update() for your game loop when a button is pressed or when some other event occurs signaling a different animation than you'll only run this code once in a blue moon. My program had a switch statement so that if you pressed the right arrow it selected the next animation and if you hit the left arrow it went to the previous animation.

But the code is returning a pointer to an animation. This is just allowing you to select which animation you want since an animation file can contain an infinite number of animations in one file. Usually the animator names the animations and so selecting them by name is pretty natural. Or at least that's what I assume by looking at the code. I imagine what Assimp is calling a channel is a single animation. Then each channel/animation contains a series of key frames. Then you have to provide the animation between the key frames.

The fact that it returns a pointer to an animation is the "efficiency". Look the pointer up when you need to change to a new animation since looking it up by name is the easiest way to do this. But then store the pointer and don't ask for it again until you need a different animation. Looking the animation up by pointer should be pretty efficient.

For those who don't know, the key frames are just poses of the armature (bones that control the model) with a specific frame number. So, if you have 90 frames in the animation and want to run the animation at 30 frames per second, the animation will last 3 seconds. And you may only get 7 key frames. Each key frame will have a frame number it needs to occur at. So for example, you may have the first one on the very first frame and then the second one on the 13th frame and the third on the 27th frame. All those frames in between you need to provide the poses for. So, between the first frame and the 13th frame - for example - you do a weighted average using SLERP to morph the pose of the first key frame into the pose of the 13th frame.

Edited by BBeck

Share on other sites

Guys, thanks a lot for the help. I'm kind of self-taught on this animations stuff and there is always something I don't know. But there's always someone else who knows it.  ^_^

Create an account

Register a new account

• Forum Statistics

• Total Topics
627704
• Total Posts
2978716
• Similar Content

• A friend of mine and I are making a 2D game engine as a learning experience and to hopefully build upon the experience in the long run.

-What I'm using:
C++;. Since im learning this language while in college and its one of the popular language to make games with why not.     Visual Studios; Im using a windows so yea.     SDL or GLFW; was thinking about SDL since i do some research on it where it is catching my interest but i hear SDL is a huge package compared to GLFW, so i may do GLFW to start with as learning since i may get overwhelmed with SDL.
-Questions
Knowing what we want in the engine what should our main focus be in terms of learning. File managements, with headers, functions ect. How can i properly manage files with out confusing myself and my friend when sharing code. Alternative to Visual studios: My friend has a mac and cant properly use Vis studios, is there another alternative to it?

• Both functions are available since 3.0, and I'm currently using glMapBuffer(), which works fine.
But, I was wondering if anyone has experienced advantage in using glMapBufferRange(), which allows to specify the range of the mapped buffer. Could this be only a safety measure or does it improve performance?
Note: I'm not asking about glBufferSubData()/glBufferData. Those two are irrelevant in this case.
• By xhcao
Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness.
• By cebugdev
hi guys,
are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic
let me know if you guys have recommendations.
• By dud3
How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below?
Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.

References:
Code: https://pastebin.com/Hcshj3FQ
The video shows the difference between blender and my rotation:

• 21
• 14
• 12
• 10
• 12