Current location - Training Enrollment Network - Mathematics courses - How to make a human skeleton model?
How to make a human skeleton model?
A method of mapping bone motion vectors to human skeleton model is proposed. By inputting the current direction of each skeleton and feeding it back to the skeleton model, the animation effect is realized. The experimental development tool is developed with VC6.0 on the OpenGL platform.

Reading objectives:

It is assumed that readers are familiar with OpenGL programming, even if they are not, as long as they understand the basic rotation, translation and stack operations.

It is assumed that the reader has already understood the basic c++ programming, in which recursive algorithms are needed. Please refer to the data structure for recursive methods.

Production process:

The first step is to prepare the 3D model.

The purpose of this step is to provide a decomposed skeleton model, which needs to export multiple files that make up the body structure. The model can be made by itself. Just look for it on the internet. There should be many, preferably mannequins. If you use animal models, you can also define your own mapping skeleton. For example, I found the skeleton model in the picture from the human animation software poser 5.0. Then use 3d max to export all parts of the body to a 3ds file. This step is very simple, and does not require any 3d max foundation. Here's a trick. You can select multiple parts to export as a 3ds model. For example, I need to export the left and right shoulder blades and spine ribs into the same part, so I can name them the body. Therefore, we have prepared various 3ds files, namely:

Body trunk BODY.3DS

HEAD.3DS

Left arm l shoulder .3ds

Right arm RSHOULDER.3DS

Left forearm LELBOW.3DS

Right forearm double bow. 3DS

L height of left thigh .3ds.

Right thigh RTHIGH.3DS

Left calf LFEET.3DS

Right calf RFEET.3DS

In this way, these parts can be flexibly spliced into a human body.

The second step is to define the related core data structure.

In order to get the data information of various parts of the body during exercise, we need to store some exercise information, mainly including:

Skeleton ID

The current position of the joint; x,y,z

The relationship between bones, such as the arm is an extension of the trunk and the left forearm is an extension of the left arm; PID,CID

We can understand the structural relationship between bones through the following picture.

The location where 3ds files are stored; File name 3ds

Initialization direction of 3ds model; This is an abstract concept, which refers to the direction from the parent node to the child node. For example, the initial position of the left forearm is flat downward, then the corresponding vector is (-0.2,-1, 0).

The following is the data structure part:

Osteoid

{

Public:

int y;

int x;

int r _ z; //Z coordinates of the real world

int r _ y;

int r _ x;

int rotated _ X; //Rotation coordinates

int rotated _ Y;

Int is _ marked// Is it marked?

Int PID// parent node

Int CID// child node, currently valid for shaft joints and knees.

Floating point start_arc_x, end _ arc _ x;; //rotation angle limit of x relative to the left and right direction of the parent node

Floating point start_arc_y, end _ arc _ y;; //y rotation angle limit relative to the parent node

Floating point start_arc_z, end _ arc _ z;; //Z rotation angle limit relative to the parent node

Double length ratio;

char name[80]; //Name

char file _ name _ 3ds[ 180]; //3ds file name

int ID

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

Deficiency ~ bone ();

float bone_init_x,bone_init_y,bone _ init _ z; //Initialize the vector direction of the bone, 3d max model.

};

The third step is to initialize the skeleton structure.

After defining the structure of bones, we define a bone class to load these structures at the first initialization.

Obone = bone (2, "head",1); //Define bones

strcpy(obone.file_name_3ds," head . 3ds "); //Set its 3ds file name.

obone . bone _ init _ x = 0; //Initialize the vector direction of the bone.

obone . bone _ init _ y = 1;

obone . bone _ init _ z = 0;

bone vec . push _ back(obone); //put it in the vector structure, where the vector in STL programming technology is used.

The following is part of the code:

skeleton::skeleton()

{

Floating point fy = 0.56f

float ftx = 0. 19f;

Floating point ffx = 0.08f

Bonebone = bone (1,"neck", 0);

bone vec . push _ back(obone);

Obone = bone (2, "head",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);

//............. is too long, only part of the code is given. ..........................

}

The fourth step is to learn the class of 3ds, CLoad3ds, which can be used to load the display model.

This class is a general class, and the detailed interface information of CLoad3DS class can refer to an open source project. /Articles/Program/Visual/Other/shiliang . htm

Then, we know the angle between two vectors and their normal vectors, and the following things become simple. We let the original vector of the bone take the normal vector as the rotation axis and rotate it by a certain angle, which is the angle between the two vectors, so the problem is solved, so the code here is as follows:

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

{

vector 3f vt 1 = vector 3f(v vector 1 . x,vVector 1.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= distance (vt 1, vt2);

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

glRotatef ((float)rarc 12,vt3.x,vt3.y,vt3 . z);

Returns 0;

}