Correction du TD 2 : placement automatique de la caméra
Déclaration de la Bounding Box dans object.h
typedef struct BoundingBoxStruct {
VERTEX Vertex[8]; /* Les 8 sommets de la bbox */
double Height; /* Sa hauteur */
double Width; /* Sa longueur */
double Depth; /* Sa profondeur */
double plus_grand_cote_sur_2; /* Le plus grand cote sur deux
utile pour le placement de la camera */
} BBOX;
typedef struct ObjectStruct {
...
/* Sa bounding box */
BBOX bbox;
} Object;
Placer le repère de l'objet en son centre de gravité, Calcul
de la Bounding Box (dans object.c)
/*------------------------------------------*/
static void CenterObjectPoints(Object *obj)
/*------------------------------------------*/
/* Positionne le centre du repere objet sur le barycentre de l'objet et
calcule la bounding box de l'objet */
{
double Somme_x=0, Somme_y=0, Somme_z=0;
double Min_x, Min_y, Min_z;
double Max_x, Max_y, Max_z;
int i;
for (i=0; i < obj->NbVertices; i++){
Somme_x += obj->Vertex[i].ObjectVertex.x;
Somme_y += obj->Vertex[i].ObjectVertex.y;
Somme_z += obj->Vertex[i].ObjectVertex.z;
}
Somme_x = (Somme_x / obj->NbVertices);
Somme_y = (Somme_y / obj->NbVertices);
Somme_z = (Somme_z / obj->NbVertices);
Min_x = obj->Vertex[0].ObjectVertex.x - Somme_x;
Min_y = obj->Vertex[0].ObjectVertex.y - Somme_y;
Min_z = obj->Vertex[0].ObjectVertex.z - Somme_z;
Max_x = Min_x; Max_y = Min_y; Max_z = Min_z;
for (i=0; i < obj->NbVertices; i++){
if ((obj->Vertex[i].ObjectVertex.x -= Somme_x) < Min_x)
Min_x = obj->Vertex[i].ObjectVertex.x ;
else
if (obj->Vertex[i].ObjectVertex.x > Max_x)
Max_x = obj->Vertex[i].ObjectVertex.x;
if ((obj->Vertex[i].ObjectVertex.y -= Somme_y) < Min_y)
Min_y = obj->Vertex[i].ObjectVertex.y ;
else
if (obj->Vertex[i].ObjectVertex.y > Max_y)
Max_y = obj->Vertex[i].ObjectVertex.y;
if ((obj->Vertex[i].ObjectVertex.z -= Somme_z) < Min_z)
Min_z = obj->Vertex[i].ObjectVertex.z ;
else
if (obj->Vertex[i].ObjectVertex.z > Max_z)
Max_z = obj->Vertex[i].ObjectVertex.z;
}
CreateBBox(obj, Min_x, Min_y, Min_z, Max_x, Max_y, Max_z);
}
/******************************************/
void CreateBBox(Object *obj, double Min_x, double Min_y, double Min_z,
double Max_x, double Max_y, double Max_z)
/******************************************/
{
obj->bbox.Vertex[0].ObjectVertex.x = Min_x;
obj->bbox.Vertex[0].ObjectVertex.y = Min_y;
obj->bbox.Vertex[0].ObjectVertex.z = Min_z;
obj->bbox.Vertex[1].ObjectVertex.x = Min_x;
obj->bbox.Vertex[1].ObjectVertex.y = Max_y;
obj->bbox.Vertex[1].ObjectVertex.z = Min_z;
obj->bbox.Vertex[2].ObjectVertex.x = Max_x;
obj->bbox.Vertex[2].ObjectVertex.y = Max_y;
obj->bbox.Vertex[2].ObjectVertex.z = Min_z;
obj->bbox.Vertex[3].ObjectVertex.x = Max_x;
obj->bbox.Vertex[3].ObjectVertex.y = Min_y;
obj->bbox.Vertex[3].ObjectVertex.z = Min_z;
obj->bbox.Vertex[4].ObjectVertex.x = Max_x;
obj->bbox.Vertex[4].ObjectVertex.y = Min_y;
obj->bbox.Vertex[4].ObjectVertex.z = Max_z;
obj->bbox.Vertex[5].ObjectVertex.x = Min_x;
obj->bbox.Vertex[5].ObjectVertex.y = Min_y;
obj->bbox.Vertex[5].ObjectVertex.z = Max_z;
obj->bbox.Vertex[6].ObjectVertex.x = Min_x;
obj->bbox.Vertex[6].ObjectVertex.y = Max_y;
obj->bbox.Vertex[6].ObjectVertex.z = Max_z;
obj->bbox.Vertex[7].ObjectVertex.x = Max_x;
obj->bbox.Vertex[7].ObjectVertex.y = Max_y;
obj->bbox.Vertex[7].ObjectVertex.z = Max_z;
obj->bbox.Height = Max_x - Min_x;
obj->bbox.Width = Max_y - Min_y;
obj->bbox.Depth = Max_z - Min_z;
obj->bbox.plus_grand_cote_sur_2 =
MAX(MAX(obj->bbox.Height, obj->bbox.Width), obj->bbox.Depth)/2.0;
printf ("CBB: W=%g H=%g D=%g PGC=%g\n",obj->bbox.Width,
obj->bbox.Height,
obj->bbox.Depth,
obj->bbox.plus_grand_cote_sur_2);
}
/* 1 ----------- 2
/ | /|
/ | / |
6 ---------- 7 |
| | | |
| | | |
| 0 --------/ 3
| / | /
| / |/
5 ----------- 4
*/
Placement de la caméra (dans object.c)
/********************************************/
void PlaceCamera (Camera *cam, Object *obj){
/********************************************/
double Ox, Oy, Oz, z;
SetMatrixToIdentity(&cam->LocalToGlobal);
SetMatrixToIdentity(&cam->GlobalToLocal);
Ox = obj->LocalToGlobal.elem[0][3];
Oy = obj->LocalToGlobal.elem[1][3];
Oz = obj->LocalToGlobal.elem[2][3];
z = Oz + obj->bbox.plus_grand_cote_sur_2 * (1 + 1/tan ((M_PI*cam->fovX) / 180.0));
TranslateCamera(cam, Ox, Oy, z);
}
Dessin de la Bounding Box (dans graphics.c)
/*-----------------------------------------------*/
static void draw_object(Object *obj, Camera *cam)
/*-----------------------------------------------*/
/* Affiche dans la fenetre graphique l'objet passe en 1er parametre, comme
s'il etait vu par la camera passe en 2eme parametre */
{
...
draw_boundingBox(obj, cam);
...
}
/*******************************************************/
static void draw_boundingBox(Object *obj, Camera *cam){
/*******************************************************/
int i;
/* D'abord, projection des points */
for (i=0; i < 8; i++){
TransformPoint(&(obj->bbox.Vertex[i].ObjectVertex),
&(obj->LocalToCamera),
&(obj->bbox.Vertex[i].CameraVertex));
obj->bbox.Vertex[i].ScreenVertex.x = ((obj->bbox.Vertex[i].CameraVertex.x /
obj->bbox.Vertex[i].CameraVertex.z) *
cam->sx + cam->tx);
obj->bbox.Vertex[i].ScreenVertex.y = ((obj->bbox.Vertex[i].CameraVertex.y /
obj->bbox.Vertex[i].CameraVertex.z) *
cam->sy + cam->ty);
}
/* Ensuite affichage des aretes de la bounding box */
DrawFace(&(obj->bbox.Vertex[0].ScreenVertex),
&(obj->bbox.Vertex[1].ScreenVertex),
&(obj->bbox.Vertex[2].ScreenVertex),
&(obj->bbox.Vertex[3].ScreenVertex));
DrawFace(&(obj->bbox.Vertex[5].ScreenVertex),
&(obj->bbox.Vertex[6].ScreenVertex),
&(obj->bbox.Vertex[7].ScreenVertex),
&(obj->bbox.Vertex[4].ScreenVertex));
DrawFace(&(obj->bbox.Vertex[5].ScreenVertex),
&(obj->bbox.Vertex[6].ScreenVertex),
&(obj->bbox.Vertex[1].ScreenVertex),
&(obj->bbox.Vertex[0].ScreenVertex));
DrawFace(&(obj->bbox.Vertex[4].ScreenVertex),
&(obj->bbox.Vertex[7].ScreenVertex),
&(obj->bbox.Vertex[2].ScreenVertex),
&(obj->bbox.Vertex[3].ScreenVertex));
}