好吧,我确实设法在无数小时后让它工作!有点……我做了一个循环转换的模型x+5, y+5, x-5, y-5
……我最终做了什么,好吧,无论如何这是我唯一能想到的。正在从场景->mAnimations[] 中读取数据,这基本上只包含一个关键帧数组。所以我不得不自己插入所有的顶点,(这总是一个有趣的任务!)。
有效地:
- 你得到了关键帧应该完全插值的时间。
- 然后减去对象当前所在的位置,以确定您需要移动多少。
- 现在你需要弄清楚每一步要移动多少,所以我采用了最简单的解决方案,将它除以应该分割移动的帧数。
- 现在只需在将所有顶点发送到 VBO 之前更新它们即可。(此步骤可能会根据您的数据设置有所不同)
在这些步骤之后,我得到了如下所示的东西:
标题:
class AssimpMesh {
private:
struct ShaderProgram {
//Shader data
GLuint program;
string programName;
vector <GLuint> shaders, uniforms;
};
struct MeshData {
//Mesh data
GLuint meshArray;
vector <GLuint> buffers;
vector <string> bufferNames;
//Shader data
ShaderProgram *shader;
vector <aiVector3D> transedVertices;
int totalIndices;
};
struct Frame {
vector <MeshData*> meshes;
};
struct Animation {
string name;
vector <Frame*> frames;
};
//Global shader data
ShaderProgram *globalShader;
//Model data
Assimp::Importer importer;
const aiScene *scene;
//Mesh data
bool initialized, perMeshShading;
vector <Animation*> animations;
int currentFrame, currentAnimation;
Uint32 lastFrameTicks;
Transform *transform;
glm::mat4 projectionView;
aiVector3D lightPosition;
void loadScene(string filePath);
void loadAnimation(Animation *animation, int numFrames);
void initMesh(aiMesh *mesh, MeshData *data);
...
public:
AssimpMesh(string filePath);
~AssimpMesh();
void draw();
...
};
资源:
void AssimpMesh::loadScene(string filePath) {
//Load animation file
scene = importer.ReadFile(filePath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality);
if (scene) {
if (scene->HasAnimations()) {
for (int i = 0; i < scene->mNumAnimations; i++) {
aiAnimation *anime = scene->mAnimations[i];
int framesInAnimation = ceil(anime->mDuration * ANIMATION_IMPORT_FPS);
Animation *animation = new Animation();
animation->name = anime->mName.C_Str();
loadAnimation(animation, framesInAnimation);
animations.push_back(animation);
}
}
else {
Animation *animation = new Animation();
animation->name = "Default";
loadAnimation(animation, 1);
animations.push_back(animation);
}
printf("Done loading '%s'\n", filePath.c_str());
}
else {
//Report error
printf("Assimp error: %s\n", importer.GetErrorString());
}
}
void AssimpMesh::loadAnimation(Animation *animation, int numFrames) {
int nextKeyframe = -1;
int nextKeyframeId = -1;
int transedFrames = 0;
aiVector3D transPos = aiVector3D();
aiVector3D transVec = aiVector3D();
for (int f = 0; f < numFrames; f++) {
Frame *frame = new Frame();
if (f > nextKeyframe && nextKeyframe < numFrames) {
//Get the new keyframe
aiAnimation *anime = scene->mAnimations[animations.size()];
aiNodeAnim *aniNode = anime->mChannels[0];
aiVectorKey key = aniNode->mPositionKeys[++nextKeyframeId];
nextKeyframe = ceil(key.mTime * ANIMATION_IMPORT_FPS);
if (!nextKeyframeId) {
transVec = key.mValue;
transPos = key.mValue;
}
else {
int transFrames = nextKeyframe - (f - 1);
aiVector3D transDir = key.mValue - transPos;
transPos = key.mValue;
transVec = transDir;
transVec /= transFrames;
transedFrames = 0;
}
}
if (scene->HasLights()) {
aiLight *light = scene->mLights[0];
//lightPosition = light->mPosition;
}
//Put data into vertex arrays
transedFrames++;
aiMesh *mesh;
MeshData *data;
for (int i = 0; i < scene->mNumMeshes; i++) {
mesh = scene->mMeshes[i];
data = new MeshData();
if (!i) {
for (int j = 0; j < mesh->mNumVertices; j++) {
if (!f) {
data->transedVertices.push_back(mesh->mVertices[j] + transVec);
}
else {
data->transedVertices.push_back(animation->frames[f-1]->meshes[i]->transedVertices[j] + transVec);
}
}
}
//Assign VBO
initMesh(mesh, data);
//Assign shader
if (perMeshShading) {
initShader(mesh, data);
setUniforms(mesh, data);
}
frame->meshes.push_back(data);
}
animation->frames.push_back(frame);
}
}
void AssimpMesh::initMesh(aiMesh *mesh, MeshData *data) {
//Buffer for temporary storage of new ids
GLuint id;
//Make vertex array
if (!initialized) {
glGenVertexArrays(1, &id);
}
data->meshArray = id;
//Tell OpenGL to use this array
glBindVertexArray(id);
//Assign vertices
if (mesh->HasPositions()) {
//Make buffer
if (!initialized) {
glGenBuffers(1, &id);
}
data->buffers.push_back(id);
data->bufferNames.push_back("Positions");
//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, id);
if (data->transedVertices.size()) {
glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * data->transedVertices.size(), &data->transedVertices[0], GL_STATIC_DRAW);
}
else {
glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mVertices[0], GL_STATIC_DRAW);
}
//Set shader attribute data
glEnableVertexAttribArray(VBO_VERTEX);
glVertexAttribPointer(VBO_VERTEX, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
}
unsigned int matId = mesh->mMaterialIndex;
aiMaterial *material = scene->mMaterials[matId];
vector <aiColor3D> colors;
aiColor3D diffuse(0, 0, 0);
material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
for (int i = 0; i < mesh->mNumVertices; i++) {
colors.push_back(diffuse);
}
//Make buffer
if (!initialized) {
glGenBuffers(1, &id);
}
data->buffers.push_back(id);
data->bufferNames.push_back("Colors");
//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, sizeof(aiColor3D) * mesh->mNumVertices, &colors.front(), GL_STATIC_DRAW);
//Set shader attribute data
glEnableVertexAttribArray(VBO_COLOR);
glVertexAttribPointer(VBO_COLOR, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
//Assign texture coords
if (mesh->HasTextureCoords(0)) {
//Make buffer
if (!initialized) {
glGenBuffers(1, &id);
}
data->buffers.push_back(id);
data->bufferNames.push_back("TextureCoords");
//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mTextureCoords[0], GL_STATIC_DRAW);
//Set shader attribute data
glEnableVertexAttribArray(VBO_TEXCORD);
glVertexAttribPointer(VBO_TEXCORD, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
}
//Assign colors
if (mesh->HasNormals()) {
//Make buffer
if (!initialized) {
glGenBuffers(1, &id);
}
data->buffers.push_back(id);
data->bufferNames.push_back("Normals");
//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mNormals[0], GL_STATIC_DRAW);
//Set shader attribute data
glEnableVertexAttribArray(VBO_NORMAL);
glVertexAttribPointer(VBO_NORMAL, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
}
if (mesh->HasFaces()) {
vector <unsigned int> indices;
aiFace face;
for (int i = 0; i < mesh->mNumFaces; i++) {
face = mesh->mFaces[i];
for (int j = 0; j < face.mNumIndices; j++) {
indices.push_back(face.mIndices[j]);
}
}
data->totalIndices = indices.size();
//Make buffer
if (!initialized) {
glGenBuffers(1, &id);
}
data->buffers.push_back(id);
data->bufferNames.push_back("Faces");
//Set buffer data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indices.size(), &indices.front(), GL_STATIC_DRAW);
}
}
当然,它并不适用于所有事情。实际上只有翻译和整个模型。显然它没有正确读取名称值,所以我无法确定动画的用途。但这让我继续前进,也许有人会觉得这很有帮助。=)