#include #include "Go.h" #include "GoGlutInterface.h" #include "GoSphere.h" // // Clip volume. // #define X_MIN -2.0 #define X_MAX 2.0 #define Y_MIN -2.0 #define Y_MAX 2.0 #define Z_MIN -2.0 #define Z_MAX 2.0 class GoSelectSphereDemo : public GoGlutInterface { public: GoSphere *sphere; int sphereSelected; int xStart; int yStart; double blueSphereTx, blueSphereTy; double blueSphereTxSave, blueSphereTySave; double redSphereTx, redSphereTy; double redSphereTxSave, redSphereTySave; double greenSphereTx, greenSphereTy; double greenSphereTxSave, greenSphereTySave; enum { NO_SPHERE, BLUE_SPHERE, RED_SPHERE, GREEN_SPHERE }; GoSelectSphereDemo(void) { // // Create a sphere to illustrate this demo. // sphere = new GoSphere(1.0, 16, 16); // // Turn on LIGHT_0 // go->light(Go::LIGHT_0, true); go->light(Go::LIGHT_0, Go::DIRECTIONAL, 1.0, 1.0, 1.0); // // Initialize sphere translations. // blueSphereTx = 0.0; blueSphereTy = 0.0; redSphereTx = 0.0; redSphereTy = 0.0; greenSphereTx = 0.0; greenSphereTy = 0.0; } // // Interface render method. // void render(void) { go->clear(Go::IMAGE); draw(); swap(); } // // Interface resized method. // void resized(int width, int height) { // // Setup projection matrix. // go->push(Go::MATRIX_MODE); go->matrixMode(Go::PROJECTION); go->identity(); ortho(); go->pop(Go::MATRIX_MODE); } // // Interface mousePressed method. // void mousePressed(int x, int y) { int width = go->width(); int height = go->height(); // // Save values that will be used to track the // mouse in the mouseDragged() method. // xStart = x; yStart = y; // // Save projection matrix. // go->push(Go::PROJECTION); // // Setup projection matrix for select mode. // go->push(Go::MATRIX_MODE); go->matrixMode(Go::PROJECTION); go->identity(); go->select(x, height - y, 5.0, 5.0); ortho(); go->pop(Go::MATRIX_MODE); // // Draw in select mode. // go->push(Go::RENDER_MODE); go->renderMode(Go::SELECTION); draw(); go->pop(Go::RENDER_MODE); // // Restore projection matrix. // go->pop(Go::PROJECTION); // // Find out what was selected. // sphereSelected = NO_SPHERE; double zMax = -1.0; for(GoSelection *selection = go->selection(); selection != NULL; selection = selection->next()) { // // If current selection has a larger Z-value, then select it. // if(selection->zMax() > zMax) { zMax = selection->zMax(); int stackSize = selection->stackSize(); for(int i = 0; i < stackSize; i++) { sphereSelected = selection->name(i); } } } // // Clear selection for next time. // go->clear(Go::SELECTION); // // Save translation of selected sphere. // switch(sphereSelected) { case BLUE_SPHERE: blueSphereTxSave = blueSphereTx; blueSphereTySave = blueSphereTy; break; case RED_SPHERE: redSphereTxSave = redSphereTx; redSphereTySave = redSphereTy; break; case GREEN_SPHERE: greenSphereTxSave = greenSphereTx; greenSphereTySave = greenSphereTy; break; } } // // Interface mouseDragged method. // void mouseDragged(int x, int y) { int xEnd = x; int yEnd = y; double width = go->width(); double height = go->height(); // // Translate selected sphere. // switch(sphereSelected) { case BLUE_SPHERE: if(width > height) { blueSphereTx = blueSphereTxSave + (xEnd - xStart) / width * (X_MAX - X_MIN) * width / height; blueSphereTy = blueSphereTySave - (yEnd - yStart) / height * (Y_MAX - Y_MIN); } else { blueSphereTx = blueSphereTxSave + (xEnd - xStart) / width * (X_MAX - X_MIN); blueSphereTy = blueSphereTySave - (yEnd - yStart) / height * (Y_MAX - Y_MIN) * height / width; } break; case RED_SPHERE: if(width > height) { redSphereTx = redSphereTxSave + (xEnd - xStart) / width * (X_MAX - X_MIN) * width / height; redSphereTy = redSphereTySave - (yEnd - yStart) / height * (Y_MAX - Y_MIN); } else { redSphereTx = redSphereTxSave + (xEnd - xStart) / width * (X_MAX - X_MIN); redSphereTy = redSphereTySave - (yEnd - yStart) / height * (Y_MAX - Y_MIN) * height / width; } break; case GREEN_SPHERE: if(width > height) { greenSphereTx = greenSphereTxSave + (xEnd - xStart) / width * (X_MAX - X_MIN) * width / height; greenSphereTy = greenSphereTySave - (yEnd - yStart) / height * (Y_MAX - Y_MIN); } else { greenSphereTx = greenSphereTxSave + (xEnd - xStart) / width * (X_MAX - X_MIN); greenSphereTy = greenSphereTySave - (yEnd - yStart) / height * (Y_MAX - Y_MIN) * height / width; } break; } // // Redisplay. // rerender(); } // // Render the spheres. // void draw(void) { go->push(Go::MATRIX); go->name(BLUE_SPHERE); go->translate(blueSphereTx, blueSphereTy + 0.5, 0.0); go->color(0, 0, 1); sphere->renderWire(go); go->translate(-blueSphereTx, -blueSphereTy, 0.0); go->name(RED_SPHERE); go->translate(redSphereTx - 0.5, redSphereTy - 0.5, 0.0); go->color(1, 0, 0); sphere->renderSolid(go); go->translate(-redSphereTx, -redSphereTy, 0.0); go->name(GREEN_SPHERE); go->translate(greenSphereTx + 1.0, greenSphereTy, 0.0); go->color(0, 1, 0); sphere->renderSolid(go); go->pop(Go::MATRIX); } // // Setup projection matrix. // void ortho() { int width = go->width(); int height = go->height(); if(width > height) { go->ortho(X_MIN * width / height, X_MAX * width / height, Y_MIN, Y_MAX, Z_MIN, Z_MAX); } else { go->ortho(X_MIN, X_MAX, Y_MIN * height / width, Y_MAX * height / width, Z_MIN, Z_MAX); } } }; int main(int argc, char *argv[]) { // // Glut setup. // GoGlutInterface::init(&argc, argv); GoGlutInterface::windowSize(400, 300); // // Create select sphere demo. // new GoSelectSphereDemo(); GoGlutInterface::mainLoop(); return(0); }