osg 骨骼绘制 注意事项

背景: osg读入一个人体模型(我的模型是fbx的),和 绘制出骨骼我绘制的骨骼图如下:修改了一下

需要注意的问题:

1,绘制bone 的时候,是绘制 本身原点,到子节点matrix的向量(这样才能绘制出那种分叉的骨骼)

2.程序初始化的时候,不要绘制骨骼,因为那时候,bone,只有_invBindInSkeletonSpace的数据,另外两个matrix,还没有被计算出来

3,将绘制出来的骨骼添加到相应的bone中,即可显示了,如果需要导出,则另行设计绘制位置

有需要源码的同学,评论留言联系我

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
osg中,可以使用Assimp库来读取人物动作模型蒙皮。Assimp库是一个开源的、跨平台的、多格式的3D模型导入库,可以读取多种3D模型格式,包括fbx、obj、3ds等。 使用Assimp库读取模型蒙皮的流程如下: 1. 导入模型:使用Assimp库的aiImportFile函数导入模型文件,返回aiScene对象。 ``` #include <assimp/Importer.hpp> #include <assimp/scene.h> #include <assimp/postprocess.h> // 读取模型文件 Assimp::Importer importer; const aiScene* scene = importer.ReadFile("model.dae", aiProcess_Triangulate | aiProcess_FlipUVs); ``` 2. 获取骨骼信息:从aiScene对象中获取骨骼信息,包括骨骼节点、骨骼矩阵等。 ``` // 遍历骨骼节点 for (unsigned int i = 0; i < scene->mNumMeshes; i++) { const aiMesh* mesh = scene->mMeshes[i]; for (unsigned int j = 0; j < mesh->mNumBones; j++) { const aiBone* bone = mesh->mBones[j]; // 获取骨骼矩阵 aiMatrix4x4 boneMatrix = bone->mOffsetMatrix; } } ``` 3. 获取动画信息:从aiScene对象中获取动画信息,包括动画名称、帧数、骨骼动画等。 ``` // 遍历动画 for (unsigned int i = 0; i < scene->mNumAnimations; i++) { const aiAnimation* anim = scene->mAnimations[i]; // 获取动画名称 std::string animName = anim->mName.C_Str(); // 获取动画帧数 int numFrames = anim->mDuration / anim->mTicksPerSecond; // 遍历骨骼动画 for (unsigned int j = 0; j < anim->mNumChannels; j++) { const aiNodeAnim* nodeAnim = anim->mChannels[j]; // 获取骨骼名称 std::string boneName = nodeAnim->mNodeName.C_Str(); // 获取骨骼动画 for (unsigned int k = 0; k < nodeAnim->mNumPositionKeys; k++) { aiVector3D position = nodeAnim->mPositionKeys[k].mValue; aiQuaternion rotation = nodeAnim->mRotationKeys[k].mValue; aiVector3D scale = nodeAnim->mScalingKeys[k].mValue; } } } ``` 4. 应用蒙皮:在渲染时,根据骨骼信息和动画信息,应用蒙皮,将顶点位置转换为骨骼空间中的位置。 ``` // 获取骨骼矩阵和权重 std::vector<aiMatrix4x4> boneMatrices; std::vector<float> boneWeights; for (unsigned int i = 0; i < mesh->mNumBones; i++) { const aiBone* bone = mesh->mBones[i]; // 获取骨骼矩阵 aiMatrix4x4 boneMatrix = bone->mOffsetMatrix; // 获取骨骼权重 for (unsigned int j = 0; j < bone->mNumWeights; j++) { const aiVertexWeight& weight = bone->mWeights[j]; boneMatrices[weight.mVertexId] += boneMatrix * weight.mWeight; boneWeights[weight.mVertexId] += weight.mWeight; } } // 应用蒙皮 for (unsigned int i = 0; i < mesh->mNumVertices; i++) { // 将顶点位置转换为骨骼空间中的位置 aiVector3D pos = mesh->mVertices[i]; aiVector3D normal = mesh->mNormals[i]; aiVector3D tangent = mesh->mTangents[i]; aiVector3D bitangent = mesh->mBitangents[i]; aiMatrix4x4 finalMatrix = boneMatrices[i] / boneWeights[i]; pos = finalMatrix * pos; normal = finalMatrix * normal; tangent = finalMatrix * tangent; bitangent = finalMatrix * bitangent; // 渲染顶点 // ... } ``` 以上就是使用Assimp库读取人物动作模型蒙皮的基本流程。需要注意的是,在读取模型时,需要指定一些参数,如aiProcess_Triangulate将多边形转换为三角形,aiProcess_FlipUVs将纹理坐标y轴反转等。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值