注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[转] 3DMax 一些基本认识  

2012-06-26 19:33:13|  分类: 3d_3dmax |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
从去年开始到现在用3dmax也快一年了,画图、建模、写插件,用的非常多,但一直却没时间(或者说懒于)整理,昨天正好写完了骨骼动画的插件,趁热打铁整理了一下3DMAX的场景组织和几何管道的方式,以下是潘李亮大师关于场景组织和几何管道的讲解。

(1) MAX的整个场景是一个树状结构,树的节点用INode来表示,整个树的根节点可以通过Interface::GetRootNode来获得,场景中的所有物体都是INode。INode中的NumberOfChildren函数和GetChildNode则用来访问INode的子节点。要遍历整个场景中对象,只需要通过Interface::GetRootNode和GetChildNode做一个递归就可以了。如果仅仅是想获得在视口中选定的物体,则可以使用Interface::GetSelNodes函数。

(2) INode仅仅是一个虚拟的节点,它本身仅仅包含一些标记和变换信息,并不表示实际的Object。实际的Object需要附着在INode上,并以INode的坐标系为Object的本地坐标系。Max中常见的Object有Shape(各种参数曲线)、Camera、Mesh等。Object有自己的变换矩阵(TM), 在很多情况下这个矩阵都是单位矩阵。
INode的变换矩阵可以通过INode::GetNodeTM来获得,而附着在INode上的Object的变换矩阵则通过 INode::GetObjectTM来获得,因为Object相对于Node的变换矩阵通常是单位矩阵,GetNodeTM和GetObjectTM获得的矩阵通常也是一样的,但是在必要的时候一定要加以区别。关于INode和Object的变换矩阵问题的详细可以参考潘李亮大师的 http://blog.csdn.net/Nhsoft/archive/2005/01/06/241629.aspx

(3) 管道。
[转] 3DMax 一些基本认识 - kasicass - Code@Pig Home
 

前面说过Object是附着在INode上的,在MAX里,Node有一个 Object Reference的指针,指向一个物体对象。熟悉MAX的操作方式的读者都知道,我们在MAX里建立一个对象后,可以在上面添加各种修改器 -Modifier。在Max的几何管道中,我们建立的对象通常称为Base Object。所有施加在这个物体上的修改器形成一个修改器堆栈-ModStack。BaseObject经过这个ModStack后形成一个新的 Object Reference。ModStack中的每个Modifier都是输入一个Object Reference,输出一个Object Reference, 并且在应用第一个Modifier的时候会自动在几何管道里插入一个Derived Object。最终INode的Object Reference将指向这个Derived Object。

Modifier在管道中的应用实例是ModApp对象,一个ModApp代表一个应用在Object上Modifier修改,ModApp包含一个ModContext的数据对象,Modifier用ModContext中的数据来对Object进行修改,以生成最终数据。

修改器按照应用的坐标系不同分成局部空间修改器和世界空间修改器(World Space Modifier)。局部空间修改器仅仅在Object的局部空间中修改Object,不会对坐标系造成影响。世界空间的修改器比如水波纹修改器则要求先将物体变换到世界空间后再进行修改,修改完成后的坐标也是世界空间的坐标。相对来说处理世界空间修改器会麻烦的多。(如果一个物体应用了世界空间修改器,则通过Mesh对象取得的坐标已经是世界坐标系中的了。不需要再乘以INode::GetObjectTM了)。

举个例子。比如在3dmax里建了一个Box对象Box01,那么这个Box在进入管线的时候即为一个Base Object——Box,然后你可以为这个Box添加各种合适的修改器(Modifer),比如Bend,Skin,Physique等等。这些修改器将形成一个修改器堆栈,即ModStack,Base Object经过这个ModStack后将形成一个Object Reference,当第一个Modifer应用的时候会自动地在管线里加入一个Dirived Object,最终INode的Object Reference将指向这个Derived Object。

注意:ModStack中的每个Modifier都是输入一个Object Reference,输出一个Object Reference,比如我们想得到Skin修改器的Modier:

Modifier *GetSkinModifer( INode *pNode )
{
  Object *pObject = pNode->GetObjectRef();
  while ( pObject->SuperClassID() == GEN_DERIVOB_CLASS_ID )
  {
    IDerivedObject *pDerivedObj = (IDerivedObject *)pObject;
    for ( int iStack = 0; iStack < pDerivedObj ->NumModifiers(); iStack++ )
    {
      Modifier *pModifier = pDerivedObj->GetModifier(iStack);
      if ( pModifier->ClassID() == SKIN_CLASSID )
        return pModifier;
    }
    //下一个Derived Object
    pObject = pDerivedObj->GetObjRef();
  }
  return NULL;
}

首先pNode->GetObjectRef();这个是前面讲的,INode通过GetObjectRef()得到它指的那个Derived Object,随后用一个循环判断pObject是不是GEN_DERIVOB_CLASS_ID,正因为每个Modifier都是输入一个Object Reference,输出一个Object Reference,所以pObject = pDerivedObj->GetObjRef();实质上不断获得其下一个的Object Reference。如此来遍历Mod Stack中的每个Modifier

  评论这张
 
阅读(1133)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017