筆者介紹:姜雪偉,it公司技術合夥人,it高階講師,csdn社群專家,特邀編輯,暢銷書作者,已出版書籍:《手把手教你架構3d遊戲引擎》電子工業出版社和《unity3d實戰核心技術詳解》電子工業出版社等。
以前有朋友問我,關於變形動畫是如何實現的,實現方式主要有兩種,一種是通過美術人員利用max工具自己調出動畫,這種調出的動畫太僵硬而且不能根據使用者的要求隨意變形,只能按照預先調好的動畫變形,這種做法可以排除了。第二種做法是通過程式實現自由的動畫變換,在這裡給讀者介紹利用opengl實現的變形動畫,目的是把動畫的變換原理給讀者介紹清楚。
在介紹3d變形的之前,讀者首先要掌握的是3d的固定流水線, 現在做遊戲的開發者對於什麼是3d固定流水線一無所知,市面上使用的大部分引擎都封裝的非常好,開發者也淪為了只會使用工具,對於一些常識一概不知。在遊戲公司做的主要事情就是寫寫邏輯,呼叫呼叫介面,如果需求超出介面的範疇基本上就是一籌莫展,或者說引擎的功能滿足不了。面對這種情況,作為開發者必須把3d的基本知識掌握了,這樣遇到3d的任何問題都不會感覺難下手,至少知道解決問題的思路。如果讀者對於3d固定流水線不清楚可以自己去查閱,我也寫過關於3d固定流水線的部落格,在這裡就不做介紹了,簡單的一句話表示3d固定流水線就是將3d模型在2d螢幕上顯示的過程,這個過程就是對於矩陣的換算,對應3d固定流水線是3d可程式設計流水線,不清楚的讀者自行查閱一下,這個都必須要掌握的。
接下來介紹實現變形的基本思路:
第一步,準備使用的模型,模型格式很多種,這個可以使用網上的,也可以自己編寫外掛程式實現自定義的模型。本專案對應的模型是字尾名為m的自定義的模型格式,模型格式內容如下所示:
上圖顯示的只是一部分,為了能讓讀者看清楚,並沒有對模型進行加密,為了計算方便,這裡只給出了vertex頂點和face面的資料。
第二步,定義模型的資料結構體
#ifndef halfedge_h
#define halfedge_h
#include using namespace std;
// halfedge structures
struct he_edge;
struct he_vert;
struct he_face;
struct he_line;
struct he_edge
;struct he_vert
;struct he_face
;struct he_line
he_line(){};
he_line(const he_line &vert)
he_line(unsigned int v1, unsigned int v2)
};#endif
第三步,需要載入模型,並計算頂點和麵的法線以及設定包圍盒,標頭檔案的內容給讀者展示如下:
#ifndef mesh_h
#define mesh_h
#include #include //#include #include #include #include using namespace std;
// mesh functions
void loadmesh(std::string path);
void findminmax(float tempx, float tempy, float tempz);
void calcfacenorm(void);
void calcvertnorm(void);
void settoorigin(void);
void scaletoorigin(void);
// draw functions
double editlinewidth(int width);
void drawmeshwire(void);
void drawmeshsolid(void);
void drawmeshpoint(void);
void drawbbox(void);
void drawgrid(void);
void drawaxes(void);
// dialog functions
void createfiledialog(void);
int createmsgbox(int msgboxid);
enum
;#endif
具體實現會在部落格的末尾給讀者展示。
第四步,開始對模型的變形處理,在這裡並沒有使用什麼高深的演算法,其實就是對它們的頂點進行矩陣變換。首先進行的是世界變換,投影變換,最後是視口變換。
變形的函式如下所示:
void deformmesh()
} for(int count = 0; count < numofvert; count++)
}}
當你看到**後,第一印象就是太簡單了,確實是這樣,變形其實就是將需要改變的頂點進行一系列矩陣變換,在這裡使用了opengl的庫函式介面
glpushmatrix();
gltranslatef(copyvertices[count].x, copyvertices[count].y, copyvertices[count].z);
glutsolidsphere(0.1, 20, 20);
glpopmatrix();
進行頂點的移動,同時呼叫了函式trivariatebernstein
進行頂點的變換以及權值計算,**如下所示:
vertex trivariatebernstein(vertex vert)
} }return convertedvert;
}
沒有使用任何演算法,實現的就是模型的矩陣變換。
最後一步就是實現,首先要做的事情是選擇需要變形的頂點或者區域,使用了函式如下所示:
void moveselectedcp(int endx, int endy)
}
在再main函式中呼叫封裝的函式即可。其實做起來還是比較簡單的,就是對變形的部分做了矩陣的運算。大家關注上面加粗的部分。 CSS3 Transform變形(3D轉換)
三維變換使用基於二維變換的相同屬性,如果您熟悉二維變換,你們發現3d變形的功能和2d變換的功能相當類似。css3中的3d變換主要包括以下幾種功能函式 3d位移 css3中的3d位移主要包括translatez 和translate3d 兩個功能函式 3d旋 css3中的3d旋轉主要包括rotatex...
3D基礎 3D座標變換在OpenGL 中的實踐
在計算機圖形學中,變換矩陣是非常基礎也是非常重要的知識,在許多資料中,只是羅列出一堆矩陣公式,圖表等等,這很難給人感性的認識,特別是初學者,筆者結合 opengl 這樣乙個非常流行的圖形庫,以實踐的方式闡述在 3d變換矩陣中最簡單的三種 平移 縮放以及旋轉。這裡有一些前提知識,就是需要了解線性代數一...
OpenGL教程之向3D進軍
在上節課的內容上作些擴充套件,我們現在開始生成真正的3d物件,而不是象前兩節課中那樣3d世界中的2d物件。我們給三角形增加乙個左側面,乙個右側面,乙個後側面來生成乙個金字塔 四稜錐 給正方形增加左 右 上 下及背面生成乙個立方體。我們混合金字塔上的顏色,建立乙個平滑著色的物件。給立方體的每一面則來個...