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

下載本文檔

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

文檔簡(jiǎn)介

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

最新文檔

評(píng)論

0/150

提交評(píng)論