在做一个Ogre3d 模型和骨骼动画转换到FBX格式的工具。中间遇到种种问题,下面将主要思路记录下来。

转换Mesh比较简单,就是遍历MeshPtr,获取顶点和索引缓冲、获取UV坐标,然后按FBX SDK的格式重新定义,然后保存即可。这个比较好弄。贴出关键代码:

bool Util::enumMeshVertex(const Ogre::String& strMesh, const Ogre::String& strGroupName, VERTEX_LIST& vecPos, INDEX_LIST& vecIndex)
    {
        Ogre::MeshPtr pMesh = Ogre::MeshManager::getSingleton().load(strMesh, strGroupName);

int nVertexCount = 0;
        int nIndexCount = 0;
        DBGSTRING("NumSubMesh: %d", pMesh->getNumSubMeshes());

for(int i=0; i<pMesh->getNumSubMeshes(); i++) {
            Ogre::SubMesh* pSubMesh = pMesh->getSubMesh(i);
            if(pSubMesh->useSharedVertices) {
                DBGSTRING("useSharedVertices");
                nVertexCount += pMesh->sharedVertexData->vertexCount;
            }else{
                nVertexCount += pSubMesh->vertexData->vertexCount;
            }
            nIndexCount += pSubMesh->indexData->indexCount;
            DBGSTRING("nIndexCount: %d", pSubMesh->indexData->indexCount);
        }

DBGSTRING("nVertexCount: %d, nIndexCount: %d", nVertexCount, nIndexCount);

for(int i=0; i<pMesh->getNumSubMeshes(); ++i) {
            Ogre::SubMesh* pSubMesh = pMesh->getSubMesh(i);

Ogre::VertexData* pVertexData = pSubMesh->useSharedVertices ? pMesh->sharedVertexData : pSubMesh->vertexData;
            const Ogre::VertexElement* posElem = pVertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
            const Ogre::VertexElement* uvElem = pVertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
            //const Ogre::VertexElement* normalElem = pVertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL);

Ogre::HardwareVertexBufferSharedPtr vbuf = pVertexData->vertexBufferBinding->getBuffer(posElem->getSource());
            Ogre::HardwareVertexBufferSharedPtr uvbuf = pVertexData->vertexBufferBinding->getBuffer(uvElem->getSource());
        
            unsigned char* pVertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
        
            float* pReal;
            float* pUVReal;
            //读取顶点
            for(size_t j=0; j<pVertexData->vertexCount; ++j, pVertex += vbuf->getVertexSize()) {
                VERTEX_DATA vd;

posElem->baseVertexPointerToElement(pVertex, &pReal);
                Ogre::Vector3 pos(pReal[0], pReal[1], pReal[2]);
                vd.position = pos;

vecPos.push_back(vd);
            }
            vbuf->unlock();

//读取UV
            unsigned char* pUV = static_cast<unsigned char*>(uvbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
            for(size_t j=0; j<pVertexData->vertexCount; ++j, pUV += uvbuf->getVertexSize()) {
                uvElem->baseVertexPointerToElement(pUV, &pUVReal);
                vecPos[j].uv = Ogre::Vector2(pUVReal[0], pUVReal[1]);
            }
            uvbuf->unlock();

Ogre::IndexData* pIndexData = pSubMesh->indexData;
            Ogre::HardwareIndexBufferSharedPtr ibuf = pIndexData->indexBuffer;
            bool b32Bit = ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT;

unsigned char* pIndex = static_cast<unsigned char*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
            int nIndexSize = b32Bit ? 4 : 2;

for(size_t k=0; k<pIndexData->indexCount; k++) {
                unsigned long ulIndex = 0;
                if(b32Bit) {
                    memcpy(&ulIndex, pIndex, 4);
                }else{
                    unsigned short usIndex = 0;
                    memcpy(&usIndex, pIndex, 2);
                    ulIndex = static_cast<unsigned long>(usIndex);
                }

vecIndex.push_back(ulIndex);
                pIndex += nIndexSize;
            }
            ibuf->unlock();
        }

return vecPos.size() > 0;
    }

bool Util::exportMesh(const char* szMesh, const char* szGroupName, const char* szFileName)
    {
        VERTEX_LIST vecPos;
        INDEX_LIST vecIndex;

enumMeshVertex(szMesh, szGroupName, vecPos, vecIndex);

if(vecPos.size() <= 0){
            DBGSTRING("获取Mesh顶点数据失败");
            return false;
        }

FbxScene* pScene = FbxOgre::FbxSdk::getScene();
        pScene->Clear();

FbxMesh* pMesh = FbxMesh::Create(pScene, szMesh);

pMesh->InitControlPoints(vecPos.size());
        FbxVector4* pVertex = pMesh->GetControlPoints();
    
        for(int i=0; i<vecPos.size(); i++) {
            Ogre::Vector3 pos = vecPos[i].position;
            pVertex[i] = FbxVector4(pos.x, pos.y, pos.z);
        }

//创建三角形
        int nTriangles = vecIndex.size() / 3;
    
        for(int i=0; i<nTriangles; i++) {
            int nIndex = i*3;
            pMesh->BeginPolygon();
            pMesh->AddPolygon(vecIndex[nIndex]);
            pMesh->AddPolygon(vecIndex[nIndex+1]);
            pMesh->AddPolygon(vecIndex[nIndex+2]);

pMesh->EndPolygon();
        }

FbxNode* pNode = FbxNode::Create(pScene, szMesh);

pNode->SetNodeAttribute(pMesh);

FbxGeometryElementUV* pUVElement = pMesh->CreateElementUV("uvset");
        pUVElement->SetMappingMode(FbxGeometryElement::eByControlPoint);
        pUVElement->SetReferenceMode(FbxGeometryElement::eDirect);
        pUVElement->GetDirectArray().Resize(vecPos.size());
        for(int i=0; i<vecPos.size(); i++) {
            FbxVector2 fbxuv(vecPos[i].uv.x, 1.0f - vecPos[i].uv.y);
            pUVElement->GetDirectArray().SetAt(i, fbxuv);
        }

FbxNode* pRootNode = pScene->GetRootNode();
        pRootNode->AddChild(pNode);

return FbxOgre::FbxSdk::saveScene(szFileName);
    }

FbxOgre是我自己进行的封装,其实就是把FBX SDK的Sample代码修改了一下,具体实现看FBX SDK。

现在主要的问题是Ogre骨骼动画数据的转换,按Ogre skeleton文件读出的数据直接写入FBX的话,导入3d max骨骼的位置和动画的效果惨不忍睹,有些是正的,有些是反的,不同的skeleton文件也会出现不同的错误,头大。欢迎懂的朋友给点指导意见。

谢谢。

Ogre3D Mesh转换到FBX格式相关推荐

  1. CGR模型文件如何转换成FBX格式文件

    最近,收到一个CGR的模型文件,想要转换成FBX格式问题并进行纹理贴图,搜了一圈,费了点时间,终于找到了窍门 1.首先新装个Pro-E 2.用Pro-E打开模型文件 3.选择另存为.stl文件 4.如 ...

  2. FBX格式mesh解析与加载(一)

    ** 理解FBX格式中Mesh数据结构** fbx文件是现在许多建模动画软件和游戏引擎之间共用的模型文件格式.fbx文件分为两种方式从建模软件中导出,一种是二进制文件另一种是ASCII码保存. ASC ...

  3. 在线转换glb格式模型gltf格式模型fbx格式模型obj模型转换

    咱们一般用的软件是3dmax,C4D 这些软件做模型,但是做出来模型不能直接导出是glb格式,可以制作glb模型,扣扣:424081801 咱们可以先导出成fbx通用格式 这样就好办了,win10自带 ...

  4. Html监听Fbx文件加载,FBX格式mesh解析与加载(一)

    FBX格式mesh解析与加载(一) FBX格式mesh解析与加载(一) ** 理解FBX格式中Mesh数据结构** fbx文件是现在许多建模动画软件和游戏引擎之间共用的模型文件格式.fbx文件分为两种 ...

  5. 【Unity3D】使用 FBX 格式的外部模型 ( 向 Unity 中添加 FBX 模型 | 向 Scene 场景中添加 FBX 模型 | 3D 物体渲染 | 3D 物体材质设置 )

    文章目录 一.向 Unity 中添加 FBX 模型 二.向 Scene 场景中添加 FBX 模型 三.3D 物体渲染 四.3D 物体材质设置 一.向 Unity 中添加 FBX 模型 Unity 中使 ...

  6. 88 Three.js 导入FBX格式骨骼绑定模型

    简介 上一节,深入了解了一下SkinnedMesh模型对象的创建.这一节,我们导入外部骨骼绑定的模型,来实现动画显示.由于Three.js支持的三维格式非常多,由于导入模式大同小异,我们就选择两种格式 ...

  7. cesium模型加载-加载fbx格式模型

    整体思路: fbx格式→dae格式→gltf格式→cesium加载gltf格式模型 具体方法: 1. fbx格式→dae格式 工具:3dsMax, 3dsMax插件:OpenCOLLADA, 下载地址 ...

  8. fbx文件导入html,AE插件:导入三维文件FBX格式包括摄像机到AE颠覆性插件FBX to AE...

    AE插件:导入三维文件FBX格式包括摄像机到AE颠覆性插件FBX to AE,可结合E3D V2,粒子插件使用! Valerio Carnevale和Davide Franceschini开发了一款极 ...

  9. FBX格式解析顶点信息和用OpenGL显示

    FbxSDK是解析FBX的工具,在unity和ue中使用较多,下面介绍一下用这个工具解析FBX格式并用OpenGL显示出来. FBX的scene是由一系列node组成的,node包含一个Transfr ...

最新文章

  1. 3天拆解数据分析全流程!
  2. springmvc+mybatis+html 下将查询数据以excell形式上传到ftp(下)
  3. 自动化测试jenkins shell命令
  4. 第十五届北京师范大学程序设计竞赛决赛(网络同步赛) B lca水 D 思维,找规律...
  5. 阿里云_数加平台类HQL的那些坑
  6. 校园无盘服务器,校园微机系统优化及无盘改造实例.docx
  7. 存储总结——DASNASSAN
  8. 关于一直卡死的两段代码,望对LDD3有兴趣者戳开这个blog : )
  9. SqlMap免Python环境绿色版下载
  10. 应该怎么正确向老板提加薪呢?
  11. 不同类型的物联网产品、物联网产品的优势
  12. WSDM2021推荐系统论文集锦
  13. 预言机私享,Defi实战特训,一场对开放式金融认知新突围来了!
  14. R语言逻辑回归Logistic回归分析预测股票涨跌
  15. 计算机无法关闭密码保护共享,xp系统怎么关闭密码保护共享
  16. 降噪蓝牙耳机哪个品牌好?降噪蓝牙耳机排行推荐
  17. 列表List: 什么是列表?
  18. vivado报位置约束指令的critical warning
  19. vue组件中数据共享——vuex
  20. 计算机图形学——生成直线的DDA算法

热门文章

  1. vue怎样引入使用layer弹窗以及icon使用
  2. CAD快捷键_CAD常用快捷键大全
  3. 13.4-软件测试标准 13.5-测试过程标准 13.6-测试文档标准 13.7-测试技术标准
  4. 我们线上教学是计算机哪方面应用,线上线下教学下计算机教学的应用
  5. 远程桌面或者共享访问引起资源管理器崩溃,故障模块名称StackHash_423a
  6. C# error MSB3171: 生成清单时出现问题。未能加载文件或程序集,Windows.winmd
  7. Android Studio Gradle UserGuide
  8. 把悲伤留给自己:依依搜集伤感空间日志
  9. 媒体文件批量改名(递归实现)
  10. https 中的SSL/TLS 加密