李寅飛
東華大學(xué)信息與科學(xué)技術(shù)學(xué)院,上海 201610
Maya的模型信息提取研究
李寅飛
東華大學(xué)信息與科學(xué)技術(shù)學(xué)院,上海 201610
Maya是Autodesk公司中和3dMax并列的三維建模和動(dòng)畫軟件,而且在模型的細(xì)節(jié)渲染方面有著更為突出功能,隨著技術(shù)的進(jìn)步和用戶對(duì)三維圖形動(dòng)畫要求的提高,Maya已經(jīng)廣泛的應(yīng)用到電影、電視、游戲等領(lǐng)域。因此,如果能將Maya中的模型信息從Maya軟件中提取出來,并按照一定的渲染方法重新組建,就能將依賴Maya的圖形文件用于其他設(shè)備上進(jìn)行三維展示,例如平板電腦,智能手機(jī)等移動(dòng)設(shè)備上。這樣,就能在很大程度上提高產(chǎn)品模型的展示效果。本文將介紹如何利用Maya的Api 將Maya模型中的信息提取出來,并按照OpenGl的模型渲染格式進(jìn)行儲(chǔ)存。
Maya;node;mesh;face;vertex;OpenGL
要成功的提取Maya模型中的信息,必須要知道Maya中的數(shù)據(jù)結(jié)構(gòu),知道Maya中的Api運(yùn)行模式,掌握Maya模型的類別,模型的構(gòu)成方式,模型屬性組成等等信息。當(dāng)掌握了這些信息之后,就能實(shí)現(xiàn)模型重構(gòu)和再實(shí)現(xiàn),以完成模型在其他顯示平臺(tái)的遷移。
我們可將整個(gè)Maya 系統(tǒng)拆分為3個(gè)主要組成部分: 圖形用戶界面 ,MEL Command Engine ,Dependency Graph 。
Maya用戶可以與Maya Gui進(jìn)行交互,可以選擇菜單項(xiàng),更改參數(shù),使對(duì)象動(dòng)畫化以及移動(dòng)對(duì)象等等,當(dāng)與用戶界面進(jìn)行交互時(shí),Maya實(shí)際是再發(fā)出MEl命令,這些命令唄發(fā)送到Command Engine,并在這里被解釋并執(zhí)行。
大部分的MEL命令運(yùn)行與Dependency Graph直接交互。這樣做是因?yàn)镈ependency Graph可以被直觀地看做是一個(gè)完整的場(chǎng)景,這個(gè)場(chǎng)景是組成3D世界的所有重要數(shù)據(jù)和信息。Dependency Graph不僅定義當(dāng)前場(chǎng)景中有什么數(shù)據(jù),還定義了數(shù)據(jù)的處理方式。Dependency Graph 實(shí)際就像Maya的心臟和大腦。
我們將Dependency Graph簡(jiǎn)稱為DG,DG是Maya的核心,它包括Maya模型的所有基本構(gòu)建,它允許你創(chuàng)建任意的數(shù)據(jù),這些數(shù)據(jù)進(jìn)行一系列的操作處理后,最終生成一些經(jīng)過加工的數(shù)據(jù)。在DG中,數(shù)據(jù)及其操作被封裝為節(jié)點(diǎn),一個(gè)節(jié)點(diǎn)含有任意數(shù)目的插槽,其中還有Maya使用的數(shù)據(jù),節(jié)點(diǎn)也包含一個(gè)操作符,用于對(duì)其數(shù)據(jù)進(jìn)行處理以生成一些其他的數(shù)據(jù)。
由圖1所示節(jié)點(diǎn)實(shí)際是Maya的基本構(gòu)件,每個(gè)節(jié)點(diǎn)都有一個(gè)或者多個(gè)與其相關(guān)的特性,這些特性通常唄成為屬性,每個(gè)節(jié)點(diǎn)根據(jù)其屬性的不同實(shí)現(xiàn)對(duì)數(shù)據(jù)的不同操作。
Maya中有多種模型類型,但最常用的靜態(tài)模型主要使用的是nurb,polygon 和 subdiv。
Mesh 英文翻譯為網(wǎng)格,在Maya中則用于代表一個(gè)三維實(shí)體,例如一個(gè)立方體、圓錐體、球體,這些都是Mesh。而模型中的每個(gè)面則就是polygon,如下圖的球體模型則更能體現(xiàn)出mesh和polygon的關(guān)系,圖中的每個(gè)四邊形方格就是一個(gè)polygon。
Polygon主要有3個(gè)主要元素:vertices , edges, faces除此之外還有兩個(gè)有助于理解和分析polygon如何工作和運(yùn)行的元素 Facevertices 和 UVs。
Polygon的Vertices元素是一個(gè)表示3d的浮點(diǎn)型數(shù)組,每個(gè)點(diǎn)都有自己的元素id,每條邊和每個(gè)面都是基于這個(gè)數(shù)組產(chǎn)生的。如表1。
3 D Float Point 行中每一個(gè)元素都是一個(gè)三維坐標(biāo)(x,y,z)Edge元素儲(chǔ)存在一個(gè)邊數(shù)組中,數(shù)組中的每個(gè)元素儲(chǔ)存著兩個(gè)整型變量,儲(chǔ)存著vertices的id,第一個(gè)表示邊的起始點(diǎn),第二個(gè)表示結(jié)束點(diǎn),這樣儲(chǔ)存數(shù)據(jù)就能表示邊的點(diǎn)組成,點(diǎn)邊的方向以及邊的編號(hào)。如表2。
表2
Edge行中的每個(gè)元素都是一個(gè)二維的點(diǎn),表示邊的起始點(diǎn)和結(jié)束點(diǎn)的id Faces的元素儲(chǔ)存在一個(gè)整數(shù)型數(shù)組中,每個(gè)面被一系列數(shù)字表示,每個(gè)數(shù)字都表示一個(gè)邊的索引。與之相應(yīng)的的是face offset 數(shù)組,這個(gè)數(shù)組標(biāo)示了每個(gè)面在face數(shù)組中每個(gè)面的起始點(diǎn),具體格式如表3,表4。
表3
表4
如表4中所示,face 1 的起始點(diǎn)在 EdgeId的Index 3 即,F(xiàn)ace 1是由,0,1,2三條邊組成的三角面。
Face-vertices 是將一個(gè)Mesh中的每個(gè)面的相對(duì)vertices 索引,就是說,他們都是以0為起始的整數(shù)數(shù)列。并不是以整個(gè)Mesh為基礎(chǔ)的全局索引坐標(biāo)。UV uv是專門用于描繪紋理信息的元素,其對(duì)應(yīng)著每個(gè)每個(gè)點(diǎn)都有與之相對(duì)應(yīng)的uv,我們要把二維貼圖與3d模型想匹配,必須找到每個(gè)3d坐標(biāo)對(duì)應(yīng)的uv。
在Maya的C++ Api 中,選取模型有兩種形式,第一種選取指定模型信息,第二種選取全部模型信息。
選取指定模型需要用到的變量類型 ∶ MSelectionList 。顧名思義,這個(gè)變量類型儲(chǔ)存了用戶的模型選擇信息,即用戶在軟件界面選擇的圖像(單選或者多選)。然后利用MGlobal類里面的成員函數(shù)getActiveSelectionList函數(shù)將MSelectionList變量進(jìn)行賦值,如此我們?cè)O(shè)置的MSelectionList類型變量就得到了賦值。
得到了選取列表之后,就需要利用選擇迭代器對(duì)選擇列表里面的內(nèi)容進(jìn)行遍歷。MItSelectionList ,MItSelectionList 也是一個(gè)類,里面有豐富的函數(shù)可以對(duì)選擇列表里面的內(nèi)容進(jìn)行操作,利用里面的next()函數(shù) 和isDone()函數(shù)可以對(duì)他儲(chǔ)存的變量進(jìn)行遍歷MItSelectionList遍歷的內(nèi)容其實(shí)就是我們上面提到的Dependency Graph 中所提到的節(jié)點(diǎn)DagNode,但是MItSelectionList類中并沒有直接提取節(jié)點(diǎn)的函數(shù),它值提供了每個(gè)節(jié)點(diǎn)的路徑DagPath,通過DagPath我們就可以定位到相應(yīng)的節(jié)點(diǎn)對(duì)模型操作。
要實(shí)現(xiàn)模型的轉(zhuǎn)移,就需要知道模型的點(diǎn)信息,面信息,點(diǎn)信息包括 點(diǎn)的空間坐標(biāo),點(diǎn)的模型序列,點(diǎn)法線信息。面信息包括面?zhèn)€數(shù),每個(gè)面的組成,在模型構(gòu)成中,任何一個(gè)面都可以分解成若干個(gè)三角面,而Maya中的模型構(gòu)成也是按照這個(gè)原則,因此,我們提取面的信息的時(shí)候是將模型中的面都分解為若干個(gè)三角面,并將每個(gè)面的點(diǎn)和點(diǎn)的索引相聯(lián)系。
3.2.1 提取點(diǎn)的坐標(biāo)以及索引
通過上面一步我們得到了dagpath,這里我們就以polygon模型為例提取上面提到過的模型信息首先創(chuàng)建mesh類的實(shí)力 MFnMesh這個(gè)類 ,通過這個(gè)類我們就可以直接得到點(diǎn)的信息以及三角面的信息,這里我們得到的點(diǎn)是以一定順序儲(chǔ)存的point序列。以立方體為例,point序列的索引為0-7,分別記錄了空間坐標(biāo)的點(diǎn),通過GetPoints函數(shù)我們就可以得到這個(gè)數(shù)列。
3.2.2 提取每個(gè)三角面的索引
通過MFnMesh類之中我們通過getTriangles函數(shù)就可以得到面的信息,主要得到兩變量,一是我們這個(gè)立方體的三角面的個(gè)數(shù),因?yàn)榱骟w是六個(gè)四邊形,因此我們得到的三角面是十二個(gè),而另一個(gè)變量就是每個(gè)三角面的點(diǎn)與我們得到的點(diǎn)的對(duì)應(yīng)索引,以這個(gè)立方體為例,我們得到的數(shù)列如下(0,1,2,2,1,3,2,3,4,4,3,5,4,5,6,5,7,6,7,0,0,7,1,1,7,3,3,7,5),這些點(diǎn)每3個(gè)對(duì)應(yīng)一個(gè)面,因?yàn)槲覀円粤⒎襟w為對(duì)象,所以每六個(gè)點(diǎn)為同一個(gè)四邊形的兩個(gè)三角面,而且可以看出每個(gè)四邊形的組成。
通過上面的步驟我們成功的得到了每個(gè)三角面的信息,通過這些單獨(dú)的三角面信息我們就能通過opengl進(jìn)行仿真對(duì)每個(gè)面配上顏色我們就能實(shí)現(xiàn)模型結(jié)構(gòu)的提取。
3.2.3 提取每個(gè)點(diǎn)的法線
為了使一個(gè)細(xì)分度很高的Polygon Mesh 在轉(zhuǎn)移的情況下表現(xiàn)的更加平緩和光滑,即表現(xiàn)的和軟件中更加相似,就需要提取每個(gè)點(diǎn)的法線。
這里我們用到的是MItMeshVertex類來對(duì)Mesh的每個(gè)點(diǎn)進(jìn)行遍歷,然后通過getNormals函數(shù)得到一個(gè)MVectorArray變量,里面儲(chǔ)存了每個(gè)點(diǎn)相對(duì)于每個(gè)面的法線值,通過計(jì)算我們可以得到每個(gè)點(diǎn)的實(shí)際法線。
下面是具體程序?qū)崿F(xiàn):
MItDag dagIter( MItDag∶∶kBreadthFirst, MFn∶∶kMesh, &stat );
通過以上幾步,我們將成功得到所需要的點(diǎn)的空間坐標(biāo),點(diǎn)的個(gè)數(shù),面的個(gè)數(shù),每個(gè)面與相應(yīng)點(diǎn)的索引,每個(gè)點(diǎn)的點(diǎn)法線通過歸一化之后的信息。通過這些信息,我們就能成功的利用OpenGl模擬出模型的體信息
通過OpenGl中的glBegin(GL_TRIANGLES)函數(shù)我們可以將得到的數(shù)據(jù)重新組合成圖形,因?yàn)槲覀冎惶崛×嘶灸P托畔?,?duì)于紋理和材質(zhì)并沒有提取,所以,只能生成模型本體,通過設(shè)置glPolygonMode可以將我們形成線框?qū)嶓w化。如圖2是軟件中的圖形,圖3是仿真后的圖形。
圖2
圖3
我們從Maya的數(shù)據(jù)結(jié)構(gòu)入手,分析了他的模型信息儲(chǔ)存結(jié)構(gòu),通過得到正確的模型信息我們就能將模型從Maya中遷移出來,利用openGl將這些信息重現(xiàn),我們就能讓3d模型脫離那些消耗系統(tǒng)資源巨大的軟件,而在我們希望的平臺(tái)展示。
[1]Watt A 3D計(jì)算機(jī)圖形學(xué)(第三版).機(jī)械工業(yè)出版社,2005.
[2]Maya user manual(瑪雅用戶手冊(cè))[OL].http://www.autodesk.com/maya
[3]Woo M,Neider J,DavisTj,Shreiner D.OpenGL 編程權(quán)威指南(第三版)[M].北京:中國電力出版社,2003.
TP31
A
1674-6708(2012)58-0157-02