2019独角兽企业重金招聘Python工程师标准>>>

目的是为OSG做自定义的导出插件. 记录取得数据的方法.

Max在代码中会提供一个INode对象. 从这个对象里取出各种数据. getSkin这个函数取出了ISkin修改器 下面这个函数一样是用于学习, 把数据输出到文本文件

`

ISkin* OSGExp::getSkin(INode *pINode)
{// get the object reference of the nodeObject *pObject;pObject = pINode->GetObjectRef();if (pObject == 0) return 0;// loop through all derived objectsObjectState _objectState = pINode->EvalWorldState(_ip->GetTime());// Arcadia 2018-09-10if (_objectState.obj->SuperClassID() == GEOMOBJECT_CLASS_ID)// Arcadia 2018-09-10 有顶点数据,才会有蒙皮{IDerivedObject *pDerivedObject;pDerivedObject = static_cast<IDerivedObject *>(pObject);// loop through all modifiers 遍历所有的修改器int stackId;Modifier *pModifier;// 这里用于存放当前修改器, 用于试着转成蒙皮ISkin* _skin = NULL;for (stackId = 0; stackId < pDerivedObject->NumModifiers(); stackId++){_skin = NULL;// get the modifierif (NULL == pDerivedObject->GetModifier(stackId)){continue;}// 蒙皮在Max中是个修改器, 取得这个修改器,再转成_skinpModifier = pDerivedObject->GetModifier(stackId);// Arcadia 2018-09-10if (pModifier){char _sTemp[255];// 蒙皮数据的上下文:_skin = dynamic_cast<ISkin*>(pModifier);if (_skin){}// END if(_skin)}}return _skin;}return 0;
}

`

函数readSkinData解析蒙皮数据 在Max导出插件制作过程中, 用写文件的方式调试比较方便 每个顶点对应几个有作用的骨骼, GetNumAssignedBones 取得有作用的骨骼 然后再遍历取得这个顶点的各个权重值. 并遍历取得相关骨骼的序号.

这里要注意的一点是, 所有骨骼是一个数组, 单个顶点的作用骨骼又是另一数组, 用单个顶点作用骨骼的下标可以取得骨骼于[所有骨骼数组]的下标.

` /** * 读取蒙皮数据, 输出到文件, 用于调试与学习 */ void OSGExp::readSkinData(ISkin skin,INode node) { using std::sprintf; string labelStart("\n S S S S S S S S S S S S\n"); m_FileObj.write(labelStart.c_str(), labelStart.size());

 char _sTemp[255];{m_FileObj.write("有转成ISkin\n", string("有转成ISkin\n").size());ISkinContextData *_data = skin->GetContextInterface(node);sprintf(_sTemp, "点数:\t%d\n", _data->GetNumPoints());m_FileObj.write(_sTemp, string(_sTemp).size());sprintf(_sTemp, "骨骼数:\t%d\n", skin->GetNumBones());m_FileObj.write(_sTemp, string(_sTemp).size());Matrix3 _mt3;sprintf(_sTemp, "SKIN_OK?\t%d\n",SKIN_OK == skin->GetSkinInitTM(node,_mt3) ); // 2018-09-12 返回是 SKIN_INVALID_NODE_PTR 不知会不会有问题 GetSkinInitTM是OK的, 但GetBoneInitTM不OKm_FileObj.write(_sTemp, string(_sTemp).size());// 取骨骼:for (int i = 0; i < skin->GetNumBones(); ++i){INode* nodeBone = skin->GetBone(i);const wchar_t* wc_strName = nodeBone->GetName();string s_strName = Util::TDuW2A(wc_strName);sprintf(_sTemp, "骨骼名:\t%d\t%s", i, s_strName.c_str() );m_FileObj.write(_sTemp, string(_sTemp).size());switch ( skin->GetBoneProperty(i) ){case BONE_LOCK_FLAG:sprintf(_sTemp, "\t%s", "BONE_LOCK_FLAG");break;case BONE_ABSOLUTE_FLAG:sprintf(_sTemp, "\t%s", "BONE_ABSOLUTE_FLAG");break;case BONE_SPLINE_FLAG:sprintf(_sTemp, "\t%s", "BONE_SPLINE_FLAG");break;case BONE_SPLINECLOSED_FLAG:sprintf(_sTemp, "\t%s", "BONE_SPLINECLOSED_FLAG");break;case BONE_DRAW_ENVELOPE_FLAG:sprintf(_sTemp, "\t%s", "BONE_DRAW_ENVELOPE_FLAG");break;case BONE_BONE_FLAG:sprintf(_sTemp, "\t%s", "BONE_BONE_FLAG");break;case BONE_DEAD_FLAG:sprintf(_sTemp, "\t%s", "BONE_DEAD_FLAG");break;}m_FileObj.write(_sTemp, string(_sTemp).size());// Bone TM:union xxx {xxx() {}Matrix3 mt3_3;// = skin->GetBoneTm(i);float m[4][3];// = (float*)mt3_3;} _getDataU;_getDataU.mt3_3 = skin->GetBoneTm(i);sprintf(_sTemp, "\t坐标Z:\t%f", _getDataU.m[3][2]);m_FileObj.write(_sTemp, string(_sTemp).size());sprintf(_sTemp, "\n");m_FileObj.write(_sTemp, string(_sTemp).size());}}// END if(_skin)// GetNumBonesFlat:sprintf(_sTemp, "GetNumBonesFlat:\t%d\n", skin->GetNumBonesFlat());m_FileObj.write(_sTemp, string(_sTemp).size());// GetRefFrame:sprintf(_sTemp, "GetRefFrame:\t%d\n", skin->GetRefFrame());m_FileObj.write(_sTemp, string(_sTemp).size());// 输出各顶点坐标:// ISkinContextData:{sprintf(_sTemp, "ISkinContextData:\n");m_FileObj.write(_sTemp, string(_sTemp).size());ISkinContextData *skinData = skin->GetContextInterface(node);sprintf(_sTemp, "\tGetNumPoints:\t%d\n", skinData->GetNumPoints());m_FileObj.write(_sTemp, string(_sTemp).size());sprintf(_sTemp, "\tGetNumAssignedBones:\t%d\n", skinData->GetNumAssignedBones(0));// 骨骼数m_FileObj.write(_sTemp, string(_sTemp).size());sprintf(_sTemp, "\tGetAssignedBone:\t%d\n", skinData->GetAssignedBone(0,0));// 有分配的骨骼m_FileObj.write(_sTemp, string(_sTemp).size());// 各顶点权重:for (int i = 0; i < skinData->GetNumPoints(); ++i){int numOfBones = skinData->GetNumAssignedBones(i);// 本顶点于各骨骼的权重for (int boneAffectedId = 0; boneAffectedId < numOfBones;++boneAffectedId){// 这里取到了权重__weightfloat __weight = skinData->GetBoneWeight(i, boneAffectedId);int boneIndex = skinData->GetAssignedBone( i , boneAffectedId);//string strName = Util::TDuW2A( skin->GetBoneName(boneAffectedId) );string strNameFromBoneIndex = Util::TDuW2A(skin->GetBoneName(boneIndex));if(-1 != boneIndex){sprintf(_sTemp, "\t\tBoneWeight:\t%d,%d:\t%f \t boneIndex:%d(%s)\n  ", i, boneAffectedId, __weight,boneIndex , strNameFromBoneIndex);m_FileObj.write(_sTemp, string(_sTemp).size());}}/*float weight = skinData->GetBoneWeight(i, skinData->GetAssignedBone(0, 0));sprintf(_sTemp, "\t\tBoneWeight:\t%d:%f\n", i , weight);m_FileObj.write(_sTemp, string(_sTemp).size());*/}//sprintf(_sTemp, "\tGetBoneWeight:\t%f\n", skinData->GetBoneWeight(0, skinData->GetAssignedBone(0, 0)));//m_FileObj.write(_sTemp, string(_sTemp).size());}#pragma region 顶点数据输出string labelVData("\n顶点数据输出:\n");m_FileObj.write(labelVData.c_str(), labelVData.size());// 输出顶点数据 , 以能进一步研究顶点蒙皮数据的正确性.// 1. 顶点的次序// Order of the vertices. Get them counter clockwise if the objects is// negatively scaled. This is important if an object has been mirrored.Matrix3 tm = node->GetObjTMAfterWSM(0/*TimeValue*/);BOOL negScale = getTMNegParity(tm);int vx1, vx2, vx3;if (negScale) {vx1 = 2;vx2 = 1;vx3 = 0;}else {vx1 = 0;vx2 = 1;vx3 = 2;}// Get mesh objectBOOL needDel;ObjectState os = node->EvalWorldState(0);TriObject* tri = getTriObjectFromObject(os.obj, 0/*TimeValue*/, needDel);// Extract coords, normals, texture coords, vertex colors, and vertex normals// from MAX mesh.Mesh* mesh = &tri->GetMesh();for (int _iv = 0; _iv < mesh->numVerts; ++_iv){Point3 v1 = mesh->verts[_iv];std::sprintf(_sTemp, "\tv1:%.4f\t%.4f\t%.4f\n", v1.x, v1.y, v1.z);string strV1(_sTemp);m_FileObj.write(strV1.c_str(), strV1.size());}#pragma endregion 顶点数据输出string labelEnd("\n ES ES ES ES ES ES ES ES\n");m_FileObj.write(labelEnd.c_str(), labelEnd.size());
}

`

转载于:https://my.oschina.net/u/235558/blog/2088300

关于获取3DS MAX中的蒙皮数据 3DSMAX C++API的应用相关推荐

  1. 3ds Max中的V-Ray学习

    时长3h 30m 大小解压后:2.73G 包含项目文件 1280X720 MP4 语言:英语+中英文字幕(根据原英文字幕机译更准确) 3ds Max中的V-Ray简介:官方V-Ray导师 云桥网络 获 ...

  2. 如何解决Vray for 3ds Max中的3个错误

    大家好,几乎所有艺术家都知道来自Chaos的Vray渲染器.Vray是世界上最完整的用于高端可视化和制作的3D渲染软件.它是一个与3D软件交互的渲染器,几乎可以应用从小规模到大规模的任何工作室工作流程 ...

  3. 如何获取3ds Max 2018序列号和密钥

    3ds Max 2018是目前市场上最新版本,其功能相对其他版本同产品都有了一定的提高和完善.这也是它为什么备受广大使用者爱戴的原因.那么我们如何获取3ds Max 2018序列号和密钥? 我们可以通 ...

  4. 在 3ds Max 中打开或保存文件时间很长,解决方案来了

    3ds Max 场景文件的打开时间比平时长(有时超过 20 分钟). 来自网络的外部参照场景或文件会增加加载时间. 文件也可能在 3ds Max 中崩溃. 成因: 包括但不限于: Windows 操作 ...

  5. 遇到V-Ray for 3ds Max中的这3个错误如何解决

    V-Ray是一款可用于高端可视化和制作的3D渲染插件.它是一个可以与3D软件交互的渲染器,从小规模到大规模的任何工作室都能用它. V-Ray虽然有很多优点,但是在使用的过程中,仍然存在一些与生产工艺流 ...

  6. 在 3ds Max 中对链模型进行摆放姿势处理

    推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 建模和"摆姿势"3D链可能看起来是一项繁琐的工作,但实际上可以通过使用阵列工具并将链中的链接视为骨骼来轻松完成.在本 ...

  7. 如何在3ds max中创建可用于真人场景的巨型机器人:第 5 部分

    推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. After Effects 中的项目设置 步骤 1 打开"后效". 打开后效果 步骤 2 我有真人版 我在Af ...

  8. 在3ds Max中使用V-Ray 5渲染引擎视频教程

    在3ds Max中使用V-Ray 5渲染引擎视频教程 MP4 | 视频:h264, 1280x720 | 音频:AAC, 44.1 KHz, 2通道.AAC, 44.1 KHz, 2 Ch. 技能水平 ...

  9. 获取烧瓶请求中收到的数据

    本文翻译自:Get the data received in a Flask request I want to be able to get the data sent to my Flask ap ...

  10. 3ds max中的物体对齐方式

    3ds max中的对齐方式非常强大,可以灵活设置对齐的各种坐标参数.首先要明确对齐的[当前对象]与[目标对象]两个概念,[当前对象]指的是受控的物体,一般都是你当前选中的物体,[目标对象]就是你对齐的 ...

最新文章

  1. 如何定制一款12306抢票浏览器——构架
  2. 谷歌浏览器输入框背景颜色变黄的解决方案
  3. 当前国内有哪些公司是做OKR管理软件做的比较好的?
  4. 电子书下载:The C# Programming Language, 4th Edition
  5. Ettercap内网渗透
  6. Oracle DB优化
  7. winform项目_winform项目——仿QQ即时通讯程序01:原理及项目分析
  8. 删除链表的中间节点 Java实现_【链表问题】删除单链表的中间节点
  9. TensorFlow从1到2 | 第五章 非专家莫入!TensorFlow实现CNN
  10. 初识DOM(文档对象模型)
  11. 编程趣谈_k++_++k_k一行顺序输出,结果会有差异吗?
  12. 有没有可以帮忙lua解密一下的大概是这样一个压缩包
  13. 微信小程序项目-出租屋管理系统
  14. 电音中DJ/Producer/MC/EDM/Remix/Mix的名词解释(转)
  15. 全基因组水平分泌蛋白鉴定
  16. K8S Pod配置进阶1 containers字段解释
  17. UUID订单单号生成器
  18. java算法:1234组成无重复的三位数
  19. 关于错误提示:could not find a part of path “X:\”的解决办法
  20. 1000w+条中国大陆企业工商注册信息数据集

热门文章

  1. Google的“神秘链接”
  2. iOS开发常用网址(最全)
  3. 基于JavaEE的人力资源管理系统的设计与实现任务书与开题报告
  4. 【归纳】对于S3C2440A芯片的认知和使用理论再学习
  5. C语言计算机二级选择题重点,2014年计算机二级C语言重点选择题笔试复习资料.doc...
  6. 个人职场工作感悟总结「如何尽快地提升自我」
  7. dcx游走 - 组合计数
  8. 体验服务器windows系统,怀旧经典:Windows 3.0操作系统体验
  9. 分享一个HandsFree Robot的国内机器人开源平台
  10. 用git下载github项目失败werning : Clone succeeded, but checkout failed.