// Computergraphik I // Prof. Dr. Juergen Doellner // Sommersemester 2001 // // Rahmenprogramm fuer Aufgabenzettel 8 #include "cgrobot.h" CGRobot::CGRobot() : pause_(false), constructed_(false), cameraBezier_(true), rootNode_(0) { // der komplette Szenengraph enthält nur exakt EINE Box Box* box = new Box(Vector(0,0,0), Vector(1,1,1)); LeafNode* leafBox = new LeafNode(box); // ein Finger modellieren fingerRotation_ = new Rotation(-1, Vector(0,0,1)); GroupNode* finger = GroupNode::shareNode(leafBox, 8, new Translation(Vector(1,0,0)), fingerRotation_); // Hand erstellen GroupNode* hand = GroupNode::shareNode(finger, 5, new Translation(Vector(0,0,1.2))); hand->setAttribute(0, new Translation(Vector(1,0.1,3))); hand->setAttribute(1, new Rotation(-90, Vector(0,1,0))); hand->setAttribute(2, new Scaling(Vector(1/5.8, 1/5.8, 1/5.8))); hand->setAttribute(3, new Color(0,0,1)); // Arm GroupNode* oberArm = new GroupNode; oberArm->setAttribute(0, new Scaling(Vector(1,0.3,3))); oberArm->setChildNode(0, leafBox); armRotation_ = new Rotation(45, Vector(1,0,0)); GroupNode* arm = new GroupNode; arm->setAttribute(0, armRotation_); arm->setAttribute(1, new Translation(Vector(0,1,0))); arm->setAttribute(2, new Scaling(Vector(0.6, 0.6, 0.6))); arm->setChildNode(0, oberArm); arm->setChildNode(1, hand); // beide Arme GroupNode* arme = GroupNode::shareNode(arm, 2, new Translation(Vector(1.6,0,0))); arme->setAttribute(0, new Translation(Vector(-1.1,0,-1))); arme->setAttribute(1, new Color(0, 1, 1)); // Sensoren GroupNode* sensor = new GroupNode; sensor->setAttribute(0, new Scaling(Vector(0.2, 0.2, 0.1))); sensor->setChildNode(0, leafBox); sensorColor_ = new Color(1,0,0); GroupNode* sensoren = GroupNode::shareNode(sensor, 2, new Translation(Vector(0.75,0,0))); sensoren->setAttribute(0, new Translation(Vector(0,1,0.5))); sensoren->setAttribute(1, sensorColor_); // Gesicht GroupNode* auge = new GroupNode; auge->setAttribute(0, new Scaling(Vector(0.2, 0.2, 0.1))); auge->setChildNode(0, leafBox); GroupNode* augen = GroupNode::shareNode(auge, 2, new Translation(Vector(0.5,0,0))); augen->setAttribute(0, new Translation(Vector(0.1,0.7,1))); augen->setAttribute(1, new Color(0,0,0)); GroupNode* mund = new GroupNode; mund->setAttribute(0, new Translation(Vector(0.1,0.2,1))); mund->setAttribute(1, new Scaling(Vector(0.8, 0.1, 0.1))); mund->setAttribute(2, new Color(1,0,0)); mund->setChildNode(0, leafBox); GroupNode* nase = new GroupNode; nase->setAttribute(0, new Translation(Vector(0.4,0.5,1))); nase->setAttribute(1, new Scaling(Vector(0.2, 0.2, 0.2))); nase->setAttribute(2, new Color(1,1,0)); nase->setChildNode(0, leafBox); // Kopf GroupNode* kopf = new GroupNode; kopf->setChildNode(0, leafBox); kopf->setChildNode(1, sensoren); kopf->setChildNode(2, augen); kopf->setChildNode(3, mund); kopf->setChildNode(4, nase); kopf->setAttribute(0, new Translation(Vector(-0.35,1,-0.35))); kopf->setAttribute(1, new Scaling(Vector(0.7,0.7,0.7))); kopf->setAttribute(2, new Color(1,1,1)); // Standfläche GroupNode* boden = new GroupNode; boden->setChildNode(0, leafBox); boden->setAttribute(0, new Translation(Vector(-1,-3,-1))); boden->setAttribute(1, new Scaling(Vector(2, 0.1, 2))); boden->setAttribute(2, new Color(0,1,1)); // Fuss GroupNode* fuss = new GroupNode; fuss->setChildNode(0, leafBox); fuss->setAttribute(0, new Translation(Vector(-0.35,-3,-0.35))); fuss->setAttribute(1, new Scaling(Vector(0.7, 2, 0.7))); fuss->setAttribute(2, new Color(0,0,1)); // Rumpf GroupNode* rumpf = new GroupNode; rumpf->setChildNode(0, leafBox); rumpf->setAttribute(0, new Scaling(Vector(1,2,1))); rumpf->setAttribute(1, new Translation(Vector(-0.5,-0.5,-0.5))); rumpf->setAttribute(2, new Color(0.5,0.5,0.5)); // Roboter zusammensetzen camera_ = new Camera(Vector(-2,-2,3)); GroupNode* robot = new GroupNode; robot->setAttribute(0, camera_); robot->setChildNode(0, arme); robot->setChildNode(1, kopf); robot->setChildNode(2, fuss); robot->setChildNode(3, boden); robot->setChildNode(4, rumpf); rootNode_ = robot; // Szene fertig gebaut, onTimer darf ab jetzt eingreifen constructed_ = true; } void CGRobot::onInit() { glClearColor(0, 0, 0, 1); glEnable(GL_DEPTH_TEST); // Setze die Beleuchtungseinstellungen: static const float specular[] = { 1.0, 1.0, 1.0, 1.0 }; static const float shininess[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_SPECULAR, specular); glMaterialfv(GL_FRONT, GL_SHININESS, shininess); static const float lightPosition[] = { 1.5, 1.5, -3.5, 0.0 }; glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glShadeModel(GL_SMOOTH); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glEnable(GL_NORMALIZE); } void CGRobot::onDraw() { // Loesche den Farb-Speicher und den Speicher // fuer den Tiefen-Test! glClearColor(0.8, 0.8, 0.8, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /**** überschrieben durch Camera !!! ****/ // Wir sind 3 Einheiten vom Nullpunkt entfernt (auf // der z-Achse) und schauen direkt in den Nullpunkt. // Die y-Achse soll nach oben zeigen: /* glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, 3, // Position 0, 0, 0, // auf diesen Punkt wird geschaut 0, 1, 0); // Up-Vektor zeigt nach oben */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.5, 1.5, -1.5, 1.5, 1, 6); // Zeichne den Szene-Graphen if(rootNode_) { rootNode_->traverse(); } // Nicht vergessen!!! swapBuffers(); } void CGRobot::onSize(unsigned int newWidth, unsigned int newHeight) { glViewport(0, 0, newWidth - 1, newHeight - 1); } void CGRobot::onKey(unsigned char key) { const unsigned char ESC = 27; const unsigned char SPACE = ' '; switch (key) { case SPACE: pause_ = !pause_; break; case 'c': case 'C': cameraBezier_ = !cameraBezier_; break; case ESC: exit(0); } } void CGRobot::onTimer() { if (!constructed_) return; static int nTimerTicks = 0; // durchgängiger Timer nTimerTicks++; // Bewegung if(!pause_) { // Kamera bewegen if (cameraBezier_) { // auf Bezierkurve const int bezierPoints = 4; Vector v[bezierPoints] = { Vector(-2,-2, 3), Vector( 5, 2, 7), Vector( 3, 5,-5), Vector(-2,-2,-2) }; static double t = 0.01; static double incT = 0.01; if (t<0.01 || t>0.99) incT = -incT; t += incT; camera_->setFrom(bezier(v,bezierPoints,t)); } else { // auf vordefinierter Bahn double angle = nTimerTicks*3.1415926/180.0; camera_->setFrom(Vector(-3*sin(angle), 3*sin(angle), 3*cos(angle))); } // Finger öffnen/schliessen static double fingerAngleInc = -1; double angle = fingerRotation_->getAngle(); if (angle == 340 || angle == 0) fingerAngleInc = -fingerAngleInc; fingerRotation_->setAngle(angle+fingerAngleInc); // Arme bewegen static double armAngleInc = -1; angle = armRotation_->getAngle(); if (angle == 80 || angle == 30) armAngleInc = -armAngleInc; armRotation_->setAngle(angle+armAngleInc); } // blinken delete sensorColor_; if (nTimerTicks % 2 == 0) sensorColor_ = new Color(1,0,0); else sensorColor_ = new Color(1,0.8,0.8); needsRedraw(); } int main(int argc, char* argv[]) { cout << "SPACE toggles rotation" << endl << "ESC quits the program" << endl; CGRobot CGRobot; CGRobot.start(argc, argv, "CGRobot, Stephan Brumme, 702544", CGApplication::ColorBuffer | CGApplication::DepthBuffer | CGApplication::DoubleBuffer, 25); return 0; }