¿Cómo hacer un modelo de esqueleto humano?
Objetivos de lectura:
Se supone que los lectores están familiarizados con la programación OpenGL, incluso si no lo están, siempre que comprendan las operaciones básicas de rotación, traducción y apilamiento.
Se supone que los lectores ya comprenden la programación básica de C++, lo que requiere comprensión de los algoritmos recursivos. Consulte la estructura de datos para conocer los métodos recursivos.
Proceso de producción:
El primer paso es preparar el modelo 3D.
El propósito de este paso es proporcionar un modelo de esqueleto descompuesto, lo que requiere exportar múltiples archivos que conforman la estructura del cuerpo. Puedes hacer el modelo tú mismo. Búscalo en línea. Debe haber muchos, preferiblemente maniquíes. Si utilizas modelos animales, también puedes definir tu propio esqueleto texturizado. Por ejemplo, encontré el modelo de esqueleto en la imagen del software de animación humana POSER 5.0. Luego use 3d max para exportar todas las partes del cuerpo a archivos 3ds. Este paso es muy sencillo y no requiere ninguna base 3D Max. Aquí tienes un pequeño truco: puedes seleccionar varias partes para 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 nombrarlo cuerpo. Por ello, hemos preparado varios archivos 3ds, a saber:
Cuerpo tronco BODY.3DS
HEAD.3DS
Brazo izquierdo l hombro 3DS
. p>Brazo derecho RSHOULDER.3DS
Antebrazo izquierdo LELBOW.3DS
El antebrazo derecho está muy arqueado 3DS
El muslo izquierdo está alto. 3DS
p>Muslo derecho RTHIGH.3DS
Pantorrilla izquierda LFEET.3DS
Pantorrilla derecha RFEET.3DS
De esta manera. Estas partes se pueden unir de manera flexible en un cuerpo humano.
El segundo paso es definir las estructuras de datos centrales relevantes.
Para obtener información sobre varias partes del cuerpo durante el movimiento, necesitamos almacenar cierta información del movimiento, que incluye principalmente:
ID del esqueleto
El posición actual de las articulaciones óseas; x, y, z
La relación entre los huesos, por ejemplo, el brazo es una extensión del tronco y el antebrazo izquierdo es una extensión del brazo izquierdo; CID
Podemos entender los huesos a través de la siguiente figura y la relación estructural entre ellos.
La ubicación donde se almacena el archivo 3ds; nombre del archivo 3ds
La dirección de inicialización del modelo 3ds es un concepto relativamente abstracto, que se refiere a la dirección desde el nodo principal hasta; el nodo hijo. Por ejemplo, si la posición inicial del antebrazo izquierdo es plana y hacia abajo, entonces el vector correspondiente es (-0,2, -1, 0).
La siguiente es la parte de la estructura de datos:
Boneoid
{
Público:
int y;
int x;
int r _ z; //Coordenada Z del mundo real
int r _ y;
int r_x;
int rotado_
int PID//Nodo padre
int CID//Nodo hijo, actualmente válido para articulaciones de eje y rodillas.
Punto flotante start_arc_x, end_arc_x; // El límite del ángulo de rotación de X en relación con la dirección izquierda y derecha del nodo principal
Punto flotante start_arc_y, end_arc_y // Y up and; límite de ángulo de rotación hacia abajo en relación con el nodo principal
Punto flotante start_arc_z, end_arc_z; // límite de ángulo de rotación Z en relación con el nodo principal
Relación de longitud doble
char nombre[80]; //Nombre
archivo char _ nombre _ 3ds[180]; //nombre de archivo 3ds
int ID
bone( int ID, char *name, int PID);
virtual~bone();
float bone_init_x, bone_init_y, bone_init_z // Inicializa la dirección del vector del hueso, 3d max; modelo.
};
El tercer paso es inicializar la estructura del esqueleto.
Después de definir las estructuras de los huesos, definimos una clase de hueso para cargar estas estructuras en la primera inicialización.
obone = bone (2, "head", 1); //Definir el hueso
strcpy(obone.file_name_3ds, "head . 3ds"); Nombre del archivo.
obone .bone _ init _ x = 0; //Inicializa la dirección del vector del hueso.
obone .bone_init_y = 1;
obone_init_z = 0
bone vec . ; // Ponlo en la estructura vectorial. Aquí se utiliza el vector en la tecnología de programación STL.
Lo siguiente es parte del código:
skeleton::skeleton()
{
Punto flotante fy = 0.56f
float ftx = 0.19f;
Float ffx = 0.08f
hueso obone = hueso (1, "cuello", 0);
hueso vec . push _ back(obone);
obone = hueso (2, "cabeza", 1
strcpy(obone.file_name_3ds, " cabeza . 3ds "); );
hueso_init_x = 0;
hueso_init_y = 1;
hueso_init_z. = 0 ;
hueso vec . push _ back(obone);
obone = hueso (3, " rHombro ",
hueso vec . push_back(obone);
obone = hueso (4, " lHombro ",
hueso vec . >obone = hueso (5, "rElbow", 3);
strcpy(obone.file_name_3ds, "rshoulder . 3ds");
obone.bone_init_x = fy
p>obone.bone_init_y=-1;
obone.bone_init_z=0;
obone. CID = 7;
hueso vec . push _ back(obone);
obone = hueso (6, "lElbow", 4); obone.file_name_3ds, " lshoulder . 3ds ");
obone .bone _ init _ x =-fy
obone _ init _ y =-1; >
obone.bone_init_z = 0;
obone. CID = 8;
bone vec . push _ back(obone);
//.............Demasiado largo, solo se da parte de el código. ........................
}
El cuarto paso, aprender CLoad3ds similar a 3ds, se puede utilizar para cargar modelos de visualización.
Esta clase es una clase general. Para obtener información detallada sobre la interfaz de la clase CLoad3DS, consulte un proyecto de código abierto. /Articles/Program/Visual/Other/shiliang .htm
Entonces, conocemos el ángulo entre los dos vectores y sus vectores normales, y lo siguiente se vuelve simple.
Dejamos que el vector original del hueso gire un cierto ángulo con el vector normal como eje de rotación. Este ángulo es el ángulo entre los dos vectores, por lo que el problema está resuelto, por lo que el código aquí es el siguiente:
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); 3f vt4 = vt2 -vt 1;
doble arco 12 = ángulo entre vectores(vvectorrorgin, vt4);
doble rarc 12 = 180 * arco 12/pi; p>
float len=distancia(vt1,vt2);
vector 3f vt3 = Cross(vvectorrorgin,vt4);
glRotatef ((float)rarc12,vt3.x ,vt3.y,vt3 z);
Devuelve 0;
}