/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Avril 2001 */ /* Calculs sur l'energie diffusee */ /* par une surface */ #include #include typedef struct coord_3D { float x ; float y ; float z ; } coord_3D ; typedef struct couleur { float r ; float v ; float b ; } couleur ; typedef struct direction_3D { float dx ; float dy ; float dz ; } direction_3D ; typedef struct pointLight { coord_3D pos ; couleur coul ; float energie ; } pointLight ; typedef struct materiau { couleur diffusion ; couleur reflexion ; couleur transmission ; couleur emission ; } materiau ; typedef struct energie { float er ; float ev ; float eb ; } energie ; float distance(coord_3D *p1, coord_3D *p2) { double x = p1->x - p2->x ; double y = p1->y - p2->y ; double z = p1->z - p2->z ; double d2 = x*x + y*y + z*z ; return((float) pow(d2,0.5)) ; } void calculVecteurNorme(coord_3D *pi, coord_3D *pf, direction_3D *n) { double x = pf->x - pi->x ; double y = pf->y - pi->y ; double z = pf->z - pi->z ; double d2 = x*x + y*y + z*z ; d2 = pow(d2,0.5) ; n->dx =(float) (x / d2) ; n->dy =(float) (y / d2) ; n->dz =(float) (z / d2) ; } float produitScalaire(direction_3D *d1, direction_3D *d2) { return(d1->dx*d2->dx + d1->dy*d2->dy + d1->dz*d2->dz) ; } /* En entree les coordonnees du point p et la pointlight l. En sortie l'energie recue*/ void calculEnergieRecue(coord_3D *p, pointLight *l, energie *e) { float d = distance(p,&l->pos) ; float atten = 1.0F / d / d ; e->er = atten * l->energie * l->coul.r ; e->ev = atten * l->energie * l->coul.v ; e->eb = atten * l->energie * l->coul.b ; } /* En entree les coordonnees du point p, la normale n a la surface au point p, le materiau m de la surface, la pointlight l. En sortie l'energie diffusee*/ void calculEnergieDiffusee(coord_3D *p, direction_3D *n, materiau *m, pointLight *l, energie *e) { energie recu ; calculEnergieRecue(p,l,&recu) ; direction_3D li ; calculVecteurNorme(p,&l->pos,&li) ; float scal = produitScalaire(&li,n) ; if ( scal < 0.0F ) scal = 0.0F ; e->er = recu.er * scal * m->diffusion.r ; e->ev = recu.ev * scal * m->diffusion.v ; e->eb = recu.eb * scal * m->diffusion.b ; } int main(int argc,char **argv) { coord_3D p = { 1.0F,2.0F,0.0F } ; direction_3D n = { 0.0F,0.0F,1.0F } ; pointLight l = { {-1.0F,2.0F,4.0F}, {1.0F,0.5F,0.5F}, 5.0F } ; materiau m = { {0.5F,0.5F,1.0F}, {0.0F,0.0F,0.0F}, {0.0F,0.0F,0.0F}, {0.0F,0.0F,0.0F} } ; energie e ; energie ed ; calculEnergieRecue(&p,&l,&e) ; printf("Energie recue : %f %f %f\n", e.er,e.ev,e.eb) ; calculEnergieDiffusee(&p,&n,&m,&l,&ed) ; printf("Energie diffusee : %f %f %f\n", ed.er,ed.ev,ed.eb) ; return(0); }