/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Avril 2001 */ /* Illustration du trace d'un segment */ /* de voxels pour une utilisation */ /* en lancer de rayons */ #include #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleReshape.h" static int aff = 0 ; static int lim = 0 ; void myinit(void) { GLfloat light_position0[] = { 1.0F,1.0F,1.0F,0.0F }; glLightfv(GL_LIGHT0,GL_AMBIENT,couleurNoir()); glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurBlanc()); glLightfv(GL_LIGHT0,GL_SPECULAR,couleurBlanc()); glLightfv(GL_LIGHT0,GL_POSITION,light_position0); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); } void voxel1(int x,int y,int z) { glColor4fv(couleurBlanc(0.5F)) ; glBegin(GL_LINES) ; glVertex3i(x,y,z) ; glVertex3i(x+1,y,z) ; glVertex3i(x,y+1,z) ; glVertex3i(x+1,y+1,z) ; glVertex3i(x,y,z+1) ; glVertex3i(x+1,y,z+1) ; glVertex3i(x,y+1,z+1) ; glVertex3i(x+1,y+1,z+1) ; glVertex3i(x,y,z) ; glVertex3i(x,y+1,z) ; glVertex3i(x+1,y,z) ; glVertex3i(x+1,y+1,z) ; glVertex3i(x,y,z+1) ; glVertex3i(x,y+1,z+1) ; glVertex3i(x+1,y,z+1) ; glVertex3i(x+1,y+1,z+1) ; glVertex3i(x,y,z) ; glVertex3i(x,y,z+1) ; glVertex3i(x+1,y,z) ; glVertex3i(x+1,y,z+1) ; glVertex3i(x,y+1,z) ; glVertex3i(x,y+1,z+1) ; glVertex3i(x+1,y+1,z) ; glVertex3i(x+1,y+1,z+1) ; glEnd() ; } void voxel2(int x,int y,int z) { glPushMatrix() ; glTranslatef(x+0.5F,y+0.5F,z+0.5F) ; glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurRouge(0.5F)) ; glutSolidCube(1.0) ; glPopMatrix() ; } void ligneVoxels1(int xi,int yi,int zi,int xf,int yf,int zf) { int dx,dy,dz,i,xinc,yinc,zinc,c1,c2,x,y,z ; x = xi ; y = yi ; z = zi ; dx = xf - xi ; dy = yf - yi ; dz = zf - zi ; xinc = ( dx > 0 ) ? 1 : -1 ; yinc = ( dy > 0 ) ? 1 : -1 ; zinc = ( dz > 0 ) ? 1 : -1 ; dx = abs(dx) ; dy = abs(dy) ; dz = abs(dz) ; voxel1(x,y,z) ; if ( ( dx > dy ) && ( dx > dz ) ) { c1 = c2 = dx / 2 ; for ( i = 1 ; i <= dx ; i++ ) { x += xinc ; c1 += dy ; int n = 0 ; if (c1 >= dx) { c1 -= dx ; n++ ; y += yinc ; } c2 += dz ; if (c2 >= dx) { c2 -= dx ; n++ ; z += zinc ; } voxel1(x,y,z) ; } } else if ( ( dy > dx ) && ( dy > dz ) ) { c1 = c2 = dy / 2 ; for ( i = 1 ; i <= dy ; i++ ) { y += yinc ; c1 += dx ; if ( c1 >= dy ) { c1 -= dy ; x += xinc ; } c2 += dz ; if ( c2 >= dy ) { c2 -= dy ; z += zinc ; } voxel1(x,y,z) ; } } else { c1 = c2 = dz / 2 ; for ( i = 1 ; i <= dz ; i++ ) { z += zinc ; c1 += dy ; if ( c1 >= dz ) { c1 -= dz ; y += yinc ; } c2 += dx ; if ( c2 >= dz ) { c2 -= dz ; x += xinc ; } voxel1(x,y,z) ; } } } void ligneVoxels2(int xi,int yi,int zi,int xf,int yf,int zf) { int dx,dy,dz,i,xinc,yinc,zinc,c1,c2,x,y,z ; x = xi ; y = yi ; z = zi ; dx = xf - xi ; dy = yf - yi ; dz = zf - zi ; xinc = ( dx > 0 ) ? 1 : -1 ; yinc = ( dy > 0 ) ? 1 : -1 ; zinc = ( dz > 0 ) ? 1 : -1 ; dx = abs(dx) ; dy = abs(dy) ; dz = abs(dz) ; voxel2(x,y,z) ; if ( ( dx > dy ) && ( dx > dz ) ) { c1 = c2 = dx / 2 ; for ( i = 1 ; i <= dx ; i++ ) { x += xinc ; c1 += dy ; int n = 0 ; if (c1 >= dx) { c1 -= dx ; n++ ; y += yinc ; } c2 += dz ; if (c2 >= dx) { c2 -= dx ; n++ ; z += zinc ; } voxel2(x,y,z) ; } } else if ( ( dy > dx ) && ( dy > dz ) ) { c1 = c2 = dy / 2 ; for ( i = 1 ; i <= dy ; i++ ) { y += yinc ; c1 += dx ; if ( c1 >= dy ) { c1 -= dy ; x += xinc ; } c2 += dz ; if ( c2 >= dy ) { c2 -= dy ; z += zinc ; } voxel2(x,y,z) ; } } else { c1 = c2 = dz / 2 ; for ( i = 1 ; i <= dz ; i++ ) { z += zinc ; c1 += dy ; if ( c1 >= dz ) { c1 -= dz ; y += yinc ; } c2 += dx ; if ( c2 >= dz ) { c2 -= dz ; x += xinc ; } voxel2(x,y,z) ; } } } void parcoursVoxels1(int xi,int yi,int zi,int xf,int yf,int zf,int lim) { int x = xi ; int y = yi ; int z = zi ; voxel1(x,y,z) ; float px =(float) x ; float py =(float) y ; float pz =(float) z ; float dx =(float) xf-xi ; float dy =(float) yf-yi ; float dz =(float) zf-zi ; int cp = 0 ; while ( ( ( x != xf ) || ( y != yf ) || ( z != zf ) ) && ( cp != lim ) ) { cp++ ; float max = 10e+10F ; int cas ; float dd = ( x-0.5F-px)/dx ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 1 ; max = dd ; } dd = ( x+0.5F-px)/dx ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 2 ; max = dd ; } dd = ( y-0.5F-py)/dy ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 3 ; max = dd ; } dd = ( y+0.5F-py)/dy ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 4 ; max = dd ; } dd = ( z-0.5F-pz)/dz ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 5 ; max = dd ; } dd = ( z+0.5F-pz)/dz ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 6 ; max = dd ; } px += max*dx ; py += max*dy ; pz += max*dz ; switch(cas) { case 1 : x-- ; break ; case 2 : x++ ; break ; case 3 : y-- ; break ; case 4 : y++ ; break ; case 5 : z-- ; break ; case 6 : z++ ; break ; } voxel1(x,y,z) ; } } void parcoursVoxels2(int xi,int yi,int zi,int xf,int yf,int zf,int lim) { int x = xi ; int y = yi ; int z = zi ; voxel2(x,y,z) ; float px =(float) x ; float py =(float) y ; float pz =(float) z ; float dx =(float) xf-xi ; float dy =(float) yf-yi ; float dz =(float) zf-zi ; int cp = 0 ; while ( ( ( x != xf ) || ( y != yf ) || ( z != zf ) ) && ( cp != lim ) ) { cp++ ; float max = 10e+10F ; int cas ; float dd = ( x-0.5F-px)/dx ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 1 ; max = dd ; } dd = ( x+0.5F-px)/dx ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 2 ; max = dd ; } dd = ( y-0.5F-py)/dy ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 3 ; max = dd ; } dd = ( y+0.5F-py)/dy ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 4 ; max = dd ; } dd = ( z-0.5F-pz)/dz ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 5 ; max = dd ; } dd = ( z+0.5F-pz)/dz ; if ( ( dd > 0.0F ) && ( dd <= max ) ) { cas = 6 ; max = dd ; } px += max*dx ; py += max*dy ; pz += max*dz ; switch(cas) { case 1 : x-- ; break ; case 2 : x++ ; break ; case 3 : y-- ; break ; case 4 : y++ ; break ; case 5 : z-- ; break ; case 6 : z++ ; break ; } voxel2(x,y,z) ; } } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix() ; manipulateurSouris(); manipulateurClavier(); glLineWidth(4.0) ; glColor4fv(couleurBleu()) ; glBegin(GL_LINES) ; glVertex3f(-8.5,-1.5,-2.5) ; glVertex3f(8.5,3.5,5.5) ; glEnd() ; glLineWidth(1.0) ; switch ( aff ) { case 1 : ligneVoxels1(-9,-2,-3,8,3,5); glEnable(GL_LIGHTING); ligneVoxels2(-9,-2,-3,8,3,5); glDisable(GL_LIGHTING); break ; case 2 : parcoursVoxels1(-9,-2,-3,8,3,5,1000); glEnable(GL_LIGHTING); parcoursVoxels2(-9,-2,-3,8,3,5,1000); glDisable(GL_LIGHTING); break ; case 3 : parcoursVoxels1(-9,-2,-3,8,3,5,lim); glEnable(GL_LIGHTING); parcoursVoxels2(-9,-2,-3,8,3,5,lim); glDisable(GL_LIGHTING); break ; } glPopMatrix() ; glFlush(); glutSwapBuffers(); } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostRedisplay(); else switch ( key ) { case 0x0D : lim = 0 ; aff = (aff+1)%4 ; glutPostRedisplay(); break; case 32 : lim = (lim+1)%40 ; glutPostRedisplay(); break; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(400,220); glutInitWindowPosition(50,50); glutCreateWindow("Une ligne de voxels"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-6.0,6.0,-6.0,6.0,-500.0,500.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutMainLoop(); return(0); }