/* 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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#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);
}