第九章 碰撞檢測_第1頁
第九章 碰撞檢測_第2頁
第九章 碰撞檢測_第3頁
第九章 碰撞檢測_第4頁
第九章 碰撞檢測_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、 OpenGL高級編程高級編程 & 可視化系統(tǒng)開發(fā)可視化系統(tǒng)開發(fā)廣東工業(yè)大學圖學與數(shù)字媒體系 羅立宏第九章第九章 碰撞檢測碰撞檢測9.1碰撞檢測概述碰撞檢測概述碰撞檢測是使系統(tǒng)更自然逼真的必須內(nèi)容。碰撞檢測的一般技術 (1)矩形包圍盒或球形包圍盒 (2)多邊形集合 (3)物體的運動軌跡跟蹤9.3 編程實例二編程實例二9.3.1 程序說明本例通過計算空間點與平面之間的距離來進行碰撞檢測7.1.2 詳細設計詳細設計1 關鍵技術關鍵技術碰撞算法一 當 |D1|g_fSphere_radius 時,認為碰撞發(fā)生D1(i=1)D1(i=2)Z碰撞算法二 當 D0與D1異號時,可認為碰撞發(fā)生D1(i=1)

2、D1(i=2)ZvD0(i=1)D0(i=2)Zv2 詳細設計詳細設計(1) 畫圖設置好繪圖坐標系設置好繪圖坐標系刷新屏幕刷新屏幕繪制兩彈性平面及連線繪制兩彈性平面及連線跟據(jù)球的位置繪制球跟據(jù)球的位置繪制球處理OnDraw( )處理RenderScene ( )CollisionCheck()碰撞檢測,狀態(tài)調(diào)整碰撞檢測,狀態(tài)調(diào)整(2) 初始化初始化程序數(shù)據(jù)初始化程序數(shù)據(jù)初始化彈性平面和球的數(shù)據(jù)初始化彈性平面和球的數(shù)據(jù)設置設置OpenGL環(huán)境環(huán)境處理OnCreate( )(3) 彈性平面類typedef struct tagQuadvec3vVertices4; /四邊形四個頂點vec3vNor

3、mal; /法線向量floatD; /離原點的距離RGBsColor; /顏色 QUAD;9.2.3 編程步驟編程步驟一步步來寫代碼,邊寫邊調(diào)試:1.使用第二章做的OpenGL單文檔模板生成程序框架2.畫出兩個彈力平面3.畫出球4.球運動起來5.碰撞檢測6.其他調(diào)整9.2.3.1生成OpenGL單文檔框架新建工程選擇OpenGL SD AppWizard編譯,改正一個錯誤fatal error RC1015: cannot open include file resMySDOpenGL.rc2.雙擊該錯誤,代碼跳到錯誤處。原來是文件MYWATER.RC中的這句: #include resMyS

4、DOpenGL.rc2“我們的程序名叫“MyWater”,查看資源管理器,在res目錄下發(fā)現(xiàn)只有MyWater.rc2資源文件,因此把錯誤句改為: #include resMyWater.rc2“再編譯,發(fā)現(xiàn)就可以了。這個是制作模板是留下的錯誤。把程序改為調(diào)試版,以方便后面調(diào)試程序右擊工具欄空白處,點擊“組建”,調(diào)出“組建”工具欄,選擇“Win32 Debug”9.2.3.2 畫出兩個彈力平面先在視圖類加入兩個彈力平面的數(shù)據(jù)成員(1)編寫彈力平面定義 在CMySDOpenGLView類頭文件中,但在CMySDOpenGLView類外部加入:#include “vec3.h“ /描述矢量及運算的

5、頭文件typedef struct tagRGB /定義顏色數(shù)據(jù)結構float r,g,b; RGB;typedef struct tagQuad /定義彈力平面vec3vVertices4; /四邊形四個頂點vec3vNormal; /法線向量float D; /離原點的距離RGBsColor; /顏色 QUAD;(2)加入涉及的矢量定義文件 編譯,發(fā)現(xiàn)錯誤,說“vec3.h”找不到。于是從課本代碼中拷貝vec3.h到工程目錄。再編譯,通過了。但是工作區(qū)中還看不見_vec3矢量類,因此還需進行下列操作:點擊菜單“工程”“添加工程”Files 注意不同的漢化版本,上面菜單文字可能稍有不同。然后

6、彈出選擇文件對話框,選中“vec3.h”,點“確定”然后工作區(qū)中就可以看見_vec3類了。如右圖此矢量類包括了矢量的定義和各種矢量運算,可以收集作為一個代碼資源收集作為一個代碼資源。(3) 在CMySDOpenGLView.h中加入兩個彈力平面的定義:public: QUAD g_sQuads2;(4)做一些初始化工作 在CMySDOpenGLView.h中加入(在彈力平面定義的上面或下面)Init的函數(shù)聲明: void Init();(5)在CMySDOpenGLView.cpp中末尾加入Init()的定義,在Init()寫入兩個彈力平面數(shù)據(jù)的初始化,和基本的OpenGL初始化代碼void

7、CMySDOpenGLView:Init(GLvoid)/紅色彈力平面數(shù)據(jù)初始化/四點位置g_sQuads0.vVertices0 = vec3( -2.0 , 2.0 , -5.0f); g_sQuads0.vVertices1 = vec3( 2.0 , 2.0 , -5.0f);g_sQuads0.vVertices2 = vec3( 2.0 , -2.0 , -5.0f);g_sQuads0.vVertices3 = vec3( -2.0 , -2.0 , -5.0f);/法線g_sQuads0.vNormal = vec3(0,0,1); /與原點距離g_sQuads0.D = g_

8、sQuads0.vVertices0.z;/顏色g_sQuads0.sColor.r = 1.0f;g_sQuads0.sColor.g = 0.0f;g_sQuads0.sColor.b = 0.0f;/綠色彈力平面數(shù)據(jù)初始化g_sQuads1.vVertices0 = vec3( -2.0 , 2.0 , 5.0f);g_sQuads1.vVertices1 = vec3( 2.0 , 2.0 , 5.0f);g_sQuads1.vVertices2 = vec3( 2.0 , -2.0 , 5.0f);g_sQuads1.vVertices3 = vec3( -2.0 , -2.0 ,

9、5.0f);g_sQuads1.vNormal = vec3(0,0,1);g_sQuads1.D = g_sQuads1.vVertices1.z; g_sQuads1.sColor.r = 0.0f;g_sQuads1.sColor.g = 1.0f;g_sQuads1.sColor.b = 0.0f;/ 初始化openglglClearColor(0.0f, 0.0f, 0.0f, 1.0f); /設置清屏顏色glEnable(GL_DEPTH_TEST); /啟用深度測試glDepthFunc(GL_LEQUAL); /深度使用“小于等于”的比較方法glPolygonMode (GL_

10、FRONT_AND_BACK, GL_FILL); /多邊形前面背面都要渲染,要畫出整個面(6) 在視圖類的OnCreate()中調(diào)用Init():int CMySDOpenGLView :OnCreate(LPCREATESTRUCT lpCreateStruct) if (CView:OnCreate(lpCreateStruct) = -1)return -1;/ TODO: Add your specialized creation code here/初始化OpenGL和設置定時器m_pDC = new CClientDC(this);SetTimer(1, 20, NULL);In

11、itializeOpenGL(m_pDC);/Init();return 0;(7)在RenderScene()中加入畫彈力平面的代碼:BOOL CMySDOpenGLView:RenderScene() /要做實際的繪圖工作,將在這個空白里寫int i=0;glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );glMatrixMode(GL_MODELVIEW); glLoadIdentity();/ 移動繪圖坐標系(達到拉開攝像機的效果)glTranslatef(-5.0f,0.0f,-25.0f);glRotatef(-45,0.0f,

12、1.0f,0.0f);/ 繪制兩個四邊形代表兩個平面glBegin(GL_QUADS);for (;i2;i+) int v=0; glColor3fv(const float*)&g_sQuadsi.sColor); for (v=0;vGetSafeHdc(); /交互緩沖區(qū)return TRUE;(8) 編譯運行,發(fā)現(xiàn)一片黑什么也看不見。原來觀察方法還沒設置,在視圖類OnSize()中加入觀察方式的代碼:void CMySDOpenGLView:OnSize(UINT nType, int cx, int cy) CView:OnSize(nType, cx, cy);/ TODO: A

13、dd your message handler code here/添加窗口縮放時的圖形變換函數(shù)glViewport(0,0,cx,cy); / 改變視口大小/glMatrixMode(GL_PROJECTION); /矩陣堆棧切換成投影矩陣glLoadIdentity(); /矩陣重置為單位陣/使用透視投影,豎向視野角為45,橫豎比率為窗口的長寬比,/ 最近面為1,最遠面為999。詳細見第七章ppt解釋gluPerspective(45,(float)cx / cy,1,999); (9) 編譯,運行,終于可以看見東西了。如下圖:暗自興奮一下,然后繼續(xù)投入下一步的工作(10)畫兩個彈力平面的

14、四個角畫4條線及z軸,運行變?yōu)橛覉DBOOL CMySDOpenGLView:RenderScene() /前面畫彈力平面的代碼略/ 繪制4條線glBegin(GL_LINES);for (i=0;iGetSafeHdc();/交互緩沖區(qū)return TRUE;9.2.3.3 畫出球(1)在CMySDOpenGLView.h中加入與球相關的三個變量public:void Init();QUAD g_sQuads2;float g_fSphere_radius; /小球半徑GLUquadricObj *q; /二次曲面對象vec3 g_vSpherePos ; /小球的位置(2)在構造函數(shù)中初始化

15、他們的值(當然,在OnCreate里面也行的)CMySDOpenGLView:CMySDOpenGLView()/ TODO: add construction code hereg_fSphere_radius = 0.5f;q = NULL;g_vSpherePos = vec3(0,0,0);(3)在RenderScene()中加入繪制球的代碼BOOL CMySDOpenGLView:RenderScene() /繪制彈力平面、4條連線、z軸的代碼省略 / 繪制球體glTranslatef(g_vSpherePos.x,g_vSpherePos.y,g_vSpherePos.z); gl

16、uSphere(q,g_fSphere_radius,32,32);:SwapBuffers(m_pDC-GetSafeHdc(); /交互緩沖區(qū)return TRUE;(4)再編譯,運行,如圖: 但是球還不能動。9.2.3.4 讓球動起來讓球運動的代碼其實是與碰撞檢測聯(lián)系在一起的,因此我們把控制球運動的代碼寫到CollisionCheck()函數(shù)中,雖然我們現(xiàn)在還沒寫到碰撞檢測的實質(zhì)代碼。所以:(1)在視圖類頭文件中增加CollisionCheck()函數(shù)的定義??梢詫懙絀nit()的后面,還要增加一個小球運動速度的變量:void Init();void CollisionCheck();Q

17、UAD g_sQuads2; /兩個彈力平面float g_fSphere_radius; /小球半徑GLUquadricObj *q; /二次曲面對象vec3 g_vSpherePos ; /小球的位置vec3 g_vVelocity; /小球的速度(2)速度要進行初始化,因此在視圖類構造函數(shù)中增加代碼:CMySDOpenGLView:CMySDOpenGLView()/ TODO: add construction code hereg_fSphere_radius = 0.5f;q=NULL;g_vSpherePos = vec3(0,0,0);g_vVelocity = vec3(0,

18、0,0.1f);(3)在視圖類cpp末尾增加CollisionCheck()函數(shù)的實現(xiàn):void CMySDOpenGLView:CollisionCheck()/算得一個新位置vec3 g_vSphereAfter = g_vSpherePos + g_vVelocity;/把新位置作為小球的新位置,即移動球體g_vSpherePos = g_vSphereAfter;(4)在RenderScene()中調(diào)用CollisionCheck()BOOL CMySDOpenGLView:RenderScene() /繪制彈力平面、連線、z軸的代碼省略/ 繪制球體glTranslatef(g_vSp

19、herePos.x,g_vSpherePos.y,g_vSpherePos.z);gluSphere(q,g_fSphere_radius,32,32);CollisionCheck();:SwapBuffers(m_pDC-GetSafeHdc();/交互緩沖區(qū)return TRUE;(5)編譯,運行,發(fā)現(xiàn)球能運動了。但沒有碰撞檢測,球會飛出彈力平面,如圖:9.2.3.5 碰撞檢測對程序應用前述碰撞檢測的兩種方法(1)加入一個控制變量,以控制是用第一種碰撞檢測方法還是第二種碰撞檢測方法。在視圖類頭文件中增加:void Init();void CollisionCheck();QUAD g_s

20、Quads2; /兩個彈力平面float g_fSphere_radius; /小球半徑bool bDistanceCheck; /是否使用第一種碰撞檢測方法GLUquadricObj *q; /二次曲面對象vec3 g_vSpherePos ; /小球的位置vec3 g_vVelocity; /小球的速度(2) 改寫CollisionCheck,實現(xiàn)碰撞檢測功能void CMySDOpenGLView:CollisionCheck()int i=0;bool collision=false;vec3 g_vSphereAfter = g_vSpherePos + g_vVelocity;for (;i2;i+) / 在兩個平面內(nèi)進行碰撞檢測

溫馨提示

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

最新文檔

評論

0/150

提交評論