當前位置:菜譜大全網 - 素菜食譜大全 - 如何制作人體骨骼模型?

如何制作人體骨骼模型?

提出了壹種將骨骼運動矢量映射到人體骨骼模型的方法。通過輸入每個骨架的當前方向,並反饋給骨架模型,實現動畫效果。實驗開發工具是在OpenGL平臺上用VC6.0開發的。

閱讀目標:

假設讀者熟悉OpenGL編程,即使他們不熟悉,只要他們了解基本的旋轉、平移和堆棧操作。

假設讀者已經了解了基本的c++編程,其中需要了解遞歸算法。遞歸方法請參考數據結構。

生產流程:

第壹步,3D模型準備。

這壹步的目的是提供壹個分解後的骨架模型,需要導出組成身體結構的多個文件。模型可以自己做。在網上找找就知道了。應該有很多,最好是人體模型。如果使用動物模型,還可以定義自己的貼圖骨架。比如我從人體動畫軟件poser 5.0中找到了圖中的骨架模型。然後使用3d max將身體的所有部分導出到3ds文件。這壹步很簡單,不需要任何3d max的基礎。這裏有壹個小技巧,您可以選擇多個部分導出為3ds模型。例如,我需要將左右肩胛骨和脊柱肋骨導出為同壹個部分,這樣就可以將其命名為身體。因此,我們準備了各種3ds文件,即:

Body trunk BODY.3DS

HEAD.3DS

左臂l肩部. 3DS

右臂RSHOULDER.3DS

左前臂LELBOW.3DS

右前臂重弓. 3DS

左大腿l高. 3DS

右大腿RTHIGH.3DS

左小腿LFEET.3DS

右小腿RFEET.3DS

這樣,這些部件可以靈活地拼接成壹個人體。

第二步是定義相關的核心數據結構。

為了得到運動中身體各個部位的數據信息,我們需要存儲壹些運動信息,主要包括:

骨架ID

骨關節的當前位置;x,y,z

骨骼之間的關系,比如手臂是軀幹的延伸,左前臂是左臂的延伸;PID,CID

我們可以通過下圖了解骨骼之間的結構關系。

存儲3ds文件的位置;文件名3ds

3ds模型的初始化方向;這是壹個比較抽象的概念,指的是從父節點到子節點的方向。比如左前臂的初始位置是平的向下,那麽對應的向量就是(-0.2,-1,0)。

以下是數據結構部分:

類骨

{

公共:

int y;

int x;

int r _ z;//真實世界的Z坐標

int r _ y;

int r _ x;

int rotated _ X;//旋轉坐標

int rotated _ Y;

int是_ marked//有沒有做標記?

int PID//父節點

int CID//子節點,當前對軸關節和膝蓋有效。

浮點start_arc_x,end _ arc _ x;//X相對於父節點的左右方向的旋轉角度限制

浮點start_arc_y,end _ arc _ y;//相對於父節點的y上下旋轉角度限制

浮點start_arc_z,end _ arc _ z;//相對於父節點的Z旋轉角度限制

雙倍長度比;

char name[80];//名稱

char file _ name _ 3ds[180];//3ds文件名

int ID

bone(int ID,char *name,int PID);

虛~骨();

float bone_init_x,bone_init_y,bone _ init _ z;//初始化骨骼的矢量方向,3d max模型。

};

第三步,初始化骨架結構。

在定義了骨骼的結構之後,我們定義了壹個骨骼類來在第壹次初始化時加載這些結構。

obone = bone (2,“頭”,1);//定義骨骼

strcpy(obone.file_name_3ds," head . 3ds ");//設置其3ds文件名。

obone . bone _ init _ x = 0;//初始化骨骼的向量方向。

obone . bone _ init _ y = 1;

obone . bone _ init _ z = 0;

bone vec . push _ back(obone);//放到vector結構中,這裏用到STL編程技術中的vector。

以下是部分代碼:

skeleton::skeleton()

{

浮點fy = 0.56f

float ftx = 0.19f;

浮點ffx = 0.08f

bone obone = bone (1,“脖子”,0);

bone vec . push _ back(obone);

obone = bone (2,“頭”,1);

strcpy(obone.file_name_3ds," head . 3ds ");

obone . bone _ init _ x = 0;

obone . bone _ init _ y = 1;

obone . bone _ init _ z = 0;

bone vec . push _ back(obone);

obone = bone (3," rShoulder ",1);

bone vec . push _ back(obone);

obone = bone (4," lShoulder ",1);

bone vec . push _ back(obone);

obone = bone (5,“rElbow”,3);

strcpy(obone.file_name_3ds," rshoulder . 3ds ");

obone.bone _ init _ x = fy

obone . bone _ init _ y =-1;

obone . bone _ init _ z = 0;

obone。CID = 7;

bone vec . push _ back(obone);

obone = bone (6,“lElbow”,4);

strcpy(obone.file_name_3ds," lshoulder . 3ds ");

obone . bone _ init _ x =-fy;

obone . bone _ init _ y =-1;

obone . bone _ init _ z = 0;

obone。CID = 8;

bone vec . push _ back(obone);

//.............太長,只給出了部分代碼。..........................

}

第四步,學習3ds的類CLoad3ds,可以用來加載顯示模型。

這個類是壹個通用類,CLoad3DS類的詳細接口信息可以參考壹個開源項目。/Articles/Program/Visual/Other/shiliang . htm

然後,我們知道了兩個向量和它們的法向量的夾角,下面的事情就變得簡單了。我們讓骨骼的原向量以法向量為旋轉軸,旋轉壹定的角度,這個角度就是兩個向量之間的角度,這樣問題就解決了,所以這裏的代碼如下:

int OpenGL::rotate _ bone(vector 3f vvector 1,Vector3f vVector2,Vector3f vVectorOrgin)

{

vector 3f vt 1 = vector 3f(v vector 1 . x,vVector1.y,v vector 1 . z);

vector 3f vt2 = vector 3f(v vector 2 . x,vVector2.y,v vector 2 . z);

vector 3f vt4 = vt2-vt 1;

double arc 12 = angle between vectors(vvectorrorgin,vt4);

double rarc 12 = 180 * arc 12/pi;

float len=距離(vt1,vt2);

vector 3f vt3 = Cross(vvectorrorgin,vt4);

glRotatef ((float)rarc12,vt3.x,vt3.y,vt3 . z);

返回0;

}