Currently I'm trying to make a game engine in C++ with OpenGL and want to get 3D animations to work. I have been advised to use Assimp and was able to find a tutorial to get static models to work, but I have no idea where to even start with animations. I have been trying to Google it, but haven't been able to find anything that works. How can I modify my code to get animations? What file format is recommended for it?
This is the code I have currently:
//Mesh.h
#include <string>
#include "glut\include\GL\glew.h"
#include "glut\include\GL\glut.h"
#include <assimp/Importer.hpp> // C++ importer interface
#include <assimp/scene.h> // Output data structure
#include <assimp/postprocess.h> // Post processing fla
//textures
#include <SOIL.h>
class Mesh
{
public:
Mesh(void);
Mesh(std::string filename, std::string textureFilename, float x, float y, float z, float width, float height, float depth, float rotX, float rotY, float rotZ);
~Mesh(void);
void Init(std::string filename);
void LoadTexture(std::string textureName);
void Draw();
private:
GLfloat *vertexArray;
GLfloat *normalArray;
GLfloat *uvArray;
GLint numVerts;
GLuint m_Texture[1];
float m_CenterX, m_CenterY, m_CenterZ, m_Width, m_Height, m_Depth;
float m_XRotation, m_YRotation, m_ZRotation;
};
//Mesh.cpp
#include "Mesh.h"
Mesh::Mesh(void)
{
}
Mesh::Mesh(std::string filename, std::string textureFilename, float x, float y, float z, float width, float height, float depth, float rotX, float rotY, float rotZ)
{
//fills in variables
Init(filename);
LoadTexture(textureFilename);
}
Mesh::~Mesh(void)
{
}
void Mesh::Init(std::string filename)
{
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(filename,aiProcessPreset_TargetRealtime_Fast);//aiProcessPreset_TargetRealtime_Fast has the configs you'll need
aiMesh *mesh = scene->mMeshes[0]; //assuming you only want the first mesh
numVerts = mesh->mNumFaces*3;
vertexArray = new float[mesh->mNumFaces*3*3];
normalArray = new float[mesh->mNumFaces*3*3];
uvArray = new float[mesh->mNumFaces*3*2];
for(unsigned int i=0;i<mesh->mNumFaces;i++)
{
const aiFace& face = mesh->mFaces[i];
for(int j=0;j<3;j++)
{
aiVector3D uv = mesh->mTextureCoords[0][face.mIndices[j]];
memcpy(uvArray,&uv,sizeof(float)*2);
uvArray+=2;
aiVector3D normal = mesh->mNormals[face.mIndices[j]];
memcpy(normalArray,&normal,sizeof(float)*3);
normalArray+=3;
aiVector3D pos = mesh->mVertices[face.mIndices[j]];
memcpy(vertexArray,&pos,sizeof(float)*3);
vertexArray+=3;
}
}
uvArray-=mesh->mNumFaces*3*2;
normalArray-=mesh->mNumFaces*3*3;
vertexArray-=mesh->mNumFaces*3*3;
}
void Mesh::LoadTexture(std::string textureName)
{
glGenTextures(1, &m_Texture[0]);
glBindTexture(GL_TEXTURE_2D, m_Texture[0]);
// Set our texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // NOTE the GL_NEAREST Here!
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // NOTE the GL_NEAREST Here!
m_Texture[0] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
textureName.c_str(),
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
}
void Mesh::Draw()
{
glPushMatrix();
glTranslatef(m_CenterX, m_CenterY, m_CenterZ);
glRotatef(m_XRotation, 1, 0, 0);
glRotatef(m_YRotation, 0, 1, 0);
glRotatef(m_ZRotation, 0, 0, 1);
glScalef(m_Width, m_Height, m_Depth);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT,0,normalArray);
glTexCoordPointer(2,GL_FLOAT,0,uvArray);
glVertexPointer(3,GL_FLOAT,0,vertexArray);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_Texture[0]);
glDrawArrays(GL_TRIANGLES,0,numVerts);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
}