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