虛擬人(行走)運動控制設(shè)計實現(xiàn)論文_第1頁
虛擬人(行走)運動控制設(shè)計實現(xiàn)論文_第2頁
虛擬人(行走)運動控制設(shè)計實現(xiàn)論文_第3頁
虛擬人(行走)運動控制設(shè)計實現(xiàn)論文_第4頁
虛擬人(行走)運動控制設(shè)計實現(xiàn)論文_第5頁
已閱讀5頁,還剩34頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

PAGE摘要本文在參閱和分析了大量有關(guān)文獻的基礎(chǔ)上,對現(xiàn)有的各種實現(xiàn)虛擬人運動控制的方法進行了總結(jié),特別是對當(dāng)前廣泛使用的參數(shù)化關(guān)鍵幀技術(shù),基于物理的仿真技術(shù),運動捕獲技術(shù)以及運動編輯技術(shù)等,對各種方法的優(yōu)缺點進行了分析。在此基礎(chǔ)上研究并實現(xiàn)了虛擬人(行走)運動控制。通過對虛擬人模型的研究,在VC6.0平臺基于DIRECTX的基礎(chǔ)上,結(jié)合計算機圖形學(xué)的基本知識,使用參數(shù)化關(guān)鍵幀技術(shù)實現(xiàn)了虛擬人的運動,通過坐標(biāo)平移實現(xiàn)虛擬人的行走,旋轉(zhuǎn)實現(xiàn)虛擬人的轉(zhuǎn)彎。關(guān)鍵詞:DIRECTX,虛擬人,人體動畫,運動控制,關(guān)鍵幀,運動捕獲AbstractInthispaper,onthebasisoftheanalysisandclassificationofavarietyofmethodsformotioncontrolinvirtualhuman,aclearoverallpictureofallthosemethodsisprovided.Itisdiscussedinthepaperthetechnologiesofmotioncontrolsuchaskeyframing,proceduremethod,motioncapture,simulationbasedonphysicsandtheiradvantagesanddisadvantagesaswell.Andthenwestudyandimplementthecontrolofthevirtualhuman'smovement(walking).BasedontheknowledgeoftheComputerGraphics,thetenchnologyofkeyframingisusedtoachieveitontheplatformofVC6.0andDIRECTX.Indetail,weimplementthewalkingofthevirtuanhumanbythetranslationofthecoordinate,andtheswervebythecoordinate'srotation.Keywords:virtualhuman,humananimation,motioncontrol,keyframe,motioncapture -PAGEii-目錄第1章緒論 11.1虛擬人的作用和意義 11.2本論文的背景 2第2章虛擬人運動控制的研究現(xiàn)狀 31.1概述 32.2虛擬人運動模型 42.3虛擬人運動關(guān)鍵技術(shù) 52.4小結(jié) 8第3章DIRECTX技術(shù) 93.1概述 93.2DIRECTX3D對象及設(shè)備 103.2.1DIRECTX對象(D3DObject) 103.2.2DIRECTX設(shè)備(D3DDEVICE) 103.3矩陣(Matrices) 123.3.13D迪卡爾坐標(biāo)系統(tǒng)和矩陣定義 123.3.2矩陣變換 123.3.3場景變換矩陣 143.4在DIRECTX3D中使用網(wǎng)格模型 153.4.1載入一個網(wǎng)格模型對象 153.4.2渲染一個網(wǎng)格模型對象 173.4.3釋放一個網(wǎng)格模型對象 173.5DIRECTINPUT 183.6小結(jié) 18第4章用DIRECTX設(shè)計實現(xiàn)虛擬人運動控制 194.1虛擬人造型 194.1.1用3DMAX建模 194.1.2虛擬人數(shù)據(jù)導(dǎo)出 194.1.3虛擬人數(shù)據(jù)結(jié)構(gòu) 204.2使用DIRECTX實現(xiàn)虛擬運動控制 254.2.1關(guān)鍵幀的設(shè)計 254.2.2平移實現(xiàn)行走 264.2.3旋轉(zhuǎn)實現(xiàn)轉(zhuǎn)彎 274.2.4程序的構(gòu)造和流程 284.2.5行走實現(xiàn)例子 33第5章結(jié)束語 345.1本文的工作總結(jié) 345.2展望 34參考文獻 35致謝 36江蘇大學(xué)本科生畢業(yè)論文-PAGE36-第1章緒論1.1虛擬人的作用和意義虛擬人是完全由計算機表示,看起來像真人的圖形實體[1],即人的計算機模型。它作為虛擬環(huán)境中有特色的群體,歷來受到研究者的額外重視。一方面,它可以作為真人的替代者對計算機設(shè)計的車輛,工作區(qū)域,機器工具,裝配線等在實際構(gòu)造前進行人類工效學(xué)的評估;在真人無法到達的環(huán)境中進行各種精密的,甚至危險的實驗;在軍事上代替真人接受各種訓(xùn)練;在醫(yī)學(xué)上代替真人接受一些矯形手術(shù);在航空軍事上代替真人從事太空作業(yè)等等。另一方面,它可以作為我們自身或其他實際參與者在虛擬環(huán)境中的實時表示。圖1-1給出了幾種虛擬人的表示:圖SEQ圖\*ARABIC1-1虛擬人模型通過對虛擬人的研究和應(yīng)用,可以使用戶得到以下兩種特性:(1)逼真性:用戶通過虛擬人所得到的感受與他在真實系統(tǒng)中得到的感受盡可能相同,通過各種感官和系統(tǒng)發(fā)生交互作用,具有“身臨其境”的逼真感。(2)虛擬性:用戶通過虛擬人能夠得到他在真實物理世界中所無法親身體驗的感受,突破物理空間,時間的限制和避免涉及生命安全的和環(huán)境,用戶得到了虛擬人的“超越現(xiàn)實”的虛擬性。虛擬人的研究和發(fā)展,使研究者可以直接以人為研究對象,開展各種有意義的人類活動的研究,一方面提高對人類自身的認識,一方面進行各種在現(xiàn)實中無法進行的,于人類有益的試驗。例如,在生物力學(xué)領(lǐng)域,可以對人后背的變形,不正確姿態(tài)的影響,語言機能障礙和視覺機能障礙進行仿真。模擬處于危險狀況中的人:交通事故,飛機失事,火災(zāi),爆炸等。在虛擬戰(zhàn)場中,模擬對軍事人員的訓(xùn)練等等。這一切對于改善人類的生活,生活環(huán)境,擴展人類的活動范圍,提高人類的生存質(zhì)量具有重要而深遠的意義。因此虛擬人已經(jīng)成為國內(nèi)外計算機科學(xué)中主要的研究方向之一,具有廣闊的應(yīng)用背景,在未來的教育,生活,科研中必將發(fā)揮巨大的作用。1.2本論文的背景在虛擬環(huán)境中,利用虛擬人來模擬真實人的行為并對其性能進行評估,這在動畫機械工程醫(yī)學(xué)軍事和空間探索等應(yīng)用中變得越來越重要。隨著虛擬人技術(shù)的日益成熟,虛擬人已被廣泛的應(yīng)用于工程,虛擬會議,交互,監(jiān)控,虛擬環(huán)境,游戲,訓(xùn)練,教育,軍事訓(xùn)練,產(chǎn)品的設(shè)計與維護等領(lǐng)域,隨著虛擬現(xiàn)實技術(shù)的快速發(fā)展在虛擬環(huán)境中建立理想的,綜合的虛擬人已經(jīng)逐漸成為人體動畫研究中的一個新的方向。在虛擬人的研究中,虛擬人的運動控制的研究是虛擬人研究中的一項十分重要的內(nèi)容。本文通過對虛擬人運動模型的研究,結(jié)合圖形學(xué)的相關(guān)知識在DIRECTX下實現(xiàn)了虛擬人的運動(行走)控制技術(shù)。第2章虛擬人運動控制的研究現(xiàn)狀1.1概述在國外研究虛擬人運動控制的眾多團體中,由蒙特利爾大學(xué)Magnenat-Thalmann和Thalmann所帶領(lǐng)的研究團隊比較著名。一支是由Magnenat-Thalmann帶領(lǐng)的在日內(nèi)瓦的MIRALab,MIRALab主要是以研究人臉的表情動畫[2],手部的變形以及虛擬人的附屬物例如服裝,頭發(fā)等為主。另外一支是由Thalmann帶領(lǐng)的在洛桑的LIG實驗室,LIG實驗室只要從事人體建模及變形的研究,人的行走,抓取等動作的研究,以及運動控制系統(tǒng),運動捕獲,人體動畫工具的開發(fā),人體平衡控制的研究,碰撞檢測技術(shù)和基于網(wǎng)絡(luò)的虛擬人的研究等。另一個比較著名的研究團體是賓夕法尼亞大學(xué)由Badler領(lǐng)導(dǎo)的人體建模與仿真中心。他們的研究包括參數(shù)化的關(guān)鍵幀技術(shù)在基于關(guān)節(jié)虛擬人的模型中的應(yīng)用,逆運動的應(yīng)用,人體的平衡研究,脊骨的建模,行走模型的建立,運動捕獲的研究,人的沖突檢測和糾正以及智能運動規(guī)劃問題的研究等。另Bruderlin和Calvert致力于研究虛擬人的動態(tài)行走模型Kunii和Sun致力于虛擬人的動力學(xué)方面的研究;Calvert等人在虛擬人的舞蹈方面也有所突破;Terzopoulos和Waters從事基于物理的人的面部表情的動畫研究,而Essa和Pentland則從基于視覺的角度研究虛擬人的面部表情的動畫;Animationlab的以Hodgins[3]等人為骨干主要從事動態(tài)仿真技術(shù)方面的研究,并成功的實現(xiàn)了很多體育運動的仿真(如跳水跳馬自行車賽等)。國內(nèi)在虛擬人的建模與運動控制方面,華中理工大學(xué),北京航空航天大學(xué),中國科學(xué)院,哈爾濱工業(yè)大學(xué)以及浙江大學(xué)等學(xué)校都做了大量的理論研究及實踐工作。其中,在人機交互方面華中理工大學(xué)陳立平等人在基于人機功效學(xué)的人體建模和運動仿真方面進行了研究;北京航空航天大學(xué)的袁修干等人主要在人機系統(tǒng)仿真中的三維人體建模的方面進行了研究。在人體建模方面,中國科學(xué)院計算機技術(shù)研究所CAD開放實驗室的詹永照等人,給出了以多面體組合建立粗略的人體,用多面體細分割來逼近真實人體曲面的方法,并在建模中考慮了人體的動態(tài)特性,為建立人體動畫模型創(chuàng)造了條件。在虛擬人的實時運動控制方面,哈爾濱工業(yè)大學(xué)的賀懷清等人致力于研究虛擬人的實時運動控制,并實現(xiàn)了虛擬人的步行與跑步運動方式;中國科學(xué)院的王兆其等人在人體行為交互方面做了大量的研究,并且應(yīng)用虛擬人合成技術(shù)實現(xiàn)了人體行為交互的主要工作,并將其研究成果應(yīng)用在聾人手語交互等方面的應(yīng)用;浙江大學(xué)莊越挺等人在人體動畫方面,提出了一種基于緊身衣和相機定標(biāo)的新的人體動畫技術(shù)。在虛擬人的面部行為方面,中國科學(xué)院的高文等主要研究與意識行為有關(guān)的虛擬人面部圖像合成技術(shù)。2.2虛擬人運動模型人體模型中各肢體之間存在一定的運動連帶關(guān)系,將關(guān)節(jié)看成點,將關(guān)節(jié)之間的骨骼看成是鏈,就可以按照運動關(guān)系將各肢體鏈接起來。本文用樹結(jié)構(gòu)來表達人體模型的層次結(jié)構(gòu),如圖2-1所示。圖SEQ圖\*ARABIC2-1基于關(guān)節(jié)的運動層次結(jié)構(gòu)為了描述人體骨架模型中各關(guān)節(jié)之間的相對位置和姿態(tài)(簡稱位姿),在每個關(guān)節(jié)上固定一個局部坐標(biāo)系,取關(guān)節(jié)軸線方向為x軸正方向,取上一關(guān)節(jié)和該關(guān)節(jié)的連線方向為y軸正方向,這樣就可以用齊次坐標(biāo)變換矩陣來描述這些坐標(biāo)系之間的相對位置和方向。對于某一任務(wù),運動的限定可用下述運動結(jié)構(gòu)方程給出:公式2-1運動結(jié)構(gòu)方程其中,表示從關(guān)節(jié)i的坐標(biāo)系到關(guān)節(jié)i-1的坐標(biāo)系的變換矩陣,是世界坐標(biāo)系到基坐標(biāo)系的變換矩陣,是目標(biāo)坐標(biāo)系到世界坐標(biāo)系的變換矩陣。故人體的運動學(xué)設(shè)計問題可轉(zhuǎn)化為求解關(guān)節(jié)模型的運動方程問題?;谌梭w運動生物力學(xué)和物理學(xué)的基礎(chǔ),可以從人體運動學(xué)和動力學(xué)兩方面對虛擬人運動進行描述。基于運動系學(xué)的模型:人體運動學(xué)是描述人體運動的學(xué)科。它只討論運動本身的細節(jié),而不涉及產(chǎn)生運動的原因(內(nèi)力和外力)。所謂基于運動學(xué)的模型是指物體的運動獨立于產(chǎn)生運動的力,其參數(shù)包括物體的位置,速度和加速度。例如在H-Anim標(biāo)準(zhǔn)中,使用三類節(jié)點(Node)表示一個虛擬人體模型:分別是人體重心(Humanoin)人體關(guān)節(jié)(Joint)和人體骨骼段(Segment)并把整個人分成1個人體重心77個關(guān)節(jié)和47個骨骼段。在基于運動學(xué)的模型中,任何一個人體骨骼段的完整的運動學(xué)參數(shù)共需15個隨時間變化的參量來形容,這些運動學(xué)參數(shù)主要包括人體骨骼段的體心位置,人體骨骼段的體心速度,人體骨骼段的體心加速度,人體骨骼段的角度,人體骨骼段角速度,人體骨骼段角加速度等。因此,人體運動參數(shù)是很復(fù)雜的,為了降低研究的復(fù)雜度,通常我們在對具體運動進行描述時,對其進行合理的簡化,這樣就可以只使用諸多運動參數(shù)的一小部分即可完成對此運動的描述了。目前,很多軟件中關(guān)于虛擬人的運動模型都是基于運動學(xué)的,利用這些軟件實現(xiàn)虛擬人的動畫的過程中,需要用戶交互設(shè)置一些關(guān)鍵參數(shù),并通過插值這些關(guān)鍵參數(shù)來生成和控制物體的運動變化,并且這些參數(shù)的變化只涉及到各時刻各參數(shù)值的大小及其變化速度。通過以上分析,可以發(fā)現(xiàn)在基于運動學(xué)模型的虛擬人的動畫技術(shù)中,只考慮了物體的運動學(xué)特性而沒有考慮物體的動力學(xué)特性,并且代之以由用戶交互確定一些關(guān)鍵參數(shù)來生成其運動,因此,可以說這種基于運動學(xué)模型的動畫技術(shù)生成的運動是虛擬的,它并不能完全反映物體的真實運動,除非用戶給定的關(guān)鍵參數(shù)及所采取的插值模式恰好符合物體的動力學(xué)特性?;趧恿W(xué)的模型:人體動力學(xué)是對產(chǎn)生人體運動的力的研究。例如對于整個身體來說,其主要受到重力,地面反作用力或外力,肌肉力以及關(guān)節(jié)反作用力及骨與骨之間的作用力。所謂基于動力學(xué)的模型則是指物體的運動由它所受的力控制,有關(guān)運動參數(shù)完全由動力學(xué)方程決定。在現(xiàn)實世界中,物體的運動變化是由于其受力均衡狀態(tài)被打破而形成的,因而,物體的運動與它和周圍的環(huán)境的相互作用及外界對它施加的外力有關(guān)。事實上,物體的真實運動決定于其受力情況?;趧恿W(xué)的模型的虛擬人動畫技術(shù)是在建立虛擬人的動畫模型時引入了物理規(guī)律,其目的是提高計算機動畫的逼真性。與基于運動學(xué)的模型恰恰相反,從上述分析我們可以看出,基于動力學(xué)的模型有很多優(yōu)勢,其最主要的優(yōu)勢就是可以按照動畫設(shè)計者的要求而運動。然而,基于動力學(xué)的模型的應(yīng)用也存在很多的局限性。例如動力學(xué)方程的求解問題,通常我們無法得到動力學(xué)方程的封閉解析解,只能采用數(shù)值求解技術(shù),而且盡管目前在數(shù)值計算領(lǐng)域已有眾多的求解微分方程的數(shù)值計算方法,但找到適當(dāng)?shù)那蠼夥椒ú⒉皇且患菀椎氖隆?.3虛擬人運動關(guān)鍵技術(shù)人體具有200個以上的自由度和非常復(fù)雜的運動,如何模擬這種運動一直是虛擬人研究中需要解決的重要課題之一。為了使虛擬人的動畫更加自然,真實,在計算機動畫中,已經(jīng)發(fā)展了很多技術(shù)來實現(xiàn)。其中比較傳統(tǒng)的運動控制方法有參數(shù)化關(guān)鍵幀技術(shù),過程動畫技術(shù),另外比較常用的有基于物理的仿真技術(shù)以及目前在商業(yè)產(chǎn)品中比較流行的運動捕獲技術(shù),運動合成技術(shù)等。(1)參數(shù)關(guān)鍵幀:關(guān)鍵幀方法是控制虛擬人運動細節(jié)的傳統(tǒng)方法。關(guān)鍵幀(keyframe)的概念來源于傳統(tǒng)的卡通動畫片制作。在早期的WaltDiseney的制作室,熟練的動畫師設(shè)計卡通片中的關(guān)鍵畫面,也就是所謂的關(guān)鍵幀,然后由一般的動畫師設(shè)計中間幀。在3D計算機動畫中,中間幀的生成由計算機來完成,插值代替了設(shè)計中間幀的動畫師。所有影響畫面圖像的參數(shù)都可謂關(guān)鍵幀的參數(shù),如位置、旋轉(zhuǎn)角度等。從原理上講,關(guān)鍵幀插值問題可歸結(jié)為參數(shù)插值問題,傳統(tǒng)的插值方法都可應(yīng)用到關(guān)鍵幀方法中,但關(guān)鍵幀插值又與純數(shù)學(xué)的插值不同,有其特殊性。為了很好地解決插值過程中的時間控制問題,Steketee等提出了用雙插值的方法來控制運動參數(shù),其中之一為位置樣條,它是位置對關(guān)鍵幀的函數(shù);另一條為運動樣條,它是關(guān)鍵幀對時間的函數(shù)。關(guān)鍵幀插值系統(tǒng)中要解決的另一個問題是物體朝向的插值問題。物體的朝向一般可由Euler角來表示,因此朝向的插值問題可簡單地轉(zhuǎn)化為3個Euler角的插值問題,但Euler角又有其局限性,因為旋轉(zhuǎn)矩陣是不可交換的,Euler角的旋轉(zhuǎn)一定要按某個特定的次序進行;等量的Euler角變化不一定引起等量的旋轉(zhuǎn)變化,而是導(dǎo)致了旋轉(zhuǎn)的不均勻性;Euler角還有可能導(dǎo)致自由度的喪失。Shoemake[4]為了解決因采用Euler角表示引起的麻煩,最早把四元數(shù)引入到動畫中,并提出了用單位四元數(shù)空間上的Bezier樣條來插值四元數(shù)。Barr,Kim等人對該方法進行了應(yīng)用。關(guān)鍵幀技術(shù)要求設(shè)計者除具有設(shè)計關(guān)鍵幀的技能外,還要特別清楚運動對象關(guān)于時間的行為。在應(yīng)用參數(shù)關(guān)鍵幀技術(shù)產(chǎn)生虛擬人的運動時,應(yīng)注意所插值的參數(shù),否則會產(chǎn)生不恰當(dāng)?shù)倪\動。由于關(guān)鍵幀插值不考慮人體的物理屬性以及參數(shù)之間的相互關(guān)系,因此插值得到的運動不一定是合理的,通常需要設(shè)計者對運動進行仔細的調(diào)整。盡管如此,由于關(guān)鍵幀技術(shù)的使用簡便,因此仍然是最常用的動畫生成方法。在技術(shù)上主要采用了插補算法和逆運動法。(2)過程動畫技術(shù):過程動畫(ProceduralMethods)指的是用一個過程去控制物體的動畫。過程動畫技術(shù)在解決一些特殊類型的運動例如行走跑步等是十分有效的,通過使用這種方法,動畫師只需要明確一小部分的參數(shù)例如速度行走的步長等,通過一個具體的過程就可以計算出每一時刻的姿勢,過程動畫技術(shù)較關(guān)鍵幀技術(shù)的優(yōu)越性主要體現(xiàn)在兩個方面:首先,可以很容易的生成一系列的相似的運動;其次,過程動畫技術(shù)可以應(yīng)用在一些用關(guān)鍵幀動畫實現(xiàn)起來非常復(fù)雜的系統(tǒng)例如粒子系統(tǒng)。過程動畫技術(shù)也可以產(chǎn)生群體運動,例如我們可以應(yīng)用群體行為的算法來獲得一群飛鳥的動畫,當(dāng)然也可以獲得一群人的運動。在迪斯尼的一些動畫片中,大多數(shù)的群體場景都使用了過程動畫技術(shù)。過程動畫技術(shù)的優(yōu)點就是它具有生成交互性行為的潛力。例如在視頻游戲中,可以預(yù)測在每種情況下的游戲者的動作反應(yīng),盡管關(guān)鍵幀技術(shù)也可以根據(jù)游戲者做出不同的反應(yīng),但是游戲者的反應(yīng)是局限在一個反應(yīng)庫中。當(dāng)然,過程動畫技術(shù)也有一定的局限性:首先,利用過程動畫很難定義一般,它只適用于某些特定類型的運動。其次,由于自動的本質(zhì)決定了動畫師不能在動畫中進行很好的細節(jié)上的控制,因此也導(dǎo)致了角色動畫運動缺乏表情或獨特性。(3)基于物理的仿真技術(shù):與關(guān)鍵幀技術(shù)不同,基于物理的仿真技術(shù)是利用動力學(xué),生物力學(xué)等物理定律產(chǎn)生運動的。包括正向和逆向動力學(xué)原理(如圖2-2)。我們通常采用有關(guān)節(jié)的基于動力學(xué)的模型來實現(xiàn)動態(tài)仿真,即構(gòu)建角色的動力學(xué)模型,通過仿真計算它們的運動。這就意味著物體的運動受物理規(guī)律的支配,以便創(chuàng)作自然逼真的動畫?;谖锢淼姆抡婕夹g(shù)優(yōu)越于其它運動控制技術(shù)的優(yōu)點主要表現(xiàn)在:首先,利用基于物理的仿真技術(shù)可以生成用關(guān)鍵幀技術(shù)無法實現(xiàn)的完全符合物理特性的理想的運動?;谖锢淼姆抡婕夹g(shù)在體育訓(xùn)練方面的應(yīng)用最為廣泛;其次,在與用戶的交互方面,基于物理的仿真技術(shù)能實現(xiàn)比關(guān)鍵幀或是運動捕獲技術(shù)更精確的交互。當(dāng)然這種技術(shù)也有其不足之處,龐大的計算量是制約動態(tài)仿真技術(shù)發(fā)展的一個主要因素。通常,為了實現(xiàn)一個很好的仿真,需要使用多處理器且大虛擬內(nèi)存及物理內(nèi)存的計算機才能實現(xiàn)。另外,對于動畫師來說,一方面由于采用基于物理的仿真技術(shù)產(chǎn)生的運動是通過計算機的仿真過程自動合成的,因此可以將動畫師從許多低層次的運動細節(jié)和制作中解放出來;另一方面,由于操縱用動態(tài)仿真技術(shù)產(chǎn)生的虛擬人的運動沒有利用其它技術(shù)產(chǎn)生的虛擬人的運動容易,因此,動態(tài)仿真技術(shù)對虛擬人的行為也有一定的限制。在技術(shù)上分為基于約束的方法和運動合成的方法。圖2-2正向和逆向動力學(xué)原理(4)運動捕獲技術(shù):如圖2-3所示,它是利用傳感器以三維的形式記錄人類主體的動作,然后計算機根據(jù)所記錄的數(shù)據(jù)驅(qū)動屏幕上的虛擬人。這種方法的最大優(yōu)點是能夠捕捉到人類真實運動的數(shù)據(jù),由于生成的運動基本上是主體人運動的復(fù)制品,因而效果非常逼真,且能生成許多復(fù)雜的運動。運動捕獲技術(shù)也是目前在商業(yè)產(chǎn)品中比較常用的一種用來生成運動的技術(shù)。運動捕獲技術(shù)是通過使用稱為跟蹤器的專門的傳感器來記錄運動者的運動信息,然后,我們就可以利用所記錄下來的數(shù)據(jù)來產(chǎn)生動畫運動。作為一種選擇,我們也可以使用一種帶有關(guān)節(jié)傳感器的木偶來代替真人。運動捕獲技術(shù)是目前相當(dāng)流行的一種技術(shù),這主要是因為它可以很容易的獲得許多人體運動的數(shù)據(jù)。然而,也存在很多問題制約著這一技術(shù)成為一種理想的方法來解決所有的應(yīng)用。首先,在運動捕獲技術(shù)中,所獲得的人體運動數(shù)據(jù)由于附著在運動者皮膚或是衣服上的跟蹤器在運動者運動時會產(chǎn)生一定程序的移位,這就造成了所獲得的運動數(shù)據(jù)有一定的冗余,在某些情況下,還會引起虛擬人的運動的一定程度的失真。例如,我們要捕獲一個人將胳膊放在桌子上的動作,由于捕獲數(shù)據(jù)的冗余,可能會導(dǎo)致計算機生成的虛擬人的手臂并沒有放在桌子上而是懸浮于空中或是手臂穿透桌子等嚴(yán)重失真的情況。其次,由于一些用于捕獲運動的技術(shù)本身的局限性導(dǎo)致一些運動不能被捕獲。一類傳感器是磁的,而且金屬會對捕獲的數(shù)據(jù)產(chǎn)生一定的干擾。還有一些傳感器要求被捕獲者連到計算機上,因此限制了被捕獲者的運動。另外一類傳感器是光學(xué)的,這類傳感器在使用時,容易使被捕獲者身體的運動數(shù)據(jù)混淆。盡管運動捕獲技術(shù)中還存在一些不足,但是鑒于運動捕獲技術(shù)可以自動的捕獲人體運動的細節(jié),因此,這項技術(shù)仍然得到了廣泛的應(yīng)用,舉個例子來說明這項技術(shù)優(yōu)越于其它技術(shù)的地方,我們用運動捕獲技術(shù)捕獲幾個不同的人走路姿勢,當(dāng)用計算機處理后,我們可以很容易的分辨出虛擬人的走路姿勢是屬于哪個人的。圖2-3用運動捕獲技術(shù)控制虛擬人的運動(5)運動編輯:從本世紀(jì)90年代開始,運動的存儲和重利用問題引起了普遍的關(guān)注。運動編輯技術(shù)主要解決利用motioncapture等技術(shù)所捕獲的運動的重利用問題。應(yīng)用以上的運動控制技術(shù),可以生成大量逼真的運動片段,如何存儲這些不同的運動片斷并將它們重利用,是目前研究的重點。由于人體運動復(fù)雜性,導(dǎo)致了運動的方式也千變?nèi)f化。在已存儲的運動的基礎(chǔ)上,生成更為復(fù)雜的虛擬人運動,是應(yīng)用運動編輯技術(shù)的目的。2.4小結(jié)本章主要介紹了國內(nèi)和國外對于虛擬人研究技術(shù)的現(xiàn)狀,介紹了虛擬人運動模型的概要內(nèi)容,并對現(xiàn)今虛擬人控制技術(shù)作了一個總的介紹,并對各項技術(shù)的優(yōu)缺點作了分析。第3章DIRECTX技術(shù)3.1概述MICROSOFT公司的DIRECTX包含了編制高級計算機游戲和多媒體應(yīng)用程序的最新技術(shù)和工具,提供了一整套應(yīng)用程序接口API,包括:通過支持訪問平臺現(xiàn)實內(nèi)存中位圖的軟硬件加速技術(shù),可利用硬件的位塊傳輸和緩沖區(qū)翻轉(zhuǎn)功能快速直接存取的DIRECTDRAW,軟硬件聲音混合和錄音再生功能的DIRECTSOUND,使動畫在調(diào)制解調(diào)器和網(wǎng)絡(luò)之間的連接更加簡單方便的DIRECTPLAY,實現(xiàn)一個完全的三維圖形系統(tǒng)的高級保留模式和使程序控制著色管道的低級立即模式DIRECT3D,基于WINDOWS的圖形圖象,游戲輸入的API和驅(qū)動程序,不僅支持目前的鍵盤,鼠標(biāo)和操縱桿,也支持WINDOWS將來的輸入設(shè)備的DIRECTINPUT,提供DIRECTX的安裝過程的DIRECTSETUP等六個組件。利用DIRECTX可以獲得硬件獨立性的優(yōu)點,可以直接訪問硬件,又可以不考慮添加新硬件帶來的識別問題。同時,DIRECTX在硬件而后應(yīng)用之間提供了一致的接口以減少安裝和配置的復(fù)雜性,通過DIRECTX可以容易地獲得硬件的能力。另外,隨著4D加速芯片的發(fā)展,各芯片生產(chǎn)商紛紛宣布DIRECTX的全面支持與優(yōu)化。因此,DIRECTX是WINDOWS環(huán)境下開發(fā)高性能三維應(yīng)用程序的較為理想的工具。DIRECTX結(jié)構(gòu)如圖3-1所示,其硬件抽象層(HAL)緊緊包圍了硬件層,而硬件模擬層(HEL)則給開發(fā)人員提供了一組必要的,相互獨立的接口。有了DIRECTX可對顯卡硬件直接進行操作,利用顯卡的硬件功能來完成對屏幕的采樣并對顯存中的數(shù)據(jù)進行實時處理,這樣可以獲得最小的延遲。圖3-1DIRECTXHAL/HEL結(jié)構(gòu)3.2DIRECTX3D對象及設(shè)備3.2.1DIRECTX對象(D3DObject)1.關(guān)于D3D對象微軟DIRECTX是基于COM的對象和接口的,Direct3D編程的第一步必須建立這個對象。而且程序結(jié)束后,必須最后釋放該對象。2.建立D3D對象在DirectX8.0中,你可以用如下代碼建立一個D3D對象:#include<d3dx8.h>//必須包含的頭文件#include<mmsystem.h>LPDIRECT3D8g_lpD3D=NULL;//D3D對象指針,以后經(jīng)常用到if(NULL==(g_lpD3D=Direct3Dcreate8(D3D_SDK_VERSION)))//D3D_SDK_VERSION確保該對象建立正確的頭文件上,目前只能用該值returnE_FAIL;3.2.2DIRECTX設(shè)備(D3DDEVICE)1.D3D設(shè)備的定義一個D3D設(shè)備接口可以簡單的認為是本機一塊顯卡的抽象,它包含了顯卡所有的硬件參數(shù)及狀態(tài)值,比如說,顯卡顯存的數(shù)量和起始的線性地址,是否支持深度緩沖(DepthBuffer),霧化(Fog),紋理(Texture)及MipMap等。2.D3D設(shè)備的功能在D3D編程中,一個D3D設(shè)備接口主要能完成以下的功能模塊:a.轉(zhuǎn)換功能(Transformation):主要完成對3D模型數(shù)據(jù)的轉(zhuǎn)換,例如,世界轉(zhuǎn)換(Worldtransformation),視轉(zhuǎn)換(Viewtransformation),投影轉(zhuǎn)換(Projectiontransformation)。b.燈光照明功能:完成對場景的燈光渲染,例如,設(shè)置環(huán)境光,方向光等。c.光柵化顯示功能:根據(jù)設(shè)置的一些3D狀態(tài)參數(shù)和當(dāng)前屏幕顯示模式以及剪切等情況,將3D圖形在屏幕上顯示出來。3.D3D設(shè)備的類型在DirectX8.0中,支持三種類型的D3D設(shè)備:硬件抽象層設(shè)備,參比設(shè)備,軟件模擬設(shè)備,每一種設(shè)備可以認為是一種獨立的3D驅(qū)動程序,但也各有用途和優(yōu)勢,分為:a.硬件抽象層設(shè)備(HALDevice):D3D中最主要的設(shè)備類型,基于顯卡的硬件功能,具有很快的3D硬件加速功能,能執(zhí)行硬件或軟件的頂點數(shù)據(jù)處理。缺點是必須有3D顯卡支持,而且,并不是每種顯卡都支持所有的3D功能,所以在使用該設(shè)備時,必須經(jīng)常查詢顯卡支持的功能,對不支持的用軟件設(shè)備來模擬。b.軟件模擬設(shè)備(SoftwareDevice):顧名思義,是用軟件的方法來模擬3D的一些功能。依賴于一些特殊的CPU指令集(比如,AMD3D-Now,IntelMMX指令集),軟件模擬設(shè)備也能獲得較高的3D性能。而且軟件模擬設(shè)備具有硬件抽象層設(shè)備一樣的函數(shù)接口,使用方便。缺點是大量占用CPU資源,運行速度較慢,只適合同硬件抽象層設(shè)備配合使用。c.參比設(shè)備(ReferenceDevice):是微軟Direct3D支持的一種附加設(shè)別類型,它也依賴于特殊的CPU指令集,但同軟件模擬設(shè)備相比,它更注重模擬的精確性,而不是速度方面。所以它一般應(yīng)用于對3D硬件的測試和硬件功能的演示上。4.建立D3D設(shè)備在DirectX8.0中,建立一個D3D設(shè)備需要到用IDirect3D8接口中的CreateDevice函數(shù),該函數(shù)原型如下HRESULTCreateDevice(UINTAdapter,D3DDEVTYPEDeviceType,HWNDhFocusWindow,DWORDBehaviorFlags,D3DPRESENT_PARAMETERS*pPresentationParameters,IDirect3DDevice8**ppReturnedDeviceInterface);//該段代碼建立一個基于Window窗口程序的D3D硬件抽象層設(shè)備,采用軟件的頂點數(shù)據(jù)處理,并使用16Bits的深度緩沖區(qū)。D3DDISPLAYMODEd3ddm;HRESULThr=0;hr=g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm);if(FAILED(hr))returnE_FAIL;D3DPRESENT_PARAMETERSd3dpp;ZeroMemory(&d3dpp,sizeof(d3dpp));d3dpp.Windowed=TRUE;//指明是窗口模式,而非全局獨占模式d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;//無需交換鏈d3dpp.BackBufferFormat=d3ddm.Format;//后備緩沖區(qū)顏色格式d3dpp.EnableAutoDepthStencil=TRUE;//使深度緩沖區(qū)有效d3dpp.AutoDepthStencilFormat=D3DFMT_D16;//深度緩沖區(qū)顏色格式//CreatetheD3DDevicehr=g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,//使用當(dāng)前顯卡作注設(shè)備D3DDEVTYPE_HEL,//設(shè)備類型hWnd,//該程序所在的窗口句柄D3DCREATE_SOFTWARE_VERTEXPROCESSING,//用軟件的方法處理頂點數(shù)據(jù)&d3dpp,//指向上面的結(jié)構(gòu)&g_pd3dDevice)))//指向3D設(shè)備的指針if(FAILED(hr)){returnE_FAIL;}3.3矩陣(Matrices)3.3.13D迪卡爾坐標(biāo)系統(tǒng)和矩陣定義1.3D迪卡爾坐標(biāo)系統(tǒng)2D坐標(biāo)系統(tǒng)只有x軸與y軸,因為它是平面的。而在3D空間里,兩個軸顯然不夠用了,所以,有了第三個軸:z軸。圖3-2演示了左手3D迪卡爾坐標(biāo)系統(tǒng)是如何工作的。圖3-2左手3D笛卡爾坐標(biāo)系統(tǒng)2.矩陣的定義由m×n個數(shù)排成m行n列,并括以方括弧(或圓括弧)的數(shù)稱為m行n列矩陣,簡稱m×n矩陣。簡要概括的講,矩陣就像是一個表格,有一定數(shù)目的行與列;每個格子中都一個數(shù)字或表達式。通過特定的矩陣,我們可以對3D對象中的頂點坐標(biāo)進行運算,來實現(xiàn)類似移動、旋轉(zhuǎn)、縮放這樣的操作。在DirectX中,矩陣就是4X4的數(shù)表。3.3.2矩陣變換要改變一個頂點的x,y與z值,你應(yīng)該把它們與某個矩陣相乘。圖3-3演示了頂點是怎樣與矩陣相乘的。圖3-3頂點通過矩陣變換這其實是一種簡單的計算,只需要將x,y和z值分別與每列上的數(shù)相乘再相加,每列上得出的數(shù)都是新頂點的一個坐標(biāo)值,這在上圖中是顯而易見的。你可能已經(jīng)注意到我們上面的圖例中在當(dāng)前頂點(currentvertex)的z值后面還有一個“1”,那是為了給矩陣的運算提供可行性和方便性的(最好參看一下相關(guān)的數(shù)學(xué)資料)。需要同樣數(shù)表來完成矩陣變換。所以,我們只需操作矩陣就能完成這些類似旋轉(zhuǎn)、縮放或移動的變幻。幸運的是,DirectX給我們提供了一些函數(shù)能方便地生成一些通常的矩陣。那末,如何完成即縮放又旋轉(zhuǎn)(復(fù)合變換)的變幻呢?首先,我們需要兩個矩陣:一個用來旋轉(zhuǎn)的一個用來縮放的;然后,我們把兩個矩陣相乘,得出一個新的復(fù)合矩陣,即縮放又旋轉(zhuǎn)的矩陣;然后利用這個新的矩陣來變幻頂點。應(yīng)該注意的是,矩陣相乘并不是普通的乘法,而且,也不滿足交換率:矩陣AX矩陣B和矩陣BX矩陣A是不相等的。下面的圖3-4演示了怎樣把兩個矩陣相乘:圖3-4矩陣相乘要把兩個矩陣相乘,需要把第一個矩陣的每一行和第二個矩陣的每一列都相乘。在上面的例子中,我們把第一個矩陣的第一行的每個元素與第二個矩陣的第一列的對應(yīng)元素相乘,然后把得出的四個結(jié)果相加,按此方法,我們得出了新矩陣的第一行的四個元素(Column1-4),其它元素的計算方法依此類推。這可能看起來有些復(fù)雜,不過,DirectX提供了一些矩陣操作的函數(shù),所以不要對此擔(dān)心。3.3.3場景變換矩陣1.WorldMatrix(世界矩陣)我們可以利用世界矩陣在3D空間(世界空間)里通過修改對象的坐標(biāo)來完成它們的旋轉(zhuǎn)、縮放或平移操作。所有這些操作(變換)都是關(guān)于原點(0,0,0)的。單一的變幻(例如平移或縮放等)可以組合起來,形成更復(fù)雜的變幻;但要注意各種變幻的順序很重要,矩陣1X矩陣2和矩陣2X矩陣1是不同的。還有,當(dāng)你完成了一項世界變幻的矩陣操作時,矩陣跟著將轉(zhuǎn)變所有的頂點。要旋轉(zhuǎn)兩個對象,一個關(guān)于x軸,一個關(guān)于y軸,你應(yīng)該先完成x軸的變幻,然后渲染第一個對象;再完成y軸的變幻,然后渲染第二個對象。世界矩陣有時候需要自己填寫,根據(jù)各種變換需要來填寫一個D3DXMATRIX結(jié)構(gòu)體。之后通過調(diào)用IDirect3DDevice9::SetTransform(D3DTRANSFORMSTATETYPEState,CONSTD3DMATRIX*pMatrix)設(shè)置世界矩陣為填好的那個。其中參數(shù)意義如下:D3DTRANSFORMSTATETYPEState代表你要設(shè)置的變換類型。D3DTS_WORLD,D3DTS_VIEW,D3DTS_PROJECTION分別表示世界,視圖,投影三種變換。CONSTD3DMATRIX*pMatrix指向一個矩陣結(jié)構(gòu)的指針,即所要用到的矩陣。后面的兩個矩陣也要通過此函數(shù)設(shè)置。D3D中,三個矩陣是要存放在固定位置的,D3D依次從這三個位置讀取矩陣信息,并乘以所有的點,得到新的點的坐標(biāo),這個過程是不用我們操心的。我們調(diào)用SetTransform()就是要把填充好的矩陣放進這三個位置中的某一個,第一個參數(shù)表示了哪一個。2.ViewMatrix(視圖矩陣)視圖矩陣就是攝像機(或眼睛)。攝像機在世界空間中有一個位置,還有一個觀察點。例如,你可以把攝像機懸置于某個對象的上面(攝像機位置),把鏡頭對準(zhǔn)那個對象的中心(觀察點)。你也可以指定哪面是上面,在我們下面的例子中,我們指定了y軸的正方向是上面。在設(shè)置視圖矩陣時,先要很清楚地建立好“視圖坐標(biāo)系”。這個坐標(biāo)系以觀察著為原點,沿著視線方向(觀察者—注視點方向)為縱深方向(也就是Z軸方向)。僅有兩個點還不足以確定一個三維坐標(biāo)系,我們還需要一個參考點,能與另兩個點構(gòu)成某一個坐標(biāo)平面。這樣的坐標(biāo)系構(gòu)件起來后,就可以根據(jù)兩個坐標(biāo)系的變換填充視矩陣了。D3D提供了函數(shù):D3DXMATRIX*D3DXMatrixLookAtLH(D3DXMATRIX*pOut,CONSTD3DXVECTOR3*pEye,CONSTD3DXVECTOR3*pAt,CONSTD3DXVECTOR3*pUp);或D3DXMATRIX*D3DXMatrixLookAtLH(參數(shù)同),區(qū)別僅在于前者用于左手系而后者用于右手系。該函數(shù)自動填充一個矩陣,參數(shù)依次是將要填充的矩陣以及上面說到的三個點,這里三個點構(gòu)成視坐標(biāo)系的YOZ平面。然后再調(diào)用SetTransform()把這個矩陣交給D3D。經(jīng)過上一步被統(tǒng)一了坐標(biāo)的各個頂點將被這個矩陣轉(zhuǎn)到視圖坐標(biāo)中。3.ProjectionMatrix(投影矩陣)投影矩陣可以被想象成攝像機的鏡頭,它指定了視界(fieldofview)和前、后裁剪平面。這個矩陣將越近的點放得越大。填充這個矩陣我們用函數(shù):D3DXMATRIX*D3DXMatrixPerspectiveFovLH(D3DXMATRIX*pOut,FLOATfovY,FLOATAspect,FLOATzn,FLOATzf);或D3DXMATRIX*D3DXMatrixPerspectiveFovLH(參數(shù)相同),區(qū)別同上面一樣。第一個參數(shù)仍然是輸出矩陣。第二個描述了在Y軸上的視角,弧度制表示,可以想象,視角越大,近端被拽拉的比例就越大。下一個參數(shù)是視圖區(qū)的長寬比。后面兩個參數(shù)就是最近視平面和最遠視平面的位置,用它們的Z坐標(biāo)(Z坐標(biāo)的值在投影變換前后是不變的)表示。3.4在DIRECTX3D中使用網(wǎng)格模型復(fù)雜的幾何模型通常是由3D建模軟體創(chuàng)建并保存到文件中。例如.x文件就是這樣的一種格式,MicrosoftDirect3D使用的網(wǎng)格模型都是載入這些文件中的對象。即使模型有些復(fù)雜,但在MicrosoftDirect3D中包含的函數(shù)建立使用它是非常容易,在這里介紹一下網(wǎng)格模型如何載入渲染,得到我們所需的效果,并且如何對其進行釋放。這里將分為載入,渲染和釋放三個步驟。3.4.1載入一個網(wǎng)格模型對象一個MicrosoftDirect3D的應(yīng)用程式在使用網(wǎng)格模型對象之前必須進行初始化,在這里調(diào)用InitGeometry函數(shù)用于載入一個網(wǎng)格模型,這是一個應(yīng)用程式定義的函數(shù),在載入必要的Direct3D對象(系統(tǒng)初始化)后調(diào)用。一個網(wǎng)格模型需要材質(zhì)緩沖,將存儲要使用的材質(zhì)以及紋理。函數(shù)在開始先聲明一個材質(zhì)緩沖如同以下的代碼片段:LPD3DXBUFFERpD3DXMtrlBuffer;下面這部分使用D3DXLoadMeshFromX的方法來載入網(wǎng)格模型://從指定文件中導(dǎo)入.X文件if(FAILED(D3DXLoadMeshFromX("tiger.x",D3DXMESH_SYSTEMMEM,g_pd3dDevice,NULL,&pD3DXMtrlBuffer,&g_dwNumMaterials,&g_pMesh)))returnE_FAIL;第一個參數(shù)D3DXLoadMeshFromX從一個指向字符串的指針獲得需要MicrosoftDirectX載入的文件名。第二個參數(shù)告訴Direct3D如何創(chuàng)建網(wǎng)格模型。這里使用了D3DXMESH_SYSTEMMEM標(biāo)記,相當(dāng)于指定了D3DXMESH_VB_SYSTEMMEM和D3DXMESH_IB_SYSTEMMEM這兩個。這兩個標(biāo)記告訴Direct3D將網(wǎng)格模型的索引緩沖(indexbuffer)和頂點緩沖(vertexbuffer)存放于系統(tǒng)存儲器。第三個參數(shù)是一個指針,指向Direct3D設(shè)備,這也是將用于模型渲染。第四個參數(shù)是指向一個ID3DXBuffer對象的指針,這個對象將填滿關(guān)于相鄰每一個面的信息。這里設(shè)置為NULL。第五個參數(shù)也同樣指向一個ID3DXBuffer對象,在這個函數(shù)完成之后,這個對象將填滿模型的D3DXMATERIAL結(jié)構(gòu)數(shù)據(jù)。第六個參數(shù)指向一個整形變量,當(dāng)函式返回時保存D3DXMATERIAL結(jié)構(gòu)的數(shù)量于ppMaterials列隊中。第七個參數(shù)返回一個指向網(wǎng)格模型對象的地址,返回所載入的模型數(shù)據(jù)。在載入模型對象和材質(zhì)信息后,需要從材質(zhì)緩沖中篩選出材質(zhì)屬性和紋理名稱。首先,取得指向材質(zhì)緩沖,下面的代碼展示了如何取得指針數(shù)據(jù):D3DXMATERIAL*d3dxMaterials=(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();下面的代碼創(chuàng)建新的模型和根據(jù)材質(zhì)中模型所統(tǒng)計的紋理對象:g_pMeshMaterials=newD3DMATERIAL8[g_dwNumMaterials];g_pMeshTextures=newLPDIRECT3DTEXTURE8[g_dwNumMaterials];為模型中每一個材質(zhì)執(zhí)行下面的步驟:第一步,拷貝材質(zhì),代碼如下:g_pMeshMaterials[i]=d3dxMaterials[i].MatD3D;第二步,為材質(zhì)設(shè)置環(huán)境顏色,代碼如下:g_pMeshMaterials[i].Ambient=g_pMeshMaterials[i].Diffuse;最后一步,為材質(zhì)創(chuàng)建紋理貼圖,代碼如下://創(chuàng)建紋理if(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,d3dxMaterials[i].pTextureFilename,&g_pMeshTextures[i])))g_pMeshTextures[i]=NULL;}在載入每一個材質(zhì)之后,完成材質(zhì)緩沖并需要釋放它的調(diào)用Release()。pD3DXMtrlBuffer->Release();3.4.2渲染一個網(wǎng)格模型對象在第一步里,模型已經(jīng)載入并準(zhǔn)備好用于渲染,模型載入后,它是以每一個材質(zhì)分開存放在一個子集中,需要對每個子集進行渲染,模型是在一個循環(huán)中渲染。第一步,在循環(huán)里為子集設(shè)置材質(zhì),參看下面代碼片段:g_pd3dDevice->SetMaterial(&g_pMeshMaterials[i]);第二步,在循環(huán)里為子集設(shè)置紋理,參看下面代碼片段:g_pd3dDevice->SetTexture(0,g_pMeshTextures[i]);在設(shè)置好材質(zhì)和紋理后,子集通過調(diào)用ID3DXBaseMesh::DrawSubset函數(shù)的方法來繪制,參看下面代碼片段:g_pMesh->DrawSubset(i);DrawSubset函數(shù)方法通過一個DWORD參數(shù)指定哪個子集用于模型繪制,本例中使用一個增加的變量在每一個時間里循環(huán)執(zhí)行。使用模型之后,完全釋放模型所使用的內(nèi)存是很重要的,這是第三步要做的事情。3.4.3釋放一個網(wǎng)格模型對象在所有MicrosoftDirectX程式完成后,需要查找所有的DirectX對象指針是在使用中還是無效,在本例中模型對象同樣也需要如此,當(dāng)程式接收到WM_DESTROY消息,這里調(diào)用Cleanup函式,這是一個應(yīng)用程式定義的函數(shù)。下面的代碼用來釋放材質(zhì)列表:if(g_pMeshMaterials)delete[]g_pMeshMaterials;下面的代碼分別將每一個紋理進行釋放并刪除紋理列表:if(g_pMeshTextures){for(DWORDi=0;i<g_dwNumMaterials;i++){if(g_pMeshTextures[i])g_pMeshTextures[i]->Release();}delete[]g_pMeshTextures;}下面的代碼片段檢測并釋放模型對象://刪除網(wǎng)格對象if(g_pMesh)g_pMesh->Release();3.5DIRECTINPUT由于涉及到對虛擬人的控制問題,這里還需要介紹一下DIRECTINPUT技術(shù)中的鍵盤編程問題。首先,必須創(chuàng)建一個DirectInput8對象,就像這樣:LPDIRECTINPUT8pInput;DirectInput8Create(GetModuleHandle(NULL),DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&pInput,NULL);然后,需要創(chuàng)建一個DirectInput設(shè)備:LPDIRECTINPUTDEVICE8pDev; pInput->CreateDevice(GUID_SysKeyboard,&pDev,NULL);設(shè)置好它的數(shù)據(jù)格式:pDev->SetDataFormat(&c_dfDIKeyboard);設(shè)置它的協(xié)作級,這里設(shè)為獨占設(shè)備+前臺:pDev->SetCooperativeLevel(hwnd,DISCL_EXCLUSIVE|DISCL_FOREGROUND);獲取設(shè)備:pDev->Acquire();像上面那樣初始化后,Windows對鍵盤的控制權(quán)就被剝奪了,以后的鍵盤消息將不會被送入消息循環(huán),我們可以把消息循環(huán)中處理鍵盤消息的語句拿掉了。當(dāng)然,這時我們需要在程序的適當(dāng)?shù)胤剑热缯f在刷新游戲時,加入對鍵盤數(shù)據(jù)進行讀取和處理的語句,就像下面的一段程序:#defineKEYDOWN(key)(buffer[key]&0x80)//定義一個宏,方便處理鍵盤數(shù)據(jù)charbuffer[256];//鍵盤數(shù)據(jù)pDev->GetDeviceState(sizeof(buffer),(LPVOID)&buffer);//得到鍵盤數(shù)據(jù)if(KEYDOWN(DIK_XXX))//如果XXX鍵被按下…(請參閱附錄二){ ……//處理之} ……//處理其它鍵3.6小結(jié)在這一章里主要通過代碼的形式介紹了一些DIRECTX常用的技術(shù)和方法,包括3D空間的坐標(biāo)問題,矩陣的變換,.X模型的導(dǎo)入和基本的DIRECTINPUT控制技術(shù),在最后講述了一些DIRECTINPUT的鍵盤編程方法,這些為以后的程序作一個基礎(chǔ)。第4章用DIRECTX設(shè)計實現(xiàn)虛擬人運動控制4.1虛擬人造型4.1.1用3DMAX建模3DSMAX是Autodesk公司開發(fā)的高性能三維動畫制作軟件,具有強大的三維圖形造型能力和動畫制作能力。3DSMAX有20種基本的3D對象,包括標(biāo)準(zhǔn)幾何體(standardprimitives)和擴展幾何體(extendedprimitives),另外還可以利用2D圖形創(chuàng)造復(fù)雜的3D模型,并且可以對這些3D模型進行各種變形(如連接、分散、布爾運算等)以組合成更為復(fù)雜的三維圖形。3DSMAX可以指定物體的運動路徑,變形方式實現(xiàn)動畫效果,但其生成的動畫只能按預(yù)先設(shè)定好的方式變化,在此過程中無法干預(yù),即不能實現(xiàn)實時控制。所用的虛擬人通過3DSMAX建模,生成.3ds文件,如圖4-1所示:圖4-1虛擬人建模4.1.2虛擬人數(shù)據(jù)導(dǎo)出通過3DSMAX建模之后,需要解決的是模型導(dǎo)出問題,可以通過conv3ds軟件來將.3ds文件轉(zhuǎn)化為.x文件,這里通過命令行的方式來運行conv3ds,轉(zhuǎn)換如圖4-2:圖4-2.3ds文件轉(zhuǎn)換為.x文件4.1.3虛擬人數(shù)據(jù)結(jié)構(gòu)1.X文件簡介在D3D中,X文件主要是用來存儲網(wǎng)格數(shù)據(jù)的,當(dāng)然不光是網(wǎng)格數(shù)據(jù),它還用來存儲有關(guān)紋理,動畫及用戶定義的對象的一些數(shù)據(jù)X文件是模板驅(qū)動(Template-Driven)[5]的,也就是說它存儲數(shù)據(jù)的格式是基于模板的.這使得這種文件格式具有結(jié)構(gòu)自由,內(nèi)容豐富,易應(yīng)用,可移植性高等優(yōu)點。2.X文件中的模板(Template)模板定義了數(shù)據(jù)流是怎樣被格式化的,也就是告訴你對于一個3D模型的各種數(shù)據(jù),它們是以什么格式存放在數(shù)據(jù)流中的(這里指文件)。a.模板的格式在X文件中,一般會有如下所示的格式:template<template-name>{//模板名<UUID>//一個全局唯一ID,用來唯一標(biāo)識該模板<member1>;//成員變量1...<membern>;//成員變量n[restrictions]//模板約束,下面會提到}b.模板約束根據(jù)模板約束的不同形式,可將模板分成以下三類:(a).開放式模板(OpenTamplate)開放式模板指除了模板本身定義的成員變量外,還可以向模板中添加其他的成員變量,來達到定制模板的目的。下面是一個開放式模板實例:templateMesh{<3D82AB44-62DA-11cf-AB39-0020AF71E433>DWORDnVertices;arrayVectorvertices[nVertices];DWORDnFaces;arrayMeshFacefaces[nFaces];[...]//該字符串表明該模板為開放式模板}(b).約束模板(RestrictedTamplate)與開放式模板相比,只能向約束模板中添加有限幾種類型的數(shù)據(jù)成員,這些數(shù)據(jù)類型由模板枚舉出來,下面是一個開約束模板實例:templateFileSystem{<UUID>STRINGname;[Directory<UUID>,File<UUID>]//表明為約束模板}(c).封閉式模板(ClosedTamplate)與上面兩種類型的模板相比,封閉式模板的數(shù)據(jù)成員是固定的,不能向里面添加另外的成員。下面是一個封閉式模板實例:templateVector{<3D82AB5E-62DA-11cf-AB39-0020AF71E433>FLOATx;FLOATy;FLOATz;}//封閉式模板c.模板類型//標(biāo)題模板,給出一些附加的X文件信息,如版本信息。templateHeader{//標(biāo)題模板,給出一些附加的X文件信息,如版本信息。<3D82AB43-62DA-11cf-AB39-0020AF71E433>WORDmajor;//大版本號WORDminor;//小版本號DWORDflags;}//向量模板,定義一個向量(x,y,z)templateVector{<3D82AB5E-62DA-11cf-AB39-0020AF71E433>FLOATx;FLOATy;FLOATz;}//顏色模板,定義一帶alpha的顏色值templateColorRGBA{<35FF44E0-6C7C-11cf-8F52-0040333594AFLOATred;FLOATgreen;FLOATblue;FLOATalpha;}//顏色模板,定義一不帶alpha的顏色值templateColorRGB{<D3E16E81-7835-11cf-8F52-0040333594A3>FLOATred;FLOATgreen;FLOATblue;}//材質(zhì)模板,定義材質(zhì)屬性templateMaterial{<3D82AB4D-62DA-11cf-AB39-0020AF71E433>ColorRGBAfaceColor;//材質(zhì)顏色FLOATpower;//高亮光強度ColorRGBspecularColor;//高亮光顏色ColorRGBemissiveColor;//發(fā)散光顏色[...]//可添加其他成員}//網(wǎng)格面模板,定義網(wǎng)格中的一個面(即圖元,還記得網(wǎng)格的概念嗎)templateMeshFace{<3D82AB5F-62DA-11cf-AB39-0020AF71E433>DWORDnFaceVertexIndices;//該面包含的定點數(shù)arrayDWORDfaceVertexIndices[nFaceVertexIndices];//面的頂點數(shù)據(jù)索引列表}//網(wǎng)格模板,定義網(wǎng)格數(shù)據(jù)格式templateMesh{<3D82AB44-62DA-11cf-AB39-0020AF71E433>DWORDnVertices;//網(wǎng)格頂點數(shù)arrayVectorvertices[nVertices];//網(wǎng)格頂點數(shù)據(jù)列表DWORDnFaces;//網(wǎng)格面數(shù)arrayMeshFacefaces[nFaces];//網(wǎng)格面的數(shù)據(jù)列表[...]//可添加其他成員}3.X文件格式D3D的X文件擁有自己的一套完整的語法規(guī)則,以下是一個完整X文件,它存儲了一個正方形網(wǎng)格的數(shù)據(jù)。該正方形有兩個面,一面為紅色,一面為藍色。1xof0302txt0064234567Header8{91;100;111;12}1314MaterialFace1Material//Material115{161.0;0.0;0.0;1.0;;//紅色170.0;180.0;0.0;0.0;0.0;;190.0;0.0;0.0;0.0;;2021}2223MaterialFace2Material//Material224{250.0;0.0;1.0;1.0;;//藍色260.0;270.0;0.0;0.0;0.0;;280.0;0.0;0.0;0.0;;2930}3132MeshFace33{344;//該網(wǎng)格包含四個頂點35-1.0;-1.0;0.0;,//頂點0坐標(biāo)36-1.0;1.0;0.0;,//頂點1坐標(biāo)371.0;1.0;0.0;,//頂點2坐標(biāo)381.0;-1.0;0.0;;//頂點3坐標(biāo)39402;//該網(wǎng)格包含兩個面414;0,1,2,3;,//網(wǎng)格正面,4表示該面有四個頂點,后面是頂點數(shù)據(jù)的索引424;3,2,1,0;;//網(wǎng)格反面4344MeshMaterialList//材質(zhì)列表,為每個面分配一個材質(zhì)45{462;472;480,1;;49{Face1Material}50{Face2Material}51}5253}a.第1行,x文件的標(biāo)題xof表明該文件類型是X文件0302表明該文件大版本號為03,小版本號為02,該版本號一般不會變txt表明該文件為文本文件,同樣"bin"為二進制文件,"tzip"為壓縮文本文件,"bzip"為壓縮二進制文件。0064表明使用64位的浮點數(shù)。同樣,0032表示使用32位的浮點數(shù)。注意:該標(biāo)題字符串必須放在X文件的第一行。b.第3-4行,注釋在X文件中,符號"http://"或"#"用來表示注釋。c.第7-12行,該文件的標(biāo)題模板數(shù)據(jù)該模板數(shù)據(jù)同最前的標(biāo)題字符串相對應(yīng),用來說明該文件的一些信息。d.第14-30行,定義了兩個材質(zhì),分別具有紅色和藍色屬性。在模板的數(shù)據(jù)中,要注意逗號和分號的使用。這方面的內(nèi)容可查SDK的文檔。e.第32-53行,給出了該網(wǎng)格的模板數(shù)據(jù),可參見注釋。4.2使用DIRECTX實現(xiàn)虛擬運動控制4.2.1關(guān)鍵幀的設(shè)計關(guān)鍵幀法是對人體模型的關(guān)節(jié)參數(shù)進行插值計算,考慮到運動控制的實時需要,這里主要用前一幀和后一幀直線連接的方法。對于參數(shù)插值來說,運動主體的狀態(tài)變量是一組“參數(shù)”,其運動的規(guī)律也是由插值計算得到的,即運動是由關(guān)鍵幀來說明的。每一個關(guān)鍵幀都有一系列的控制點對應(yīng)于其它關(guān)鍵幀的控制點。本系統(tǒng)中插值法的應(yīng)用主要是對運動鏈上各關(guān)節(jié)的初始位姿與利用逆運動學(xué)所得的關(guān)節(jié)的旋轉(zhuǎn)角進行插補,形成中間畫面。例如:對人體胳膊的動作可用它在某個時刻上的角度a來描述。如起始是a=10度;1秒鐘后,a=20度;5秒鐘后,a=45度;8秒鐘后,a=100度。對角度參數(shù)a進行線性插值計算每隔1/30秒的a角。當(dāng)t=1/30,a=10+(20-10)/2*1/30=10.1666。關(guān)鍵幀設(shè)計如圖4-3:圖4-3虛擬人24幅關(guān)鍵幀4.2.2平移實現(xiàn)行走在這里介紹一下計算機圖形學(xué)的平移公式,設(shè)Tx,Ty,Tz是物體在三個坐標(biāo)方向上的移動量,則有公式:x′=x+Txy′=y(tǒng)+Tyz′=z+Tz公式4-1平移公式矩陣運算表達為:[x′y′z′1]=[xyz1]與此相對應(yīng),DIRECT3D提供了D3DXMatrixTranslation函數(shù)來實現(xiàn)坐標(biāo)的平移變換,函數(shù)原型下:D3DXMATRIX*D3DXMatrixTranslation(D3DXMATRIX*pOut,FLOATx,FLOATy,FLOATz,);其中參數(shù)一是平移操作矩陣的指針,剩下的三個參數(shù)分別是相對當(dāng)前坐標(biāo)x,y,z的偏移量。通過對虛擬人物體各個頂點的變換,就可以生成類似行走的效果。4.2.3旋轉(zhuǎn)實現(xiàn)轉(zhuǎn)彎旋轉(zhuǎn)分為三種基本旋轉(zhuǎn):繞z軸旋轉(zhuǎn),繞x軸旋轉(zhuǎn),繞y軸旋轉(zhuǎn)。在下述旋轉(zhuǎn)變換公式中,設(shè)旋轉(zhuǎn)的參考點在所繞的軸上,繞軸轉(zhuǎn)θ角,方向是從軸所指處往原點看的逆時針方向。1.繞z軸旋轉(zhuǎn)的公式為:x′=xcosθ-ysinθy′=xsinθ+ycosθz′=z公式4-2繞Z軸旋轉(zhuǎn)公式矩陣運算的表達為:[x′y′z1]=[xyz1]在DIRECT3D中,使用D3DXMatrixRotationZ進行Z軸的旋轉(zhuǎn),原型如下:D3DXMATRIX*D3DXMatrixRotationZ(D3DXMATRIX*pOut,floatangle);其中參數(shù)一是旋轉(zhuǎn)矩陣的指針,下一個參數(shù)為繞Z軸旋轉(zhuǎn)角度。2.繞X軸旋轉(zhuǎn)的公式為:x′=xy′=y(tǒng)cosθ-zsinθz′=y(tǒng)sinθ+zcosθ公式4-3繞X軸旋轉(zhuǎn)公式矩陣運算的表達為:[x′y′z′1]=[xyz1]與繞Z軸相似,在DIRECT3D中用D3DXMatrixRotationX進行X軸的旋轉(zhuǎn)。原型如下:D3DXMATRIX*D3DXMatrixRotationX(D3DXMATRIX*pOut,floatangle);參數(shù)一與上相同,參數(shù)二為繞X軸的旋轉(zhuǎn)角度。3.繞y軸旋轉(zhuǎn)的公式為:x′=zsinθ+xcosθy′=y(tǒng)z′=zcosθ-xsinθ公式4-4繞Y軸旋轉(zhuǎn)公式矩陣的運算表達式為:[x′y′z′1]=[xyz1]D3D中使用D3DXMatrixRotationY進行繞Y軸的旋轉(zhuǎn)。原型如下:D3DXMATRIX*D3DXMatrixRotationY(D3DXMATRIX*pOut,floatangle);參數(shù)二為繞Y軸的旋轉(zhuǎn)角度,參數(shù)一與上相同?;谶@幾種基本的旋轉(zhuǎn)變換,通過矩陣的相乘,可以實現(xiàn)更為復(fù)雜的旋轉(zhuǎn)。對于虛擬人來說,即是通過對人本身坐標(biāo)軸的旋轉(zhuǎn)來達到使虛擬人轉(zhuǎn)彎的目的。在D3D中,也提供了矩陣相乘的方法D3DXMATRIX*D3DXMatrixMultiply(D3DXMATRIX*pOut,CONSTD3DXMATRIX*pM1,CONSTD3DXMATRIX*pM2);其中參數(shù)一是最終輸出矩陣的指針,參數(shù)二,三為相乘矩陣,這里要注意的是矩陣相乘要注意順序。4.2.4程序的構(gòu)造和流程為了讀取數(shù)據(jù),需要使用X文件庫。IDirectXFile是庫的主要接口。IDirectXFile有一個方法為創(chuàng)建IDirectXFileEnumObject。IDirectXFileEnumObject方法是被用于從一個指定的X文件里檢索數(shù)據(jù)。IDirectXFileEnumObject::GetNextDataObject將循環(huán)通過在X文件里所有的頂層模版并且返回一個IDirectXFileData接口。稍后在X文件內(nèi)部被用于檢索單個模版的數(shù)據(jù)。相似于IDirectXFileEnumObject::GetNextDataObject,方法IDirectXFileData::GetNextObject循環(huán)通過所有的子類模版并且返回一個IDirectXFileData接口。方法IDirectXFileData::GetData被用于從模版里檢索數(shù)據(jù),但在我們能檢索數(shù)據(jù)以前,我們需要知道模版的類型。方法IDirectXFileData::GetID返回模版的GUID。例如,如果模版是一個框架模版,GetID將返回TID_D3DRMFrame,它被預(yù)先定義在DX的頭文件里。假如你需要模版的實例的名字(象是用框架的情況一樣),方法GetName把名字將給你。在讀取X文件模版期間,需要尋找一個模版,并且它的GUID等于TID_D3DRMMesh,這就意味著它包含一個mesh。函數(shù)D3DXLoadSkinMeshFromXof將讀取skinmesh與所有的余下的數(shù)據(jù)。僅給它一個指向IDirectXFileData接口的指針并且它將做余下的工作。函數(shù)D3DXLoadSkinMeshFromXof將返回一個指向ID3DXSkinMesh對象的指針。這個對象包含skinmesh。在內(nèi)部,這個對象包含mesh數(shù)據(jù)作為組(group)。每個組(group)被一個不同骨架的設(shè)置變換。函數(shù)將也返回一個材質(zhì)數(shù)據(jù)由skinmesh使用。D3DXLoadSkinMeshFromXof返回一個緩沖區(qū)包含影響mesh的所有骨架的名字。它也給予其它緩沖區(qū)包含它們的變換。這里將使用名字為指定的骨架查遍我們的框架分層結(jié)構(gòu)。骨架變換有點讓人混亂。假定變換不在這里被包含在框架里。事實上,這個變換是骨架偏移(boneoffset)。那么骨架偏移又是什么呢?重要的知道skinmesh的所有頂點是被存儲在相對于一個原點,它是mesh的原點并不是骨架的局部原點。這意味著在mesh上為了有骨架的影響,我們應(yīng)該使mesh變形由位于骨架的當(dāng)前變換與骨架的原點變換之間的差別。或者換句話說,我們應(yīng)該變換頂點到骨架的局部空間,然后變換它們回到mesh的空間使用新的骨架的變換。舉個例子,有一個骨架被放置在(0,50,0)與一個頂點被放置在(0,51,0)并且讓我們假定這個頂點是只由一個骨架影響。如果移動骨架從它的原始位置到這個新的位置(0,51,0),頂點應(yīng)該被移動到位置(0,52,0),但如果簡單的由骨架的變換乘頂點,頂點將有新的位置等于(0,102,0)它是錯誤的坐標(biāo)。因此,使用骨架的偏移矩陣到變換頂點從它的原始位置到一個相對于骨架的位置。新的位置將是(0,1,0)它將是被骨架的當(dāng)前矩陣到新的位置變換,它是(0,52,0)。簡單步驟如下:當(dāng)你使用一個骨架,由偏移矩陣乘以它的當(dāng)前變換矩陣并且使用結(jié)果作為世界矩陣?;氐絀D3DXSkinMesh對象。這個對象在它的原型里包含skinmesh。這個對象為渲染skinmesh沒有任何機能。因此,需要首先轉(zhuǎn)換mesh進入一個ID3DXMesh對象。函數(shù)ConvertToBlendedMesh將做這工作。雖然它是相同的對象被用于渲染靜態(tài)mesh,ID3DXMesh獲得從ConvertToBlendedMesh里有區(qū)別它的頂點包含混合權(quán),因此所需要做的是啟用頂點混合并且在調(diào)用ID3DXMesh的DrawSubset方法以前設(shè)置我們的骨架矩陣。象前面提到的一樣,mesh將被分裂進入組或子對象。每個子對象應(yīng)該與一個指定的材質(zhì)和一個指定的骨架設(shè)置一起被渲染。結(jié)構(gòu)D3DXBONECOMBINATION指定材質(zhì)和骨架被用于一個mesh的單個子對象。結(jié)構(gòu)的數(shù)組也從ConvertToBlendedMesh函數(shù)里獲得。然后要做的是循環(huán)通過這個數(shù)組,設(shè)置材質(zhì)與骨架然后調(diào)用ID3DXMesh的DrawSubset方法給予它在數(shù)據(jù)里的下標(biāo)。動畫在X文件里不是為skinmesh特定使用的;它們能被應(yīng)用于在X文件里的任何框架。X文件存儲關(guān)鍵幀框架并且應(yīng)用程序應(yīng)該產(chǎn)生在框架使用線性插值中間。動畫關(guān)鍵幀有四種類型,旋轉(zhuǎn),縮放,位置,和矩陣關(guān)鍵幀。旋轉(zhuǎn)是被存儲作為四元法(quaternions)并且能被球狀線性插值(sphericallinearinterpolation)進行插值運算。函數(shù)D3DXQuaternionSlerp由D3DX提供實現(xiàn)球狀線性插值。為了在skinmesh里實現(xiàn)動畫,我們需要添加一個新的類。我們把這個類命名為CAnimationNode。這個類將包含動畫關(guān)鍵幀和一個指向目標(biāo)框架的指針一起。這個類也包含一個用從動畫關(guān)鍵幀里在新的時間值上獲得的矩陣來更新目標(biāo)框架的變換矩陣的SetTime函數(shù)。CAnimationNode的每個實例將包含動畫模版的單個實例的數(shù)據(jù)。程序流程圖如下所示:CobjectAttachChild()DetachChild()GetNextSibling()CmeshNodeGenerateBlendedMesh()FindBones()Render()CframeNodeLoad()Update()FindBones()Render()MeshesCanimationNodeLoad()SetTime()FindBone()pTargetFrameCskinMeshCreate()FindBones()Render()RootFrameAnimation大略代碼如下:CSkinMesh::Create()BeginInitializeXfileAPIRegisterD3DRMtemplatesOpentheXfileForeverytopleveltemplateintheXfileBeginRetrievetheXfiledataobjectPassthedataobjecttoRootFrame.LoadEndLinkthebonestotheskinmesh(es)LinkthebonestotheanimationsEndCFrameNode::Load()BeginCheckthetypeofthedataobjectIfthetypeisMeshBeginCreatenewCMeshNodeobjectAttachthenewobjecttothe

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論