#include "main.h" Model *myModel; int output=0; int caveButtonChange1 = 0, caveButtonChange2 = 0, caveButtonChange3 = 0; int caveButton1=0, caveButton2=0, caveButton3=0; void main() { CAVEInit(); CAVEInitApplication(initScene, 0); CAVEFrameFunction (frameFunc, 0); CAVEDisplay( drawScene, 0); while (!CAVEgetbutton(CAVE_ESCKEY)) { sginap(0); } CAVEExit(); } void initScene() { GLfloat light0_ambient[] = { .1, .1, .1, 1.0 }; GLfloat light0_diffuse[] = { .8, 0.8, 0.8, 1.0 }; GLfloat light0_specular[] = { 0.4, 0.4, 0.5, 1.0 }; GLfloat light0_position[] = {10.0, 10.0, 00.0, 1.0 }; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular); glLightfv(GL_LIGHT0, GL_POSITION, light0_position); glEnable(GL_AUTO_NORMAL); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glShadeModel(GL_SMOOTH); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); myModel=new Model; myModel->init(); } void drawScene() { float p[3]; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glColor3f(1.0, 1.0, 0.0); //draw hand indicator CAVEGetPosition(CAVE_WAND, &p[0]); glPushMatrix(); glTranslatef(p[0], p[1], p[2]); myModel->drawBall(); glPopMatrix(); //draw the tinkertoys glPushMatrix(); myModel->draw(0); glPopMatrix(); if(output) myModel->writefile(); } void frameFunc () { static Disk *closestd; //for next stick static Stick *nextOnes; //for next stick static Stick *closest; //for next disk static Disk *nextOne; //for next disk static int usedHole; float p[3], angle[3]; int recalculate=0; float length; caveButton1=CAVEBUTTON1; caveButton2=CAVEBUTTON2; caveButton3=CAVEBUTTON3; caveButtonChange1 = CAVEButtonChange( 1 ); caveButtonChange2 = CAVEButtonChange( 2 ); caveButtonChange3 = CAVEButtonChange( 3 ); CAVEGetPosition(CAVE_WAND, &p[0]); CAVEGetOrientation(CAVE_WAND, &angle[0]); //ADD STICK if(caveButtonChange1==1) { recalculate=1; //pushed button 1, find closest disk and add stick closestd=myModel->findClosestDisk(p); //add stick if we can support one if(!(closestd->full())) { //get the length for this stick length=distance(p, closestd->center); nextOnes=new Stick; //nextOnes->setLength(length); usedHole=closestd->setNextStick(nextOnes, p); //check for collision starting at root myModel->collideCheckNewStick(nextOnes); } } //ADD DISK if(caveButtonChange2==1) { recalculate=1; //pushed button 2, find closest stick closest=myModel->findClosestStick(p); //add disk if we can support one if(!(closest->nextExists())) { nextOne=new Disk; closest->setNextDisk(nextOne); } } //ORIENT NEW DISK if(caveButtonChange2==0 && caveButton2) { recalculate=1; //holding down button 2, orient last disk created if(angle[2]>45 || angle[2]<-45) { nextOne->orient=1; } else { nextOne->orient=0; } } //ORIENT NEW STICK if(caveButtonChange1==0 && caveButton1) { recalculate=1; //holding down button 1, put last stick created in closest hole closestd->nextStick[usedHole]=NULL; usedHole=closestd->setNextStick(nextOnes, p); //get the length for this stick length=distance(p, closestd->center); //nextOnes->setLength(length); //check for collision starting at root myModel->removeColliding(nextOnes); myModel->collideCheckNewStick(nextOnes); } if(caveButtonChange3==1) { //we are going to rotate a disk, find the closest one closestd=myModel->findClosestDisk(p); } //ROTATE EXISTING DISK if(caveButtonChange3==0 && caveButton3) { recalculate=1; //holding down button 3, rotate the disk we selected if(closestd->orient==0) { closestd->orient0_angle=-angle[2]; } else { closestd->orient1_angle=-angle[2]; } //check for collision myModel->collideCheckRotated(closestd); } //START THE MOTION if(caveButton1 && caveButton2 && caveButton3) { if(myModel->inMotion) myModel->inMotion=0; else myModel->inMotion=1; if(myModel->inMotion) { myModel->startMotion(); } } if(myModel->inMotion) { myModel->move(); recalculate=1; } if(recalculate) { glPushMatrix(); glLoadIdentity(); myModel->draw(1); glPopMatrix(); //now check if things in the collisionList are still colliding //myModel->checkList(); } if(CAVEgetbutton(CAVE_AKEY)) output=1; }