賽后總結(jié)
本人小菜,WPF剛?cè)腴T,只是寫一下最近的項目心得。歡迎各位前輩們前來拍磚指正,感激不敬!先申明,小弟我入門倉促,很多東西也是一知半解,所以很多問題甚至是不求甚解,所以大神們就直接繞路算了。
總結(jié)一:3D max+blend+WPF綜合運用
開發(fā)環(huán)境:
Autodesk 3ds Max Design 2012
Micosoft Expression Blend 4 ,
Microsoft Visual Studio 2010
小弟之前參加一個項目,得用到WPF3D編程,但是WPF的3D只有最基本的3D場景元素,比如攝像機,光照等。如果想要在WPF中畫一個正方體或者球體,都得自己一步一步的把每個網(wǎng)格點的坐標算好,三角網(wǎng)格的頂點順序添加好,設(shè)置法向量,貼圖的話也得自己指定好對應(yīng)的頂點坐標。畫個簡單的模型都如此麻煩了,稍微復(fù)雜點的模型,只能依賴第三方建模軟件來構(gòu)建模型,然后把模型轉(zhuǎn)換成松散的XAML文件,才能導入到WPF中去,或者把模型的相應(yīng)XAML代碼直接嵌入到程序中去。
工欲善其事必先利其器,下面是我找到的相關(guān)工具和相關(guān)示例,有些我自己也沒用過:
1. 3D MaxStudio有導出XAML的插件:http://max2xaml.codeplex.com/
2. 還有開源的Blender: http://www.blender.org/ 以及相應(yīng)的導出XAML的插件:
http://xamlexporter.codeplex.com/
3. 還有Viewer3ds-3ds to xaml converter:http://www.wpf-graphics.com/Viewer3ds.aspx
4. WPF(c#)有專門的3D建模工具,使用起來和3DMax差不多,制作完成后可直接導出XAML語言方便快捷:ZAM 3D :http://www.erain.com/products/zam3d/DefaultPDC.asp
示例:
1.WPF加載obj格式的3D模型:http://www.pin5i.com/showtopic-26486.html
2.3ds Max建模,Blend設(shè)計,VS2008控制WPF的3D模型例
http://www.cnblogs.com/foundation/archive/2008/05/23/1205892.html
http://www.cnblogs.com/couhujia/archive/2010/07/28/1787103.html
http://zhouwenqi.com/blog/board_33.html
現(xiàn)在網(wǎng)上可以下載到很多絢麗逼真的3D模型,模型有很多格式,我們這次之所以選擇了.Max格式,因為網(wǎng)上很多模型(尤其是游戲角色原型)都是.max格式,其他的格式大多都可以在3Dmax中打開,然后再保存為.max格式。
小弟的3Dmax門都沒入,項目做到一半恨不得馬上找一個傳設(shè)的女友幫我建模做美工,無奈之下,去圖書館速度借了2本3Dmax的書,需要的時候啃兩下,因此只掌握了最基本的模型導入,導出和修改合成的功能。
下面以一個游戲角色原型(誅仙中的某個武士)為例,這個原型是在網(wǎng)上下載的,具體網(wǎng)址是我忘記了。在3Dmax中打開這個模型后,可以隨心所欲的修改,肢解,或合體。
提醒:打開模型時如何文件單位比例和系統(tǒng)單位比例不匹配時,就會彈出以下的對話框讓你選擇。選擇哪個都無所謂,按自己的需要選擇吧!但如果兩者比例相差太大,比如下面的系統(tǒng)單位比例是1單位=1cm,而文件單位比例是1單位=1m,如果按系統(tǒng)單位打開的話,模型可能在3dmax視圖中過大,沒能在3Dmax視圖中顯示出來或者只顯示模型的局部,這時選擇右下角這個按鈕(
選擇保存類型為obj格式,然后給文件命名為man1,再點擊保存,就會有如下“OBJ導出選項”的對話框:
單純的obj格式是不帶貼圖的,想要把貼圖一同導出的話得勾選材質(zhì)選項的“導出材質(zhì)”“創(chuàng)建材質(zhì)庫”,同時點擊“材質(zhì)導出”按鈕,就會彈出“OBJMap-Export選項”對話框,在這里可以選擇圖片保存的格式和大小。然后選擇“導出”,obj,mtl和相應(yīng)的貼圖圖片文件就會在3dmax的export文件夾下,貼圖信息存放到.mtl,具體的貼圖則存放到Maps文件夾下。
提醒:導出時如果出現(xiàn)“缺少貼圖”的對話框,得“手動搜索路徑”,如果跳過的話只會有mtl和obj文件,而不會有具體的貼圖文件。搜索路徑一般為原模型的所在的路徑,因為.dds格式的文件一般都和.max模型文件一起。
然后打開Blend 4,新建項目->WPF應(yīng)用程序,單擊確定。
選擇“項目”->“添加現(xiàn)有項”,出現(xiàn)下面對話框,把man1.mtl和man1.obj兩個文件添加到項目中去。此時,雙擊man1.obj文件就可以把不含貼圖的模型載入到當前工程中。拖拽右下角的正方形邊框可以控制模型大小,一般情況下就可以看到不帶貼圖的模型了,大多都是光禿禿的單調(diào)灰白色。
但是為什么我這里什么也看不見呢?仔細看看,Blend確實已經(jīng)載入模型了(如下圖):
只不過我遇到稍微特殊情況,不是看不到,是因為“漫射材料”的“紋理畫筆”或者“漫射顏色”設(shè)為透明了。稍微修改一下就可以看到模型了,比如我這里修改褲子模型的“漫射材料”的“紋理畫筆”和“漫射顏色”的A值設(shè)為100%,即不透明,就可以看到單調(diào)的灰色模型。
但這樣的模型肯定沒有漂亮的貼圖,只有單調(diào)顏色,所以需要我們自己加載相應(yīng)的貼圖。當時我很郁悶,因為Blend4的用戶指南上說了“在導入三維對象(.obj文件)時,同時導入任何相關(guān)的材料文件 (.mtl)以及材料文件中使用的所有圖像文件很重要。如果丟失了任何圖像文件,以后將無法添加這些文件”。因此看來是我沒導入圖片文件的緣故,于是馬上“添加現(xiàn)有項”,把四個貼圖文件加載到項目中,依然看不到帶貼圖的模型,在這里郁悶良久,找不到解決的方法,只得自己手動為每個模型加載貼圖了。這其實是一條遠路,近路后來發(fā)現(xiàn)了,后面會介紹。比如為頭部添加紋理圖片,效果如下:
在Blend中還可以對模型進行基本的調(diào)整,諸如放縮,旋轉(zhuǎn),平移等操作。
然而依然有不足之處,貼圖細節(jié)處依然有問題。比如Blend中的模型背面和3Dmax元模型的背面差別如下:估計是因為貼圖坐標不對應(yīng)造成的,用3Dmax導出的圖片直接在Blend里貼的話,達不到原來的效果?;蛘哒f目前我們做不到,可能美工大神們做得到。這些應(yīng)該屬于美工那邊的。哎。
然后可以用VS2010打開Blend4中所創(chuàng)建的WPF項目,可以在VS2010中繼續(xù)添加相應(yīng)的交互界面和控制按鈕,這里就不嘮叨了,自己啃書去吧!
繼續(xù)糾結(jié)用戶指南中的“在導入三維對象(.obj文件)時,同時導入任何相關(guān)的材料文件 (.mtl)以及材料文件中使用的所有圖像文件很重要。如果丟失了任何圖像文件,以后將無法添加這些文件”這句話的深意,我猜測是貼圖路徑問題,貼圖的信息是由3Dmax導出的,且存在mtl格式文件中,后來打開mtl文件,才發(fā)現(xiàn)貼圖文件前面都有一個maps文件路徑(如下),果然如此。
于是趕緊在項目中新建一個maps文件夾,然后把貼圖加載到這個文件夾下,再雙擊obj文件,這時Blend就自動幫咱們貼圖了。但是缺陷依然存在,和之前提到的不足之處一摸一樣,背面的貼圖自動貼的和手動貼的效果一樣,效果和原始3Dmax模型還是有一些差別的,這已經(jīng)超出IT碼農(nóng)范疇了,去找個美工妹子吧!
總結(jié)二:WPF載入松散的XAML模型
我們的項目需要把3Dmax模型載入到WPF中,主要涉及模型的存放、導入和控制。
首先是模型的存放問題。前面用3Dmax模型在Blend中設(shè)計,之后用VS2010打開這個項目后,會發(fā)現(xiàn)模型對應(yīng)的相應(yīng)的xaml代碼已經(jīng)嵌入到程序中了。如果多個模型怎么辦?不可能把每個模型對應(yīng)的xaml代碼敲入到程序中,這樣既不美觀也不利于后面的模型各自控制。
于是得把模型的xaml代碼摳出來,放到txt中,再重命名為xaml格式,就是一個松散的xaml模型文件了。
其次是模型的導入。存放到xaml文件中的模型如何導入到wpf中,主要通過文件流FileStream打開,然后用XamlReader加載,根據(jù)不同的模型類型加載到不同類型的變量里。一般松散的xaml模型類型有GeometryModel3D,Model3Dgroup等,看自己的需要去轉(zhuǎn)換。
public void LoadModel(ref GeometryModel3D _model,string path)
{
if (path != null&& File.Exists(path))
{
using (FileStream file = File.OpenRead(path))
{
_model = (GeometryModel3D)XamlReader.Load(file);//
}
}
}
public void LoadModel(refModel3DGroup _model, string path)
{
if (path != null &&File.Exists(path))
{
using (FileStream file = File.OpenRead(path))
{
_model = (Model3DGroup)XamlReader.Load(file);
}
}
}
最后是模型的控制,如何根據(jù)Kinect中提供的肢體數(shù)據(jù)實時變換模型姿勢,我們只是把衣服切成一塊塊生硬地掛在骨骼節(jié)點上,沒有考慮一切物理效應(yīng),諸如重力,碰撞檢測,骨骼蒙皮等效果。因為WPF的3D功能沒那么強大,除非得借助其他的游戲引擎才行,或者自己從底層編寫,當時時間緊迫,只能生硬地把模型切割,再分塊貼上去。Kinect的骨骼數(shù)據(jù)提供的XYZ空間坐標方位,那么2個骨骼點間連線的角度和方向都很容易計算,然后把模型通過一系列的平移,旋轉(zhuǎn),放縮變化放到相應(yīng)的骨骼點上。
為了達到增強現(xiàn)實的效果,在WPF界面中,Viewport3D和顯示原始視屏流Image控件的大小一摸一樣,位置完全重合。然后把Camera放在空間坐標系坐標零點,這樣Camera就和真實空間中的Kinect傳感器的位置,朝向一致了。所以,Viewport3D中的虛擬效果正好可以覆蓋在底層視屏中的人身上,達到增強現(xiàn)實的效果。但是會有小小的偏差,源于Kinect骨骼數(shù)據(jù)不是很精確,所以還需要自己手動修正一些細節(jié),從而讓效果更真實點。