¿Cómo hacer un modelo de esqueleto humano?
Este artículo proporciona un método para asignar el vector de acción del esqueleto al modelo de esqueleto humano. Al ingresar la dirección actual de cada hueso y enviarla al modelo de esqueleto, se logra el efecto de animación. La herramienta de desarrollo experimental se desarrolla en la plataforma OpenGL utilizando VC6.0.
Objetivo de lectura:
Se supone que los lectores ya están familiarizados con la programación OpenGL. Incluso si no están familiarizados con ella, solo necesitan comprender la rotación, la traducción y la traducción básicas. operaciones de pila.
Se supone que el lector ya comprende la programación básica en C y necesita comprender el algoritmo recursivo. Consulte la estructura de datos del método recursivo.
Proceso de producción:
El primer paso, preparación del modelo 3D
El propósito de este paso es proporcionar un modelo esquelético descompuesto, lo que requiere la exportación de múltiples componentes del cuerpo No es necesario que cree los archivos y modelos estructurales usted mismo, simplemente búsquelos en línea. Debe haber muchos, preferiblemente modelos animales, pero debe definir el esqueleto cartográfico. Por ejemplo, el modelo de esqueleto en la imagen lo encontré en el software de animación humana Poser 5.0. Luego use 3D Max para exportar varias partes del cuerpo como archivos 3ds. Este paso es muy simple y no requiere ninguna base de 3D Max. Un pequeño truco aquí es seleccionar varias partes y exportarlas como un modelo 3ds. Por ejemplo, necesito exportar los omóplatos izquierdo y derecho y las costillas de la columna como la misma parte, para poder nombrarla cuerpo. De esta forma hemos preparado varios archivos 3ds, que son:
Cuerpo y torso BODY.3DS
Cabeza HEAD.3DS
Brazo izquierdo LSHOULDER.3DS
Brazo derecho RSHOULDER.3DS
Antebrazo izquierdo LELBOW.3DS
Antebrazo derecho RELBOW.3DS
Muslo izquierdo LTHIGH.3DS
p>Muslo derecho RTHIGH.3DS
Pantorrilla izquierda LFEET.3DS
Pantorrilla derecha RFEET.3DS
De esta manera estos componentes pueden ser flexibles Un humano El cuerpo está empalmado.
El segundo paso es definir la estructura de datos central relevante
Para obtener la información de datos de cada parte del cuerpo en movimiento, necesitamos almacenar cierta información de movimiento, que incluye principalmente:
Bone ID
La posición actual de la articulación ósea r_x, r_y, r_z
La relación entre los huesos, por ejemplo, el brazo es una extensión de el torso y el antebrazo izquierdo es una extensión del brazo izquierdo; PID, CID
Podemos entender la relación estructural entre los huesos a través de la siguiente figura
La ubicación donde se encuentra el archivo 3ds se almacena; file_name_3ds
La dirección de inicialización del modelo 3ds; Este es un concepto más abstracto. Se refiere a la dirección desde el nodo principal al nodo secundario. Por ejemplo, la posición inicial del antebrazo izquierdo. es plano y hacia abajo, entonces el vector correspondiente es (-0.2, -1, 0)
La siguiente es la parte de la estructura de datos:
clase de hueso
{
público:
int y;
int x;
int r_z; //coordenada z del mundo real
int r_y;
int r_x;
int rotado_X; //Coordenadas rotadas
int rotado_Y;
int is_marked; //Si se ha marcado
int PID; //Nodo principal
int CID; //Subnodo, actualmente válido para articulaciones de eje y rodillas
float start_arc_x, end_arc_x; //Relativo al límite del ángulo de rotación izquierda y derecha x del nodo principal
float start_arc_y, end_arc_y //Límite del ángulo de rotación en la dirección hacia arriba y hacia abajo de y en relación con el nodo principal p>
float start_arc_z, end_arc_z; // Límite del ángulo de rotación en la dirección delantera y trasera de z en relación con el nodo principal
double lengthRatio;
char name[80] ; //Nombre
char file_name_3ds[180]; //nombre del archivo 3ds
int ID;
bone(int ID, char *nombre, int PID );
virtual ~bone();
float bone_init_x, bone_init_y, bone_init_z; //Inicializa la dirección del vector del hueso, modelo 3d max
} ;
El tercer paso es inicializar la estructura del esqueleto.
Después de definir la estructura del hueso, definimos una clase de esqueleto para cargar estas estructuras durante la inicialización.
obone = bone (2, "head", 1); //Definir un hueso
strcpy(obone.file_name_3ds, "head.3DS" //Establecer su nombre de archivo 3ds
);obone.bone_init_x = 0; //Inicializa la dirección del vector del hueso
obone.bone_init_y = 1;
obone.bone_init_z = 0;
bonevec.push_back (obone); // Colocado en la estructura vectorial, aquí se utiliza el vector en la tecnología de programación STL
Lo siguiente es parte del código implementado:
skelecton: :skelecton()
{
flotante fy = 0.56f;
float ftx = 0.19f;
float ffx = 0.08f;
hueso obone = hueso (1, "cuello",
bonevec.push_back (obone);
obone = hueso (2, "cabeza", 1
strcpy(obone.file_name_3ds, "cabeza.3DS") ;
obone.bone_init_x = 0;
obone.bone_init_y = 1;
obone.bone_init_z = 0;
bonevec.push_back (obone);
obone = hueso (3, "rHombro", 1
bonevec.push_back (obone);
obone = hueso (4); , "lHombro", 1);
bonevec.push_back (obone);
obone = hueso (5, "rElbow",
strcpy); (obone.file_name_3ds, "rShoulder.3DS");
obone.bone_init_x = fy
obone.bone_init_y = -1; 0;
obone.CID = 7;
bonevec.push_back (obone);
obone = hueso (6, "lCodo", 4); /p>
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;
bonevec.push_back (obone);
//.... .........Demasiado largo y solo se da una parte del código.............
}
El cuarto paso es aprender la clase pública 3ds CLoad3DS, que se puede usar para cargar el modelo de visualización
Esta clase es una clase pública con información detallada de la interfaz de la clase CLoad3DS. Puede consultar un proyecto de código abierto.
/Articles/Program/Visual/Other/shiliang.htm
Entonces, conocemos el ángulo entre los dos vectores y sus vectores normales. Lo siguiente se vuelve simple. Hacemos los huesos originales. El vector usa lo normal. vector como eje de rotación y gira en un cierto ángulo. Este ángulo es el ángulo entre los dos vectores. Este problema está resuelto, por lo que el código aquí es el siguiente:
int OpenGL::rotate_bone(Vector3f vVector1. , Vector3f vVector2, Vector3f vVectorOrgin)
{
Vector3f vt1 = Vector3f(vVector1.x, vVector1.y, vVector1.z);
Vector3f vt2 = Vector3f(vVector2.x, vVector2.y, vVector2.z);
Vector3f vt4 = vt2-vt1;
doble arco12 = AngleBetweenVectors(vVectorOrgin, vt4); p>
doble rarc12 = 180*arc12/pi;
float len= Distancia(vt1, vt2);
Vector3f vt3 = Cruz(vVectorOrgin, vt4); p>
glRotatef ((float)rarc12, vt3.x, vt3.y, vt3.z);
devuelve 0;
}