- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正尝试按照 here ( at ogldev ) 上的教程进行操作提到in this answer .
然而,我面临一些问题,我认为这些问题与 Assimp 的行主要订单与 GLM 的列主要订单有关,尽管我不太确定。
我已经尝试了一些变体和命令以查看是否有任何效果,但无济于事。
Here ( Gist )是我用来加载完整 MD5 文件的类。以及我目前的结果。
而且,这是我认为出错的部分,当我尝试更新骨骼转换矩阵时。
void SkeletalModel::ReadNodeHierarchyAnimation(float _animationTime, const aiNode* _node,
const glm::mat4& _parentTransform)
{
std::string node_name = _node->mName.data;
const aiAnimation * p_animation = scene->mAnimations[0];
glm::mat4 node_transformation(1.0f);
convert_aimatrix_to_glm(node_transformation, _node->mTransformation);
// Transpose it.
node_transformation = glm::transpose(node_transformation);
const aiNodeAnim * node_anim = FindNodeAnim(p_animation, node_name);
if (node_anim) {
//glm::mat4 transformation_matrix(1.0f);
glm::mat4 translation_matrix(1.0f);
glm::mat4 rotation_matrix(1.0f);
glm::mat4 scaling_matrix(1.0f);
aiVector3D translation;
CalcInterpolatedPosition(translation, _animationTime, node_anim);
translation_matrix = glm::translate(translation_matrix, glm::vec3(translation.x, translation.y, translation.z));
aiQuaternion rotation;
CalcInterpolatedRotation(rotation, _animationTime, node_anim);
// Transpose the matrix after this.
convert_aimatrix_to_glm(rotation_matrix, rotation.GetMatrix());
//rotation_matrix = glm::transpose(rotation_matrix);
aiVector3D scaling;
CalcInterpolatedScaling(scaling, _animationTime, node_anim);
scaling_matrix = glm::scale(scaling_matrix, glm::vec3(scaling.x, scaling.y, scaling.z));
node_transformation = scaling_matrix * rotation_matrix * translation_matrix;
//node_transformation = translation_matrix * rotation_matrix * scaling_matrix;
}
glm::mat4 global_transformation = node_transformation * _parentTransform;
if (boneMapping.find(node_name) != boneMapping.end()) {
// Update the Global Transformation.
auto bone_index = boneMapping[node_name];
//boneInfoData[bone_index].finalTransformation = globalInverseTransform * global_transformation * boneInfoData[bone_index].boneOffset;
boneInfoData[bone_index].finalTransformation = boneInfoData[bone_index].boneOffset * global_transformation * globalInverseTransform;
//boneInfoData[bone_index].finalTransformation = globalInverseTransform;
}
for (auto i = 0; i < _node->mNumChildren; i++) {
ReadNodeHierarchyAnimation(_animationTime, _node->mChildren[i], global_transformation);
}
}
我当前的输出:
我尝试遍历代码中使用的每个矩阵来检查我是否应该转置它。我是否应该更改矩阵乘法顺序。我找不到我的问题。
如果有人能在这里指出我的错误或指导我阅读其他教程以帮助我加载动画,那就太好了。
另外,我看到了在学习这个的初始阶段使用基本模型的建议。但是我被告知 Obj 格式不支持动画,在此之前我一直只使用 Obj。我可以使用 blender 以类似于本教程中所示的 MD5 的方式导出的任何其他格式吗?
最佳答案
我几年前使用 Assimp 库构建了一个动画场景,基本上遵循了这些教程。 http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html和 http://sourceforge.net/projects/assimp/forums/forum/817654/topic/3880745
虽然我使用的是旧的 X 格式(Blender 可以使用 X,使用扩展),但我可以肯定地确认您需要转置 assimp 动画矩阵以用于 GML。
关于使用其他格式,只要 Blender(导入、编辑、导出)和 Assimp 支持,您可以使用任何您喜欢的格式。准备好在更改格式时进行大量试验和错误!
与其尝试理解您的代码,不如发布我的工作系统中的相关片段,这些片段显示了骨骼矩阵的计算。希望这会对您有所帮助,因为我记得我遇到过与您描述的相同的问题,并且花了一些时间来追踪它。代码是纯“C”。
您可以在代码末尾看到转置发生的位置。
// calculateAnimPose() calculates the bone transformations for a mesh at a particular time in an animation (in scene)
// Each bone transformation is relative to the rest pose.
void calculateAnimPose(aiMesh* mesh, const aiScene* scene, int animNum, float poseTime, mat4 *boneTransforms) {
if(mesh->mNumBones == 0 || animNum < 0) { // animNum = -1 for no animation
boneTransforms[0] = mat4(1.0); // so, just return a single identity matrix
return;
}
if(scene->mNumAnimations <= (unsigned int)animNum)
failInt("No animation with number:", animNum);
aiAnimation *anim = scene->mAnimations[animNum]; // animNum = 0 for the first animation
// Set transforms from bone channels
for(unsigned int chanID=0; chanID < anim->mNumChannels; chanID++) {
aiNodeAnim *channel = anim->mChannels[chanID];
aiVector3D curPosition;
aiQuaternion curRotation; // interpolation of scaling purposefully left out for simplicity.
// find the node which the channel affects
aiNode* targetNode = scene->mRootNode->FindNode( channel->mNodeName );
// find current positionKey
size_t posIndex = 0;
for(posIndex=0; posIndex+1 < channel->mNumPositionKeys; posIndex++)
if( channel->mPositionKeys[posIndex + 1].mTime > poseTime )
break; // the next key lies in the future - so use the current key
// This assumes that there is at least one key
if(posIndex+1 == channel-> mNumPositionKeys)
curPosition = channel->mPositionKeys[posIndex].mValue;
else {
float t0 = channel->mPositionKeys[posIndex].mTime; // Interpolate position/translation
float t1 = channel->mPositionKeys[posIndex+1].mTime;
float weight1 = (poseTime-t0)/(t1-t0);
curPosition = channel->mPositionKeys[posIndex].mValue * (1.0f - weight1) +
channel->mPositionKeys[posIndex+1].mValue * weight1;
}
// find current rotationKey
size_t rotIndex = 0;
for(rotIndex=0; rotIndex+1 < channel->mNumRotationKeys; rotIndex++)
if( channel->mRotationKeys[rotIndex + 1].mTime > poseTime )
break; // the next key lies in the future - so use the current key
if(rotIndex+1 == channel-> mNumRotationKeys)
curRotation = channel->mRotationKeys[rotIndex].mValue;
else {
float t0 = channel->mRotationKeys[rotIndex].mTime; // Interpolate using quaternions
float t1 = channel->mRotationKeys[rotIndex+1].mTime;
float weight1 = (poseTime-t0)/(t1-t0);
aiQuaternion::Interpolate(curRotation, channel->mRotationKeys[rotIndex].mValue,
channel->mRotationKeys[rotIndex+1].mValue, weight1);
curRotation = curRotation.Normalize();
}
aiMatrix4x4 trafo = aiMatrix4x4(curRotation.GetMatrix()); // now build a rotation matrix
trafo.a4 = curPosition.x; trafo.b4 = curPosition.y; trafo.c4 = curPosition.z; // add the translation
targetNode->mTransformation = trafo; // assign this transformation to the node
}
// Calculate the total transformation for each bone relative to the rest pose
for(unsigned int a=0; a<mesh->mNumBones; a++) {
const aiBone* bone = mesh->mBones[a];
aiMatrix4x4 bTrans = bone->mOffsetMatrix; // start with mesh-to-bone matrix to subtract rest pose
// Find the bone, then loop through the nodes/bones on the path up to the root.
for(aiNode* node = scene->mRootNode->FindNode(bone->mName); node!=NULL; node=node->mParent)
bTrans = node->mTransformation * bTrans; // add each bone's current relative transformation
boneTransforms[a] = mat4(vec4(bTrans.a1, bTrans.a2, bTrans.a3, bTrans.a4),
vec4(bTrans.b1, bTrans.b2, bTrans.b3, bTrans.b4),
vec4(bTrans.c1, bTrans.c2, bTrans.c3, bTrans.c4),
vec4(bTrans.d1, bTrans.d2, bTrans.d3, bTrans.d4)); // Convert to mat4
}
}
关于c++ - 尝试使用 Assimp GLM 从 MD5 文件加载 OpenGL 中的动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52248731/
我尝试加载 gltf 格式的场景。它具有金属和粗糙纹理(未嵌入)。现在我想使用 Assimp 加载具有指定纹理的模型。我使用 GetTexture() 检索纹理,但 aiTextureType 没有粗
我已经从 http://assimp.sourceforge.net/main_downloads.html 下载了 Assimp 项目 Assimp release image assimp zip
assimp 库提供了一种从文件加载 3D .obj 模型的好方法。但是我发现它附带的 assimp_viewer.exe(我使用 3.1.1 版)在导入我的 .obj 文件(42Mb,已经简化)时比
我正在使用 Assimp 将 3D 模型加载到我的程序中。到目前为止,一切都很顺利,除了我遇到了一个似乎没有意义的 Lightwave 对象。当然它在 Lightwave 中渲染得很好,但在 Assi
最近我在做骨骼动画导入,所以我用一些IK技术制作了一个类似Minecraft的3d模型来测试Assimp动画导入。输出格式为 COLLADA(*.dae),我使用的工具是 Blender。在编程方面,
导入网格物体时,我得到了 Material ,但是无法访问纹理的文件名。 .mtl文件显式显示纹理的文件名。在代码中,它的纹理计数为1,但文件名字段显示为空字符串,fullPath输出为“* 0”。在
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
过去几天我一直在尝试使用 assimp 加载我的蒙皮 collada 网格,但我遇到了非常困难的时间。目前我只是试图在没有任何变换或动画的情况下以其正常的“姿势”渲染它,但网格变得非常变形。我认为问题
我正在尝试使用 Assimp(Open Asset Import Library)制作骨骼动画。现在我可以成功加载 .dae 模型并用动画渲染它,但在这样做的过程中模型变得困惑。 http://i.i
我刚刚下载了 assimp 3.0 库并使用 cmake 构建了所需的 make 文件,然后编译并构建了库本身,这个过程是成功的(对 StepFile.h 稍作修改), 我的 assimp 头文件夹位
我刚拿到最后一个assimp SDK,做了一个项目,我正确地链接了它(链接没有错误)但是我似乎在Sample项目上遇到了一些麻烦。更具体地说,是 SimpleOpenGL。我将 C++ 与 OpenG
我正在使用 Assimp 加载我的模型和网格,到目前为止它一直运行良好。我正在尝试从从 blender 导出 .obj 文件时生成的 .mtl 文件加载发射贴图。它加载漫反射贴图、法线贴图和镜面反射贴
我目前正在使用 ASSIMP 库将骨骼动画实现到我的 3D OpenGL 游戏引擎中,不幸的是它并没有那么好。我目前面临的问题是,串联的骨骼变换(骨骼之间的父子关系)只有在只有一个父级被变换时才能正确
我已经使用 Assimp 一段时间了,现在我正在尝试加载一个 .obj 文件。它加载完美,但我想在加载后操作面部数据。 基本上我在简单的 cube.obj 文件中有这个(完整文件 - http://p
我正在做一个项目,我使用 ASSIMP 库导入一个化身的 3D 网格,更新它并使用同一个 ASSIMP 库再次导出更新后的场景。为此,作为第一步,我编写了一段代码来导入场景,并且在不做任何更改的情况下
我正在使用 assimp 在我的游戏引擎中导入 3d 模型。出于某种原因,无论我使用什么模型或模型格式,assimp 都不会报告任何纹理。这是为什么? 以下是使用 assimp 的非常简单的设置: c
我正在使用 Assimp 加载 COLLADA 模型,但是 scene->mMeshes[i]->mName.C_Str() 调用为我返回 "" existing mesh index(当然,"" 不
我最近通过 valgrind 对我的游戏引擎进行了内存泄漏测试;它实际上告诉我,在我的 Mesh 类中有大约 7000 个字节被泄露;奇怪的是它告诉我这个: 7,280 bytes in 1 bloc
我在 Windows 上安装了 Assimp 库,并且喜欢这些文件,然后只是复制粘贴 SimpleOpenGL 示例并删除了结构词(其中大部分)以清除我得到的错误。 现在,我没有任何错误,但是每当我尝
我正在使用 Assimp.net 将动画 .dae 文件导入我的 OpenTK 引擎并努力建立可用的分层骨骼结构。 在 tutorial我正在关注,根骨骼或“关节”包含它的子关节列表,以及它们的子关节
我是一名优秀的程序员,十分优秀!