//TESINA MAN //modello di uomo composto di: // 1)primitive glutSolid // per le quali sono gia' definite le normali ai vertici per illuminazione. // 2)per i cilindri usero' le quadriche di GLU. //Illuminazione + rimozione parti nascoste //Disegno gerarchico di un uomo. // riga di comando per compilare e linkare sotto Linux Mandrake 8.0 // gcc -o man3 man3.c -L/usr/X11R6/lib -lX11 -lGL -lGLU -lglut # include # include # include # include # include //INIZIO DICHIARAZIONE VARIABILI GLOBALI //usero' tutte variabili globali per: // parametri movimenti // parametri luci // indici Display Lists //dimensione finestra iniziale GLint w0=650, h0=650; //tipo proiezione ( 0 = parallela ; 1 = prospettica ). GLint proiez=1; GLint left=-30,right=30,bottom=-30,top=30,frontplane=20,backplane=100000; //Adattamento dimensioni finestre GLint x,y; //dimensioni intere finestra di proiezione scelta GLint larghezza,altezza; //dimensioni effettive correnti della finestra GLfloat ydivisox; //View Point GLint VPx=0,VPy=0,VPz=120; //Light Source Point GLint LSPx=0,LSPy=0,LSPz=200; //Light Color GLfloat R=0.0,G=0.8,B=0.8; //indici display lists GLuint piedeEcaviglia, stincoEginocchio, cosciaEgluteo, bacino, panciaEtorace, manoEpolso, avambraccioEgomito, bicipideEspalla, colloEtesta; //parametri per movimenti //rotazioni intorno asse x inizializzate tutte a 0 GLint cavsinx=0, cavdesx=0, ginsinx=0, gindesx=0, gamsinx=0, gamdesx=0, panciax=0, collox=0, spalladesx=0, spallasinx=0, gomdesx=0, gomsinx=0, polsodesx=0, polsosinx=0; //rotazioni intorno asse z GLint panciaz=0, colloz=0, spalladesz=0, spallasinz=0, polsodesz=0,polsosinz=0, gamsinz=0, gamdesz=0; //rotazioni intorno asse y GLint panciay=0, colloy=0, spalladesy=0, spallasiny=0; //angolo di rotazione intorno all'asse y //che da direzione di corsa o camminata. //inizializzato a 0, //vuol dire che all'inizio l'omino guarda in direzione e verso dell'asse z. GLint direzione=0; //FINE DICHIARAZIONE VARIABILI GLOBALI //IN "DefDisplayLists" DEFINISCO TUTTE LE DISPLAY LISTS //CHE DISEGNANO LE VARIE PARTI DELL'UOMO. void DefDisplayLists() { //dichiaro puntatori a strutture quadriche GLU usate per i cilindri //necessari (per ora solo) per bacino e torace GLUquadricObj *bac,*tor,*bic,*avam,*coscia,*stinco; //servono solo alle display lists che li usano //HO GIA' DEFINITO IL PUNTO DI VISTA!!!!! //LA MATRICE GL_MODELVIEW COSTRUITA NON E' PIU' UNITARIA!!!!!!!! //DEVO USARE PUSH E POP per usare per ogni primitiva la stessa!!!! glMatrixMode(GL_MODELVIEW); //per essere certi che sia attiva la GL_MODELVIEW //piede e caviglia solidali fra loro //caviglia sfera con centro nell'origine per poterla ruotare facilmente!!! //raggio caviglia 0.3 //dimensioni parallelepipedo piede 1.9 , 0.35 , 0.9 rispettivamente lungo x,y,z. //costruisco piede e caviglia piedeEcaviglia=glGenLists(1); glNewList(piedeEcaviglia,GL_COMPILE); glPushMatrix(); glutSolidSphere(0.3,10,10); //disegna sfera caviglia //ora disegno piede glTranslatef(-0.75,-0.4,0.0); glScalef(1.9,0.35,0.9); glutSolidCube(1.0); glPopMatrix(); glEndList(); //costruisco stinco e ginocchio altezza=5.4 stincoEginocchio=glGenLists(1); glNewList(stincoEginocchio,GL_COMPILE); glPushMatrix(); //il ginocchio e' sfera centrata nell'origine //per poterlo ruotare facilmente!!!!! glutSolidSphere(0.5,10,10); //disegna sfera ginocchio //disegno stinco stinco=gluNewQuadric(); glTranslatef(0.0,-0.3,0.0); glRotatef(90,1.0,0.0,0.0); //glutSolidCone(0.5,4.5,30,30); gluCylinder(stinco,0.5,0.25,4.5,20,20); gluDeleteQuadric(stinco); glPopMatrix(); glEndList(); //costruisco coscia e gluteo. altezza=5.3 cosciaEgluteo=glGenLists(1); glNewList(cosciaEgluteo,GL_COMPILE); glPushMatrix(); glutSolidSphere(0.7,20,20);//disegno sfera gluteo coscia=gluNewQuadric(); glTranslatef(0.0,-0.5,0.0); glRotatef(90,1.0,0.0,0.0); gluCylinder(coscia,0.7,0.5,4,20,20); gluDeleteQuadric(coscia); glPopMatrix(); glEndList(); //costruisco collo e testa altezza=3.8 colloEtesta=glGenLists(1); glNewList(colloEtesta,GL_COMPILE); glPushMatrix(); glutSolidSphere(0.6,10,10); //collo glTranslatef(0.0,1.8,0.0); glScalef(1.0,1.4,0.7); glutSolidSphere(1,20,20); //testa glTranslatef(0.0,0.0,0.5); glutSolidCone(0.3,2.0,20,20); //naso glPopMatrix(); glEndList(); //costruisco bacino (fisso) a cui attachero' glutei di sotto e pancia di sopra bacino=glGenLists(1); glNewList(bacino,GL_COMPILE); glPushMatrix(); bac=gluNewQuadric(); //crea o alloca memoria per una quadrica glTranslatef(0.0,-0.5,0.0); //per centrare bacino nell'origine glRotatef(90,-1.0,0.0,0.0); gluCylinder(bac,1.5,1.6,1.0,20,20); gluDeleteQuadric(bac); glPopMatrix(); glEndList(); //costruisco pancia e torace //sfera pancia centrata nell'origine panciaEtorace=glGenLists(1); glNewList(panciaEtorace,GL_COMPILE); glPushMatrix(); glutSolidSphere(1.5,20,20); //e' la pancia, fatta con una sfera, //sara' incastonata in ugual misura nel bacino e nel torace. //centrata nell'origine dara' movimenti fra bacino e torace. tor=gluNewQuadric(); //crea memoria per quadrica cilindro torace glTranslatef(0.0,0.5,0.0); glRotatef(90,-1.0,0.0,0.0); gluCylinder(tor,1.6,2.0,3.0,20,20); glTranslatef(0.0,0.0,3.0); glutSolidCone(2.0,0.5,20,20); gluDeleteQuadric(tor); glPopMatrix(); glEndList(); //costruisco bicipide e spalla, altezza=3.1 bicipideEspalla=glGenLists(1); glNewList(bicipideEspalla,GL_COMPILE); glPushMatrix(); glutSolidSphere(0.6,10,10); bic=gluNewQuadric(); glTranslatef(0.0,-0.5,0.0); glRotatef(90,1.0,0.0,0.0); gluCylinder(bic,0.6,0.5,2.0,20,20); gluDeleteQuadric(bic); glPopMatrix(); glEndList(); //costruisco avambraccio e gomito, altezza=2.9 avambraccioEgomito=glGenLists(1); glNewList(avambraccioEgomito,GL_COMPILE); glPushMatrix(); glutSolidSphere(0.5,10,10); avam=gluNewQuadric(); glTranslatef(0.0,-0.4,0.0); glRotatef(90,1.0,0.0,0.0); gluCylinder(avam,0.5,0.4,2.0,20,20); gluDeleteQuadric(avam); glPopMatrix(); glEndList(); //costruisco mano e polso manoEpolso=glGenLists(1); glNewList(manoEpolso,GL_COMPILE); glPushMatrix(); glutSolidSphere(0.4,10,10); glTranslatef(0.0,-1.05,0.0); glScalef(0.3,1.5,1.0); glutSolidCube(1); glPopMatrix(); glEndList(); } //le parti dell'uomo sono disegnate ferme e tutte in loro coordinate, //con sfere articolazioni centrate nell'origine delle loro coordinate! //FINE DISEGNO PARTI UOMO CON DISPLAY LISTS //INIZIALIZZAZIONE GENERICA void init(void) { glClearColor(0.0,0.0,0.0,0.0); //da colore con cui pulire lo sfondo glClearDepth(1);//sceglie valore di clear per la profondita' //RIM. PARTI NASCOSTE glEnable(GL_DEPTH_TEST); //rende attivo il depth buffer glEnable(GL_CULL_FACE); //per i poliedri considera solo facce visibili } //FINE INIZIALIZZAZIONE GENERICA //"Reshape" DEFINISCE LA PROIEZIONE CON LA QUALE VEDO L'UOMO. void reshape(GLint w,GLint h) { //larghezza e altezza contengono dimensioni finestra effettiva sul monitor larghezza=w; //larghezza e altezza sono 2 variabili globali altezza=h; //x e y variabili globali intere che contengono dimensioni finestra scelta x=right-left; //sempre un quadrato e' la finestra per ora y=top-bottom; //quindi x=y ydivisox=(GLfloat)y/x; //operazione su reali , in campana! In genere vale 1 //w e h variabili locali intere che contengono dimensioni finestra effettiva //NON VOGLIO MAI DISEGNO DEFORMATO!!!!!! glViewport ( 0 , 0 , (GLsizei) w, (GLsizei) w*ydivisox); //segue def. vista prospettica a semi-piramide o parallela a parallelepipedo glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (proiez==1) glFrustum(left,right,bottom,top,frontplane,backplane); else glOrtho(left,right,bottom,top,frontplane,backplane); glMatrixMode(GL_MODELVIEW); } //FINE DEF. PROIEZIONE //COSTRUZIONE LUCI void CostruiscoLuci() { //dichiaro e definisco vettori reali in coordinate omogenee per GLfloat lightZeroPosition[] = {LSPx, LSPy, LSPz, 1.0}; //posizione sorgente luce 0 GLfloat lightZeroColor[] = {R,G,B,0.0}; //colore sorg. luce 0 (RGBA) glShadeModel(GL_SMOOTH); //si illuminazione glEnable(GL_SMOOTH); //abilita smooth shading glEnable(GL_LIGHTING); //attiva illuminazione glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor); glEnable(GL_LIGHT0); //accende la luce 0 } //FINE COSTRUZIONE LUCI //DEFINIZIONE PUNTO DI VISTA //la GL_MODELVIEW non sara' piu' unitaria!! void PuntoDiVista() { glMatrixMode (GL_MODELVIEW); glLoadIdentity (); //coordinate di vista VRC = coordinate del mondo WC /* viewing transformation */ gluLookAt (VPx, VPy, VPz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //ho specificato:PRP(osservatore);CW(center window);VUP(vector up).Tutto in WC! //VPN assunta da PRP a CW } //FINE DEFINIZIONE PUNTO DI VISTA //DEFINIZIONE FUNZIONI NODI ALBERO CON MOVIMENTI PARAMETRIZZATI void DisegnoCavigliaSinistra() //disegna caviglia sinistra e restante parte di sotto { glPushMatrix(); glTranslatef(0.0,-4.9,0.0); glRotatef(cavsinx,1.0,0.0,0.0); glRotatef(90.0,0.0,1.0,0.0); glCallList(piedeEcaviglia); glPopMatrix(); } void DisegnoCavigliaDestra() { glPushMatrix(); glTranslatef(0.0,-4.9,0.0); glRotatef(cavdesx,1.0,0.0,0.0); glRotatef(90.0,0.0,1.0,0.0); glCallList(piedeEcaviglia); glPopMatrix(); } void DisegnoGinocchioSinistro() { glPushMatrix(); glTranslatef(0.0,-4.9,0.0); glRotatef(ginsinx,1.0,0.0,0.0); glCallList(stincoEginocchio); glPushMatrix(); DisegnoCavigliaSinistra(); glPopMatrix(); glPopMatrix(); } void DisegnoGinocchioDestro() { glPushMatrix(); glTranslatef(0.0,-4.9,0.0); glRotatef(gindesx,1.0,0.0,0.0); glCallList(stincoEginocchio); glPushMatrix(); DisegnoCavigliaDestra(); glPopMatrix(); glPopMatrix(); } void DisegnoGambaDestra() { glPushMatrix(); glTranslatef(-0.75,-1.0,0.0); //per posizionare gamba destra rispetto al bacino glRotatef(gamdesx,1.0,0.0,0.0); glRotatef(gamdesz,0.0,0.0,1.0); glCallList(cosciaEgluteo); glPushMatrix(); DisegnoGinocchioDestro(); //disegna ginocchio destro e la restante parte di sotto glPopMatrix(); glPopMatrix(); } void DisegnoGambaSinistra() { glPushMatrix(); glTranslatef(0.75,-1.0,0.0); //per posizionare gamba sinistra rispetto al bacino glRotatef(gamsinx,1.0,0.0,0.0); glRotatef(gamsinz,0.0,0.0,1.0); glCallList(cosciaEgluteo); glPushMatrix(); DisegnoGinocchioSinistro(); glPopMatrix(); glPopMatrix(); } void DisegnoTesta() //disegno collo e testa. { glPushMatrix(); glTranslatef(0.0,4.4,0.0); glRotatef(collox,1.0,0.0,0.0); glRotatef(colloy,0.0,1.0,0.0); glRotatef(colloz,0.0,0.0,1.0); glCallList(colloEtesta); glPopMatrix(); } void DisegnoPolsoSinistro() { glPushMatrix(); glTranslatef(0.0,-2.7,0.0); glRotatef(polsosinz,0.0,0.0,1.0); glCallList(manoEpolso); glPopMatrix(); } void DisegnoPolsoDestro() { glPushMatrix(); glTranslatef(0.0,-2.7,0.0); glRotatef(polsodesz,0.0,0.0,1.0); glCallList(manoEpolso); glPopMatrix(); } void DisegnoGomitoDestro() { glPushMatrix(); glTranslatef(0.0,-2.85,0.0); glRotatef(gomdesx,1.0,0.0,0.0); glCallList(avambraccioEgomito); glPushMatrix(); DisegnoPolsoDestro(); //e tutto quello che c'c' sotto glPopMatrix(); glPopMatrix(); } void DisegnoGomitoSinistro() { glPushMatrix(); glTranslatef(0.0,-2.85,0.0); glRotatef(gomsinx,1.0,0.0,0.0); glCallList(avambraccioEgomito); glPushMatrix(); DisegnoPolsoSinistro(); glPopMatrix(); glPopMatrix(); } void DisegnoBraccioDestro() { glPushMatrix(); glTranslatef(-2.5,3.0,0.0); glRotatef(spalladesx,1.0,0.0,0.0); glRotatef(spalladesy,0.0,1.0,0.0); glRotatef(spalladesz,0.0,0.0,1.0); glCallList(bicipideEspalla); glPushMatrix(); DisegnoGomitoDestro(); glPopMatrix(); glPopMatrix(); } void DisegnoBraccioSinistro() { glPushMatrix(); glTranslatef(2.5,3.0,0.0); glRotatef(spallasinx,1.0,0.0,0.0); glRotatef(spallasiny,0.0,1.0,0.0); glRotatef(spallasinz,0.0,0.0,1.0); glCallList(bicipideEspalla); glPushMatrix(); DisegnoGomitoSinistro(); glPopMatrix(); glPopMatrix(); } void DisegnoTorace() //disegna dalla pancia in su { glPushMatrix(); glTranslatef(0.0,1.0,0.0); glRotatef(panciax,1.0,0.0,0.0); glRotatef(panciay,0.0,1.0,0.0); glRotatef(panciaz,0.0,0.0,1.0); glCallList(panciaEtorace); glPushMatrix(); DisegnoTesta(); //disegna testa e collo glPopMatrix(); glPushMatrix(); DisegnoBraccioDestro(); glPopMatrix(); glPushMatrix(); DisegnoBraccioSinistro(); glPopMatrix(); glPopMatrix(); } void DisegnoSopraBacino() { glPushMatrix(); DisegnoTorace(); //disegna pancia e torace e tutto il resto della parte superiore glPopMatrix(); } void DisegnoSottoBacino() { glPushMatrix(); DisegnoGambaSinistra(); //disegno gamba sinistra glPopMatrix(); glPushMatrix(); DisegnoGambaDestra(); //disegno gamba destra glPopMatrix(); } //FUNZIONE RADICE DI DISEGNO GERARCHICO void DisegnoUomo() { glColor3f(1.0,1.0,1.0); //colore con cui disegno (bianco) glMatrixMode(GL_MODELVIEW); //gia' contiene traformazioni che ci portano in coordinate di vista! glPushMatrix(); glCallList(bacino); //disegno bacino fisso, il cui baricentro e' nell'origine //del sistema di coordinate glPopMatrix(); glPushMatrix(); DisegnoSopraBacino(); glPopMatrix(); glPushMatrix(); DisegnoSottoBacino(); glPopMatrix(); } //FINE FUNZIONE RADICE DI DISEGNO GERARCHICO //INIZIO DISEGNO void display(void) { glClear(GL_COLOR_BUFFER_BIT); //init frame(color) buffer tutto nero //aggiunto da me rispetto ai lucidi per vedere bene glClear(GL_DEPTH_BUFFER_BIT); //inizializza z-buffer glPushMatrix(); glRotatef(direzione,0.0,1.0,0.0); //da direzione dell'omino ruotando intorno asse y DisegnoUomo(); glPopMatrix(); glutSwapBuffers(); //scambia contenuto FrameBuffer e DoubleBuffer } //FINE DISEGNO //mette l'omino dritto,fermo,in piedi, cioe' sull'attenti. void Attenti() { cavsinx=0; cavdesx=0; ginsinx=0; gindesx=0; gamsinx=0; gamdesx=0; panciax=0; collox=0; spalladesx=0; spallasinx=0; gomdesx=0; gomsinx=0; polsodesx=0; polsosinx=0; panciaz=0; colloz=0; spalladesz=0; spallasinz=0; polsodesz=0; polsosinz=0; gamdesz=0; gamsinz=0; panciay=0; colloy=0; spalladesy=0; spallasiny=0; } //FUNZIONI PER ANIMAZIONI E SPOSTAMENTI RIGIDI void Salta() { GLint i; //dichiaro una variabile per i cicli Attenti(); //metto omino in posizione di partenza //fase 1 salita for(i=1;i<=20;i++)//mi piego sulle ginocchia per caricare la spinta { gamdesx-=2; gamsinx-=2; ginsinx+=4; gindesx+=4; cavsinx-=2; cavdesx-=2; // 2*3.14159/180=0.0349 glTranslatef(0.0,-(9.8*(cos((i-1)*0.0349)-cos(i*0.0349))),0.0); display(); } //fase 2 salita for(i=10;i>=1;i--) //spinta in alto, ancora piedi a terra { gamdesx+=4; gamsinx+=4; ginsinx-=8; gindesx-=8; cavsinx+=4; cavdesx+=4; spalladesz-=9; spallasinz+=9; // 4*3.14159/180=0.0698 glTranslatef(0.0,(9.8*(cos((i-1)*0.0698)-cos(i*0.0698))),0.0); display(); } //fase 3 salita for(i=1;i<=10;i++) //distacco da terra { //continua a salire ruotando le braccia di altri 90 gradi spalladesz-=9; spallasinz+=9; cavsinx+=3; cavdesx+=3; glTranslatef(0.0,0.3,0.0); display(); } //fase 4 salita for(i=1;i<=10;i++) //continua inerzia verso l'alto, ruotano solo le caviglie { cavsinx+=3; cavdesx+=3; glTranslatef(0.0,0.3,0.0); display(); } //fase 5 salita for(i=1;i<=10;i++) //salgo ancora senza che nulla si muovi { glTranslatef(0.0,0.3,0.0); display(); } //fase 6 salita for(i=1;i<=10;i++) //salgo ancora ma piano piano { glTranslatef(0.0,0.2,0.0); display(); } for(i=1;i<=5;i++) //fermo in aria { display(); } //fase 1 discesa for(i=1;i<=10;i++) //scendo piano piano { glTranslatef(0.0,-0.2,0.0); display(); } //fase 2 discesa for(i=1;i<=10;i++) //scendo piu' veloce senza che nulla si muovi { glTranslatef(0.0,-0.3,0.0); display(); } //fase 3 discesa for(i=1;i<=20;i++) //discesa finale con caviglie che si preparano ad atterraggio { spalladesz+=9; spallasinz-=9; cavsinx-=3; cavdesx-=3; glTranslatef(0.0,-0.3,0.0); display(); } } void Cammina() //max angolo fra gambe e' 24 gradi //gamba che indietreggia fa 1 grado a ciclo { GLint i,np; //variabili usate per i cicli GLint anggam=1,anggin=4,angspal=1; GLfloat trasl=9.8*sin(1*3.14/180); //l'angolo e' 1 gradi Attenti(); //metto omino in posizione di partenza //seguono 2 cicli per portare camminata a regime da posizione Attenti() //la prima gamba ad andare avanti e' la destra //gamba destra dritta verticale //gamba sinistra dritta verticale for(i=1;i<=4;i++) { spallasinx-=angspal; spalladesx+=angspal; gamsinx+=anggam; gamdesx-=anggam; gindesx+=anggin; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba sinistra dritta e dietro di 4 gradi //gamba destra avanti di 4 gradi con ginocchio indietro di 16 gradi for(i=1;i<=8;i++) { spallasinx-=angspal; spalladesx+=angspal; gamsinx+=anggam; gamdesx-=anggam; gindesx-=anggin/2; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //ciclo FOR per camminata a regime for(np=1;np<=3;np++) //provo con 3 passi { //gamba destra avanti di 12 gradi //gamba sinistra dietro di 12 gradi for(i=1;i<=8;i++) //FOR 1 { spallasinx+=angspal; spalladesx-=angspal; gamdesx+=anggam; //anggam=1 gamsinx-=anggam; ginsinx+=anggin; //anggin=4 glTranslatef( //3.14159/180=0.0174 trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba destra dritta e avanti di 4 gradi //gamba sinistra dietro di 4 gradi con ginocchio indietro di 32 gradi for(i=1;i<=8;i++) //FOR 2 { spallasinx+=angspal; spalladesx-=angspal; gamdesx+=anggam; gamsinx-=anggam; ginsinx-=anggin/2; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba destra dritta e dietro di 4 gradi //gamba sinistra avanti di 4 gradi con ginocchio indietro di 16 gradi for(i=1;i<=8;i++) //FOR 3 ( = FOR 2 ) { spallasinx+=angspal; spalladesx-=angspal; gamdesx+=anggam; gamsinx-=anggam; ginsinx-=anggin/2; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba destra dietro di 12 gradi //gamba sinistra avanti di 12 gradi //ADESSO TRE CICLI UGUALI MA A GAMBE INVERTITE //gamba sinistra avanti di 12 gradi //gamba destra dietro di 12 gradi for(i=1;i<=8;i++) //FOR 4 { spallasinx-=angspal; spalladesx+=angspal; gamsinx+=anggam; //anggam=1 gamdesx-=anggam; gindesx+=anggin; //anggin=4 glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba sinistra dritta e avanti di 4 gradi //gamba destra dietro di 4 gradi con ginocchio indietro di 32 gradi for(i=1;i<=8;i++) //FOR 5 { spallasinx-=angspal; spalladesx+=angspal; gamsinx+=anggam; gamdesx-=anggam; gindesx-=anggin/2; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba sinistra dritta e dietro di 4 gradi //gamba destra avanti di 4 gradi con ginocchio indietro di 16 gradi for(i=1;i<=8;i++) //FOR 6 ( = FOR 5 ) { spallasinx-=angspal; spalladesx+=angspal; gamsinx+=anggam; gamdesx-=anggam; gindesx-=anggin/2; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba sinistra dietro di 12 gradi //gamba destra avanti di 12 gradi }//FINE FOR camminata a regime //ora ci vanno due cicli per riportare omino sull'Attenti(). //gamba destra avanti di 12 gradi dritta //gamba sinistra dietro di 12 gradi dritta for(i=1;i<=8;i++) { spallasinx+=angspal; spalladesx-=angspal; gamdesx+=anggam; //anggam=1 gamsinx-=anggam; ginsinx+=anggin/2; //anggin=4 glTranslatef( //3.14159/180=0.0174 trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba destra dritta e avanti di 4 gradi //gamba sinistra dietro di 4 gradi con ginocchio indietro di 32 gradi for(i=1;i<=4;i++) { spallasinx+=angspal; spalladesx-=angspal; gamdesx+=anggam; gamsinx-=anggam; ginsinx-=anggin; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } } //fine funzione Cammina() //FUNZIONE CORRI void Corri() { //provare ad usare solo numeri interi per maggiore velocita' di calcolo, //quindi piu' fluidita' nei movimenti GLint i,np; //variabili usate per i cicli GLint anggam=4,anggin=4,angspal=4; GLfloat trasl=9.7*sin(4*3.14/180); //l'angolo e' 4 gradi //omino dritto sull'Attenti() spalladesx=+2; spallasinx=-2; gomdesx=-6; gomsinx=-6; panciax=0; gamdesx=-2; //max angolo fra coscie destra e sinistra e' 60 gindesx=0; //max angolo fra coscia e stinco e' 50, il minimo e' 20. gamsinx=+2; ginsinx=+6; //angolo ginocchi va da 20 a 50 display(); //ho disegnato primo movimento dell'omino che si avvia a correre //cicli for per portare corsa a regime for(i=1;i<=7;i++) { gamsinx+=anggam; //anggam = 4 gradi gamdesx-=anggam; ginsinx+=8; //anggin = 2 gradi spalladesx+=angspal; spallasinx-=angspal; gomdesx-=12; gomsinx-=12; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //ciclo FOR per corsa a regime for(np=1;np<=3;np++) //3 passi di corsa { //gamba destra avanti di 30 gradi con ginocchio a 0 gradi //gamba sinistra dietro di 30 gradi con ginocchio a +60 gradi for(i=1;i<=15;i++) { gamdesx+=anggam; //anggam = 4 gradi gamsinx-=anggam; gindesx+=anggin; //anggin = 4 gradi ginsinx-=anggin; spallasinx+=angspal; spalladesx-=angspal; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } //gamba sinistra avanti di 30 gradi con ginocchio a 0 gradi cioe' dritto //gamba destra dietro di 30 gradi con ginocchio a 60 gradi for(i=1;i<=15;i++) { gamsinx+=anggam; //anggam = 4 gradi gamdesx-=anggam; ginsinx+=anggin; //anggin = 4 gradi gindesx-=anggin; spalladesx+=angspal; spallasinx-=angspal; glTranslatef( trasl*sin(direzione*0.0174), 0.0, trasl*cos(direzione*0.0174) ); display(); } }//fine ciclo FOR corsa a regime //devo riportarmi sull'Attenti() //gamba destra avanti di 30 gradi con ginocchio a 0 gradi //gamba sinistra dietro di 30 gradi con ginocchio a +60 gradi for(i=1;i<=10;i++) { gamdesx+=3; //ginocchio destro rimane dritto gamsinx-=3; ginsinx-=6; gomdesx+=9; gomsinx+=9; spallasinx+=3; spalladesx-=3; glTranslatef( trasl*0.8*sin(direzione*0.0174), 0.0, trasl*0.8*cos(direzione*0.0174) ); display(); } } //Funzioni movimenti rigidi void TraslaIndietro() { glTranslatef(//3.14159/180=0.0174 15*sin(-direzione*0.0174), 0.0, -15*cos(direzione*0.0174) ); glutPostRedisplay(); } void TraslaAvanti() { glTranslatef(//3.14159/180=0.0174 15*sin(direzione*0.0174), 0.0, 15*cos(direzione*0.0174) ); glutPostRedisplay(); } void RuotaADestra() { direzione=(direzione-15)%360; glutPostRedisplay(); } void RuotaASinistra() { direzione=(direzione+15)%360; glutPostRedisplay(); } void Ruota180() { direzione-=180; glutPostRedisplay(); } void Allarga() { left-=5; right+=5; bottom-=5; top+=5; reshape(larghezza,altezza); glutPostRedisplay(); } void Restringi() { left+=5; right-=5; bottom+=5; top-=5; reshape(larghezza,altezza); glutPostRedisplay(); } void CambiaProiezione() { proiez=(proiez+1)%2; reshape(larghezza,altezza); glutPostRedisplay(); } //funzione gestione menu pulsante sinistro del mouse void Animazioni(int value) { switch (value) { case 1: Salta(); break; case 2: Corri(); break; case 3: Cammina(); break; } } //funzione gestione menu pulsante destro del mouse void Rigidi(int value) { switch (value) { case 1: TraslaIndietro(); break; case 2: TraslaAvanti(); break; case 3: RuotaADestra(); break; case 4: RuotaASinistra(); break; case 5: Ruota180(); break; case 6: Allarga(); break; case 7: Restringi(); break; case 8: CambiaProiezione(); break; default: break; } } //USO TASTIERA PER MOVIMENTI ARTICOLAZIONI SEMPLICI //DEFINISCO FUNZIONE "keyboard" CHE CONTROLLA USO TASTIERA void keyboard(unsigned char key, int x, int y) //x e y danno pos. mouse nella finestra //key e' il tasto premuto { switch (key) {//destra,sinistra,dietro,avanti sempre rispetto all'uomo disegnato case 'e': polsosinz=(polsosinz+3)%90; //ruota polso sinistro verso interno glutPostRedisplay(); break; case 'r': polsosinz=(polsosinz-3)%90; //ruota polso sinistro verso esterno glutPostRedisplay(); break; case 't': polsodesz=(polsodesz+3)%90; //ruota polso destro verso interno glutPostRedisplay(); break; case 'y': polsodesz=(polsodesz-3)%90; //ruota polso destro verso esterno glutPostRedisplay(); break; case 'q': gomdesx=(gomdesx-3)%180; //ruota gomito destro verso avanti glutPostRedisplay(); break; case 'w': gomdesx=(gomdesx+3)%180; //ruota gomito destro verso dietro glutPostRedisplay(); break; case '9': gomsinx=(gomsinx-3)%180; //ruota gomito sinistro verso avanti glutPostRedisplay(); break; case '0': gomsinx=(gomsinx+3)%180; //ruota gomito sinistro verso dietro glutPostRedisplay(); break; case '1': spallasinz=(spallasinz-3)%360; //ruota spalla sinistra verso l'alto glutPostRedisplay(); break; case '2': spallasinz=(spallasinz+3)%360; //ruota spalla sinistra verso il basso glutPostRedisplay(); break; case '3': spallasinx=(spallasinx+3)%360; //ruota spalla sinistra avanti glutPostRedisplay(); break; case '4': spallasinx=(spallasinx-3)%360; //ruota spalla sinistra indietro glutPostRedisplay(); break; case '5': spalladesz=(spalladesz-3)%360; //ruota spalla destra verso l'alto glutPostRedisplay(); break; case '6': spalladesz=(spalladesz+3)%360; //ruota spalla destra verso il basso glutPostRedisplay(); break; case '7': spalladesx=(spalladesx+3)%360; //ruota spalla destra avanti glutPostRedisplay(); break; case '8': spalladesx=(spalladesx-3)%360; //ruota spalla destra indietro glutPostRedisplay(); break; case 'u': gamsinx=(gamsinx-3)%180; //ruota gamba sinistra avanti glutPostRedisplay(); break; case 'i': gamsinx=(gamsinx+3)%180; //ruota gamba sinistra indietro glutPostRedisplay(); break; case 'v': gamsinz=(gamsinz-3)%90; //ruota gamba sinistra esterno glutPostRedisplay(); break; case 'b': gamsinz=(gamsinz+3)%90; //ruota gamba sinistra interno glutPostRedisplay(); break; case 'a': ginsinx=(ginsinx+3)%180; //ruota ginocchio sinistro indietro glutPostRedisplay(); break; case 's': ginsinx=(ginsinx-3)%180; //ruota ginocchio sinistro avanti glutPostRedisplay(); break; case 'g': cavsinx=(cavsinx+3)%180; //ruota caviglia sinistra indietro glutPostRedisplay(); break; case 'h': cavsinx=(cavsinx-3)%180; //ruota caviglia sinistra avanti glutPostRedisplay(); break; case 'o': gamdesx=(gamdesx-3)%180; //ruota gamba destra avanti glutPostRedisplay(); break; case 'p': gamdesx=(gamdesx+3)%180; //ruota gamba destra indietro glutPostRedisplay(); break; case 'x': gamdesz=(gamdesz+3)%90; //ruota gamba destra verso l'esterno glutPostRedisplay(); break; case 'c': gamdesz=(gamdesz-3)%90; //ruota gamba destra verso interno glutPostRedisplay(); break; case 'd': gindesx=(gindesx+3)%180; //ruota ginocchio destro indietro glutPostRedisplay(); break; case 'f': gindesx=(gindesx-3)%180; //ruota ginocchio destro avanti glutPostRedisplay(); break; case 'j': cavdesx=(cavdesx+3)%180; //ruota caviglia destra indietro glutPostRedisplay(); break; case 'k': cavdesx=(cavdesx-3)%180; //ruota caviglia destra avanti glutPostRedisplay(); break; case 'z': Attenti(); glutPostRedisplay(); break; default: break; } } //DEFINISCO FUNZIONE "specialkeyboard" SEMPRE PER CONTROLLO TASTIERA void specialkeyboard(int key, int x, int y) //key e' il tasto premuto { switch (key) {//destra,sinistra,dietro,avanti sempre rispetto all'uomo disegnato case GLUT_KEY_F1: colloz=(colloz+3)%90; //piega collo verso sinistra glutPostRedisplay(); break; case GLUT_KEY_F2: colloz=(colloz-3)%90; //piega collo verso destra glutPostRedisplay(); break; case GLUT_KEY_F3: collox=(collox+3)%90; //piega collo in avanti glutPostRedisplay(); break; case GLUT_KEY_F4: collox=(collox-3)%90; //piega collo indietro glutPostRedisplay(); break; case GLUT_KEY_F5: colloy=(colloy+3)%90; //ruota collo verso sinistra glutPostRedisplay(); break; case GLUT_KEY_F6: colloy=(colloy-3)%90; //ruota collo verso destra glutPostRedisplay(); break; case GLUT_KEY_F7: panciaz=(panciaz+3)%50; //ruota busto verso destra glutPostRedisplay(); break; case GLUT_KEY_F8: panciaz=(panciaz-3)%50; //ruota busto verso sinistra glutPostRedisplay(); break; case GLUT_KEY_F9: panciay=(panciay+3)%90; //ruota pancia verso sinistra glutPostRedisplay(); break; case GLUT_KEY_F10: panciay=(panciay-3)%90; //ruota pancia verso destra glutPostRedisplay(); break; case GLUT_KEY_F11: panciax=(panciax+3)%180; //piega pancia avanti glutPostRedisplay(); break; case GLUT_KEY_F12: panciax=(panciax-3)%180; //piega pancia indietro glutPostRedisplay(); break; case GLUT_KEY_RIGHT: //l'omino ruota alla sua destra direzione=(direzione-3)%360; glutPostRedisplay(); break; case GLUT_KEY_LEFT: //l'omino ruota alla sua sinistra direzione=(direzione+3)%360; glutPostRedisplay(); break; case GLUT_KEY_DOWN: //l'omino e' traslato indietro immobile glTranslatef(//3.14159/180=0.0174 sin(-direzione*0.0174), 0.0, -cos(direzione*0.0174) ); glutPostRedisplay(); break; case GLUT_KEY_UP: glTranslatef(//3.14159/180=0.0174 sin(direzione*0.0174), 0.0, cos(direzione*0.0174) ); glutPostRedisplay(); break; default: break; } } //INIZIO "main" DI CONTROLLO GENERALE int main(int argc, char** argv) { GLint id_menu_animazioni,id_menu_rigidi; glutInit(&argc,argv); glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB); //la precedente dichiara si useranno 2 buffer //Double Buffering //per evitare sfarfallio //ed anche uso z-buffer per rimozione parti nascoste glutInitWindowSize(w0,h0); glutInitWindowPosition(0,0); glutCreateWindow("Man"); init(); PuntoDiVista(); CostruiscoLuci(); DefDisplayLists(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(specialkeyboard); id_menu_animazioni=glutCreateMenu(Animazioni); glutAddMenuEntry("Salta" , 1 ); //animato glutAddMenuEntry("Corri" , 2 ); //animato glutAddMenuEntry("Cammina" , 3 ); //animato glutAttachMenu(GLUT_LEFT_BUTTON); id_menu_rigidi=glutCreateMenu(Rigidi); //movimenti omino rigidi e istantanei glutAddMenuEntry("Trasla indietro" , 1 ); //non animata glutAddMenuEntry("Trasla avanti" , 2 ); //non animata glutAddMenuEntry("Ruota a destra" , 3 ); //non animata glutAddMenuEntry("Ruota a sinistra" , 4 ); //non animata glutAddMenuEntry("Ruota di 180 gradi", 5 ); //non animata glutAddMenuEntry("Allarga visuale" , 6 ); //allarga finestra su frontplane glutAddMenuEntry("Restringi visuale" , 7 ); //restringe finestra su frontplane glutAddMenuEntry("Cambia proiezione" , 8 ); //prospettiche o ortogonali glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); //dice di far ciclare il main in un loop infinito, //ogni volta i parametri di movimento saranno diversi quindi vedro' movimento //rispetto alla precedente iterazione. return 0; } //FINE "main" DI CONTROLLO GENERALE