void keySelect(unsigned char key, int x, int y) { // escape key if ((key == 27) || (key == 'x')) { // close everything close(); // exit application exit(0); } // option 1: if (key == '1') { bool useTexture = object->getUseTexture(); object->setUseTexture(!useTexture); } // option 2: if (key == '2') { bool useWireMode = object->getWireMode(); object->setWireMode(!useWireMode, true); } // option 3: if (key == '3') { cColorf color = cColorf(1.0, 0.0, 0.0); object->setCollisionDetectorProperties(collisionTreeDisplayLevel, color, true); bool show = object->getShowCollisionDetector(); object->setShowCollisionDetector(!show, true); } // option -: if (key == '-') { collisionTreeDisplayLevel--; if (collisionTreeDisplayLevel < 0) { collisionTreeDisplayLevel = 0; } cColorf color = cColorf(1.0, 0.0, 0.0); object->setCollisionDetectorProperties(collisionTreeDisplayLevel, color, true); object->setShowCollisionDetector(true, true); } // option +: if (key == '+') { collisionTreeDisplayLevel++; cColorf color = cColorf(1.0, 0.0, 0.0); object->setCollisionDetectorProperties(collisionTreeDisplayLevel, color, true); object->setShowCollisionDetector(true, true); } }
void keySelect(unsigned char key, int x, int y) { // escape key if ((key == 27) || (key == 'x')) { // close everything close(); // exit application exit(0); } // option 1: if (key == '1') { object->setUseTexture(true); } // option 2: if (key == '2') { object->setUseTexture(false); } // option 3: if (key == '3') { object->setWireMode(true); } // option 4: if (key == '4') { object->setWireMode(false); } // option 5: if (key == '5') { object->setShowNormals(true); object->setNormalsProperties(0.05, cColorf(1.0, 0.0, 0.0)); } // option 6: if (key == '6') { object->setShowNormals(false); } }
int main(int argc, char* argv[]) { //----------------------------------------------------------------------- // INITIALIZATION //----------------------------------------------------------------------- printf ("\n"); printf ("-----------------------------------\n"); printf ("CHAI 3D\n"); printf ("Demo: 52-GEL-duck\n"); printf ("Copyright 2003-2010\n"); printf ("-----------------------------------\n"); printf ("\n\n"); printf ("Keyboard Options:\n\n"); printf ("[1] - Show GEL Skeleton\n"); printf ("[2] - Hide GEL Skeleton\n"); printf ("[x] - Exit application\n"); printf ("\n\n"); // parse first arg to try and locate resources resourceRoot = string(argv[0]).substr(0,string(argv[0]).find_last_of("/\\")+1); //----------------------------------------------------------------------- // 3D - SCENEGRAPH //----------------------------------------------------------------------- // create a new world. world = new cWorld(); // set the background color of the environment // the color is defined by its (R,G,B) components. world->setBackgroundColor(0.0, 0.0, 0.0); world->setBackgroundColor(1.0, 1.0, 1.0); // create a camera and insert it into the virtual world camera = new cCamera(world); world->addChild(camera); // position and oriente the camera // define a default position of the camera (described in spherical coordinates) cameraAngleH = 0; cameraAngleV = 45; cameraDistance = 2.5; updateCameraPosition(); // set the near and far clipping planes of the camera // anything in front/behind these clipping planes will not be rendered camera->setClippingPlanes(0.01, 10.0); // enable higher rendering quality because we are displaying transparent objects camera->enableMultipassTransparency(true); // create a light source and attach it to the camera light = new cLight(world); camera->addChild(light); // attach light to camera light->setEnabled(true); // enable light source light->setPos(cVector3d( 2.0, 0.5, 1.0)); // position the light source light->setDir(cVector3d(-2.0, 0.5, 1.0)); // define the direction of the light beam light->setDirectionalLight(false); light->m_ambient.set(0.5, 0.5, 0.5); light->m_diffuse.set(0.7, 0.7, 0.7); light->m_specular.set(0.9, 0.9, 0.9); //----------------------------------------------------------------------- // 2D - WIDGETS //----------------------------------------------------------------------- // create a 2D bitmap logo logo = new cBitmap(); // add logo to the front plane camera->m_front_2Dscene.addChild(logo); // load a "chai3d" bitmap image file bool fileload; fileload = logo->m_image.loadFromFile(RESOURCE_PATH("resources/images/chai3d.bmp")); if (!fileload) { #if defined(_MSVC) fileload = logo->m_image.loadFromFile("../../../bin/resources/images/chai3d.bmp"); #endif } // position the logo at the bottom left of the screen (pixel coordinates) logo->setPos(10, 10, 0); // scale the logo along its horizontal and vertical axis logo->setZoomHV(0.4, 0.4); // here we replace all black pixels (0,0,0) of the logo bitmap // with transparent black pixels (0, 0, 0, 0). This allows us to make // the background of the logo look transparent. logo->m_image.replace( cColorb(0, 0, 0), // original RGB color cColorb(0, 0, 0, 0) // new RGBA color ); // enable transparency logo->enableTransparency(true); //----------------------------------------------------------------------- // HAPTIC DEVICES / TOOLS //----------------------------------------------------------------------- // create a haptic device handler handler = new cHapticDeviceHandler(); // get access to the first available haptic device handler->getDevice(hapticDevice, 0); // retrieve information about the current haptic device cHapticDeviceInfo info; if (hapticDevice) { hapticDevice->open(); info = hapticDevice->getSpecifications(); } // desired workspace radius of the cursor cursorWorkspaceRadius = 0.8; // read the scale factor between the physical workspace of the haptic // device and the virtual workspace defined for the tool workspaceScaleFactor = cursorWorkspaceRadius / info.m_workspaceRadius; // define a scale factor between the force perceived at the cursor and the // forces actually sent to the haptic device deviceForceScale = 0.005 * (info.m_maxForceStiffness / workspaceScaleFactor); // define a force scale factor for the current haptic device. const double FORCE_REFERENCE = 10.0; deviceForceScale = info.m_maxForce / FORCE_REFERENCE; // create a large sphere that represents the haptic device deviceRadius = 0.12; device = new cShapeSphere(deviceRadius); world->addChild(device); device->m_material.m_ambient.set(0.4, 0.4, 0.4, 0.7); device->m_material.m_diffuse.set(0.7, 0.7, 0.7, 0.7); device->m_material.m_specular.set(1.0, 1.0, 1.0, 0.7); device->m_material.setShininess(100); stiffness = 40; //----------------------------------------------------------------------- // COMPOSE THE VIRTUAL SCENE //----------------------------------------------------------------------- // create a world which supports deformable object defWorld = new cGELWorld(); world->addChild(defWorld); world->setPos(-1.5, 0.0, -0.1); world->rotate(cVector3d(0,1,0), cDegToRad(30)); //----------------------------------------------------------------------- // COMPOSE THE WATER //----------------------------------------------------------------------- ground = new cGELMesh(world); ground->m_useMassParticleModel = true; defWorld->m_gelMeshes.push_back(ground); cGELMassParticle::default_mass = 0.010; cGELMassParticle::default_kDampingPos = 0.4; cGELMassParticle::default_gravity.set(0,0,0); int u,v; int RESOLUTION = 15; double SIZE = 3.5; for (v=0; v<RESOLUTION; v++) { for (u=0; u<RESOLUTION; u++) { double px, py, tu, tv; // compute the position of the vertex px = SIZE / (double)RESOLUTION * (double)u - (SIZE/2.0); py = SIZE / (double)RESOLUTION * (double)v - (SIZE/2.0); // create new vertex unsigned int index = ground->newVertex(px, py, level); cVertex* vertex = ground->getVertex(index); // compute texture coordinate tu = (double)u / (double)RESOLUTION; tv = (double)v / (double)RESOLUTION; vertex->setTexCoord(tu, tv); vertex->setColor(cColorf(1.0, 0.0, 0.1)); } } ground->buildVertices(); for (v=0; v<RESOLUTION; v++) { for (u=0; u<RESOLUTION; u++) { if ((u == 0) || (v == 0) || (u == (RESOLUTION-1)) || (v == (RESOLUTION-1))) { // create new vertex unsigned int index = ((v + 0) * RESOLUTION) + (u + 0); ground->m_gelVertices[index].m_massParticle->m_fixed = true; } } } cGELLinearSpring::default_kSpringElongation = 10.0; // [N/m] // Create a triangle based map using the above pixels for (v=0; v<(RESOLUTION-1); v++) { for (u=0; u<(RESOLUTION-1); u++) { // get the indexing numbers of the next four vertices unsigned int index00 = ((v + 0) * RESOLUTION) + (u + 0); unsigned int index01 = ((v + 0) * RESOLUTION) + (u + 1); unsigned int index10 = ((v + 1) * RESOLUTION) + (u + 0); unsigned int index11 = ((v + 1) * RESOLUTION) + (u + 1); // create two new triangles ground->newTriangle(index00, index01, index10); ground->newTriangle(index10, index01, index11); cGELMassParticle* m0 = ground->m_gelVertices[index00].m_massParticle; cGELMassParticle* m1 = ground->m_gelVertices[index01].m_massParticle; cGELMassParticle* m2 = ground->m_gelVertices[index10].m_massParticle; cGELLinearSpring* spring0 = new cGELLinearSpring(m0, m1); cGELLinearSpring* spring1 = new cGELLinearSpring(m0, m2); ground->m_linearSprings.push_back(spring0); ground->m_linearSprings.push_back(spring1); } } double transparencyLevel = 0.7; ground->setUseMaterial(true); ground->m_material.m_ambient.set(0.6, 0.6, 0.6, transparencyLevel); ground->m_material.m_diffuse.set(0.8, 0.8, 0.8, transparencyLevel); ground->m_material.m_specular.set(0.9, 0.9, 0.9, transparencyLevel); ground->setTransparencyLevel(transparencyLevel); ground->setUseTransparency(true); cTexture2D* textureGround = new cTexture2D(); ground->setTexture(textureGround); ground->setUseTexture(true, true); fileload = textureGround->loadFromFile(RESOURCE_PATH("resources/images/aqua.bmp")); if (!fileload) { #if defined(_MSVC) fileload = textureGround->loadFromFile("../../../bin/resources/images/aqua.bmp" ); #endif if (!fileload) { printf("Error - 3D Texture failed to load correctly.\n"); close(); return (-1); } } //----------------------------------------------------------------------- // COMPOSE SOME REFLEXION //----------------------------------------------------------------------- cGenericObject* reflexion = new cGenericObject(); world->addChild(reflexion); cMatrix3d rot; rot.set(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0); reflexion->setRot(rot); reflexion->addChild(defWorld); reflexion->setPos(0.0, 0.0, 2.0 * level); cGenericObject* reflexionTool = new cGenericObject(); reflexion->addChild(reflexionTool); reflexionTool->addChild(device); reflexionTool->setPos(0.0, 0.0, -0.5 * level); // Play with thse numbers carefully! defWorld->m_integrationTime = 0.001; // create a deformable mesh defObject = new cGELMesh(world); defWorld->m_gelMeshes.push_front(defObject); //----------------------------------------------------------------------- // BUILD THE DUCK! //----------------------------------------------------------------------- if (USE_SKELETON_MODEL) { fileload = createSkeletonMesh(defObject, RESOURCE_PATH("resources/models/ducky/duck-200.off"), RESOURCE_PATH("resources/models/ducky/duck-full.obj")); if (!fileload) { #if defined(_MSVC) fileload = createSkeletonMesh(defObject, "../../../bin/resources/models/ducky/duck-200.off", "../../../bin/resources/models/ducky/duck-full.obj"); #endif if (!fileload) { printf("Error - 3D Model failed to load correctly.\n"); close(); return (-1); } } } else { fileload = createTetGenMesh(defObject, RESOURCE_PATH("resources/models/ducky/duck-1200.off"), RESOURCE_PATH("resources/models/ducky/duck-green.obj")); if (!fileload) { #if defined(_MSVC) fileload = createTetGenMesh(defObject, "../../../bin/resources/models/ducky/duck-1200.off", "../../../bin/resources/models/ducky/duck-green.obj"); #endif if (!fileload) { printf("Error - 3D Model failed to load correctly.\n"); close(); return (-1); } } } //----------------------------------------------------------------------- // OPEN GL - WINDOW DISPLAY //----------------------------------------------------------------------- // initialize GLUT glutInit(&argc, argv); // retrieve the resolution of the computer display and estimate the position // of the GLUT window so that it is located at the center of the screen int screenW = glutGet(GLUT_SCREEN_WIDTH); int screenH = glutGet(GLUT_SCREEN_HEIGHT); int windowPosX = (screenW - WINDOW_SIZE_W) / 2; int windowPosY = (screenH - WINDOW_SIZE_H) / 2; // initialize the OpenGL GLUT window glutInitWindowPosition(windowPosX, windowPosY); glutInitWindowSize(WINDOW_SIZE_W, WINDOW_SIZE_H); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow(argv[0]); glutMouseFunc(mouseClick); glutMotionFunc(mouseMove); glutDisplayFunc(updateGraphics); glutKeyboardFunc(keySelect); glutReshapeFunc(resizeWindow); glutSetWindowTitle("CS 268 - Sonny Chan & Francois Conti - March 2009"); // create a mouse menu (right button) glutCreateMenu(menuSelect); glutAddMenuEntry("full screen", OPTION_FULLSCREEN); glutAddMenuEntry("window display", OPTION_WINDOWDISPLAY); glutAddMenuEntry("show skeleton", OPTION_SHOWSKELETON); glutAddMenuEntry("hide skeleton", OPTION_HIDESKELETON); glutAttachMenu(GLUT_RIGHT_BUTTON); //----------------------------------------------------------------------- // START SIMULATION //----------------------------------------------------------------------- // simulation in now running simulationRunning = true; // create a thread which starts the main haptics rendering loop cThread* hapticsThread = new cThread(); hapticsThread->set(updateHaptics, CHAI_THREAD_PRIORITY_HAPTICS); // start the main graphics rendering loop glutMainLoop(); // close everything close(); // exit return (0); }
void keySelect(unsigned char key, int x, int y) { // escape key if ((key == 27) || (key == 'x')) { // close everything close(); // exit application exit(0); } // option 1: if (key == '1') { // only enable/disable wireframe of one part of the tooth model bool useWireMode = ((cMesh*)(tooth->getChild(1)))->getWireMode(); ((cMesh*)(tooth->getChild(1)))->setWireMode(!useWireMode); } // option 2: if (key == '2') { bool showNormals = tooth->getShowNormals(); tooth->setShowNormals(!showNormals, true); tooth->setNormalsProperties(0.05, cColorf(1.0, 0.0, 0.0), true); } // option -: if (key == '-') { // decrease transparency level transparencyLevel = transparencyLevel - 0.1; if (transparencyLevel < 0.0) { transparencyLevel = 0.0; } // apply changes to tooth ((cMesh*)(tooth->getChild(1)))->setTransparencyLevel(transparencyLevel); ((cMesh*)(tooth->getChild(1)))->setUseTransparency(true); // if object is almost transparent, make it invisible if (transparencyLevel < 0.1) { ((cMesh*)(tooth->getChild(1)))->setShowEnabled(false, true); } } // option +: if (key == '+') { // increase transparency level transparencyLevel = transparencyLevel + 0.1; if (transparencyLevel > 1.0) { transparencyLevel = 1.0; } // apply changes to tooth ((cMesh*)(tooth->getChild(1)))->setTransparencyLevel(transparencyLevel); // make object visible if (transparencyLevel >= 0.1) { ((cMesh*)(tooth->getChild(1)))->setShowEnabled(true, true); } // disable transparency is transparency level is set to 1.0 if (transparencyLevel == 1.0) { ((cMesh*)(tooth->getChild(1)))->setUseTransparency(false); } } }
BOOL Cforce_shadingApp::InitInstance() { AfxEnableControlContainer(); #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif g_main_dlg = new Cforce_shadingDlg; m_pMainWnd = g_main_dlg; g_main_dlg->Create(IDD_force_shading_DIALOG,NULL); // Now we should have a display context to work with... // Create a world and set a white background color world = new cWorld(); world->setBackgroundColor(1.0,1.0,1.0); // Create a camera and set its position, look-at point, and orientation (up-direction) camera = new cCamera(world); int result = camera->set(cVector3d(0,0,4), cVector3d(0,0,0), cVector3d(0,1,0)); // Create, enable, and position a light source light = new cLight(world); light->setEnabled(true); light->setPos(cVector3d(4,1,0)); // Create a display for graphic rendering viewport = new cViewport(g_main_dlg->m_gl_area_hwnd, camera, false); // Create an octagonal prism... object = new cMesh(world); float d = 1.0; // Vertices forming an octagon in y=-1 plane object->newVertex(0.924*d, -1, -0.383*d); cVector3d norm(2,0,-1); norm.normalize(); object->getVertex(0)->setNormal(norm); object->newVertex(0.383*d, -1, -0.924*d); norm = cVector3d(1,0,-2); norm.normalize(); object->getVertex(1)->setNormal(norm); object->newVertex(-0.383*d, -1, -0.924*d); norm = cVector3d(-1,0,-2); norm.normalize(); object->getVertex(2)->setNormal(norm); object->newVertex(-0.924*d, -1, -0.383*d); norm = cVector3d(-2,0,-1); norm.normalize(); object->getVertex(3)->setNormal(norm); object->newVertex(-0.924*d, -1, 0.383*d); norm = cVector3d(-2,0,1); norm.normalize(); object->getVertex(4)->setNormal(norm); object->newVertex(-0.383*d, -1, 0.924*d); norm = cVector3d(-1,0,2); norm.normalize(); object->getVertex(5)->setNormal(norm); object->newVertex(0.383*d, -1, 0.924*d); norm = cVector3d(1,0,2); norm.normalize(); object->getVertex(6)->setNormal(norm); object->newVertex(0.924*d, -1, 0.383*d); norm = cVector3d(2,0,1); norm.normalize(); object->getVertex(7)->setNormal(norm); // Vertices forming an octagon in y=1 plane object->newVertex(0.924*d, 1, -0.383*d); norm = cVector3d(2,0,-1); norm.normalize(); object->getVertex(8)->setNormal(norm); object->newVertex(0.383*d, 1, -0.924*d); norm = cVector3d(1,0,-2); norm.normalize(); object->getVertex(9)->setNormal(norm); object->newVertex(-0.383*d, 1, -0.924*d); norm = cVector3d(-1,0,-2); norm.normalize(); object->getVertex(10)->setNormal(norm); object->newVertex(-0.924*d, 1, -0.383*d); norm = cVector3d(-2,0,-1); norm.normalize(); object->getVertex(11)->setNormal(norm); object->newVertex(-0.924*d, 1, 0.383*d); norm = cVector3d(-2,0,1); norm.normalize(); object->getVertex(12)->setNormal(norm); object->newVertex(-0.383*d, 1, 0.924*d); norm = cVector3d(-1,0,2); norm.normalize(); object->getVertex(13)->setNormal(norm); object->newVertex(0.383*d, 1, 0.924*d); norm = cVector3d(1,0,2); norm.normalize(); object->getVertex(14)->setNormal(norm); object->newVertex(0.924*d, 1, 0.383*d); norm = cVector3d(2,0,1); norm.normalize(); object->getVertex(15)->setNormal(norm); // "Bottom" triangles of each face object->newTriangle(5,6,13); object->newTriangle(6,7,14); object->newTriangle(7,0,15); object->newTriangle(0,1,8); object->newTriangle(1,2,9); object->newTriangle(2,3,10); object->newTriangle(3,4,11); object->newTriangle(4,5,12); // "Top" triangles of each face object->newTriangle(14,13,6); object->newTriangle(15,14,7); object->newTriangle(8,15,0); object->newTriangle(9,8,1); object->newTriangle(10,9,2); object->newTriangle(11,10,3); object->newTriangle(12,11,4); object->newTriangle(13,12,5); // Draw all triangles object->useCulling(false, true); // Show the normals we set object->showNormals(true, true); object->setNormalsProperties(1.0, cColorf(1.0,0,0), true); // Add the octagonal prism to the world world->addChild(object); // Create a soft, green material for the object cMaterial material1; material1.setStiffness(3.0); material1.m_ambient.set(0.0, 0.8, 0.0, 1.0); material1.m_diffuse.set(0.0, 0.8, 0.0, 1.0); material1.m_specular.set(1.0, 1.0, 1.0, 1.0); material1.setShininess(100.0); object->m_material = material1; // Initilize some variables world->computeGlobalPositions(); tool = 0; haptics_enabled = 0; return TRUE; }
int main(int argc, char* argv[]) { //----------------------------------------------------------------------- // INITIALIZATION //----------------------------------------------------------------------- printf ("\n"); printf ("-----------------------------------\n"); printf ("CHAI3D\n"); printf ("Demo: 13-primitives\n"); printf ("Copyright 2003-2012\n"); printf ("-----------------------------------\n"); printf ("\n\n"); printf ("Keyboard Options:\n\n"); printf ("[1] - Wireframe (ON/OFF)\n"); printf ("[x] - Exit application\n"); printf ("\n\n>\r"); //----------------------------------------------------------------------- // WORLD - CAMERA - LIGHTING //----------------------------------------------------------------------- // create a new world. world = new cWorld(); // set the background color of the environment world->m_backgroundColor.setBlack(); // create a camera and insert it into the virtual world camera = new cCamera(world); world->addChild(camera); // position and oriente the camera camera->set( cVector3d (1.4, 0.0, 0.6), // camera position (eye) cVector3d (0.0, 0.0, 0.0), // lookat position (target) cVector3d (0.0, 0.0, 1.0)); // direction of the (up) vector // set the near and far clipping planes of the camera // anything in front/behind these clipping planes will not be rendered camera->setClippingPlanes(0.01, 10.0); // Enable shadow casting camera->setUseShadowCasting(true); // create a light source light = new cSpotLight(world); // attach light to camera camera->addChild(light); // enable light source light->setEnabled(true); // position the light source light->setLocalPos( 0.0, 0.5, 0.0); // define the direction of the light beam light->setDir(-3.0,-0.5, 0.0); // enable this light source to generate shadows light->setShadowMapEnabled(true); //----------------------------------------------------------------------- // HAPTIC DEVICES / TOOLS //----------------------------------------------------------------------- // create a haptic device handler handler = new cHapticDeviceHandler(); // get access to the first available haptic device handler->getDevice(hapticDevice, 0); // retrieve information about the current haptic device cHapticDeviceInfo info = hapticDevice->getSpecifications(); // if the haptic devices carries a gripper, enable it to behave like a user switch hapticDevice->setEnableGripperUserSwitch(true); // create a 3D tool and add it to the world tool = new cToolCursor(world); world->addChild(tool); // connect the haptic device to the tool tool->setHapticDevice(hapticDevice); // initialize tool by connecting to haptic device tool->start(); // map the physical workspace of the haptic device to a larger virtual workspace. tool->setWorkspaceRadius(1.0); // define the radius of the tool (sphere) double toolRadius = 0.05; // define a radius for the tool tool->setRadius(toolRadius); // hide the device sphere. only show proxy. tool->setShowContactPoints(true, false); // enable if objects in the scene are going to rotate of translate // or possibly collide against the tool. If the environment // is entirely static, you can set this parameter to "false" tool->enableDynamicObjects(true); // read the scale factor between the physical workspace of the haptic // device and the virtual workspace defined for the tool double workspaceScaleFactor = tool->getWorkspaceScaleFactor(); // define a maximum stiffness that can be handled by the current // haptic device. The value is scaled to take into account the // workspace scale factor double stiffnessMax = info.m_maxLinearStiffness / workspaceScaleFactor; //----------------------------------------------------------------------- // CREATING OBJECTS //----------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////// // BASE ///////////////////////////////////////////////////////////////////////// // create a virtual mesh cMesh* base = new cMesh(); // add object to world world->addChild(base); // build mesh using a cylinder primitive cCreateCylinder(base, 0.01, 0.5, 64, 1, true, true, cVector3d(0.0, 0.0, 0.0), cMatrix3d(cDegToRad(0), cDegToRad(0), cDegToRad(0), C_EULER_ORDER_XYZ) ); // set material color base->m_material->setGrayGainsboro(); base->m_material->setStiffness(0.5 * stiffnessMax); // build collision detection tree base->createAABBCollisionDetector(toolRadius); ///////////////////////////////////////////////////////////////////////// // TEA POT ///////////////////////////////////////////////////////////////////////// // create a virtual mesh cMesh* teaPot = new cMesh(); // add object to world base->addChild(teaPot); // build mesh using a cylinder primitive cCreateTeaPot(teaPot, 0.5, cVector3d(0.0, 0.2, 0.12), cMatrix3d(cDegToRad(0), cDegToRad(0), cDegToRad(170), C_EULER_ORDER_XYZ) ); // set material properties teaPot->m_material->setRedDark(); teaPot->m_material->setStiffness(0.5 * stiffnessMax); // build collision detection tree teaPot->createAABBCollisionDetector(toolRadius); ///////////////////////////////////////////////////////////////////////// // GLASS ///////////////////////////////////////////////////////////////////////// // create a virtual mesh cMesh* glass = new cMesh(); // add object to world base->addChild(glass); // build mesh using a cylinder primitive cCreatePipe(glass, 0.15, 0.05, 0.06, 32, 1, cVector3d(0.0,-0.2, 0.0), cMatrix3d(cDegToRad(0), cDegToRad(0), cDegToRad(170), C_EULER_ORDER_XYZ) ); // set material color glass->m_material->setBlueCornflower(); glass->m_material->setStiffness(0.5 * stiffnessMax); // build collision detection tree glass->createAABBCollisionDetector(toolRadius); ///////////////////////////////////////////////////////////////////////// // CONE ///////////////////////////////////////////////////////////////////////// // create a virtual mesh cMesh* cone = new cMesh(); // add object to world base->addChild(cone); // build mesh using a cylinder primitive cCreateCone(cone, 0.15, 0.05, 0.01, 32, 1, false, true, cVector3d(0.25, 0.0, 0.0), cMatrix3d(cDegToRad(0), cDegToRad(0), cDegToRad(0), C_EULER_ORDER_XYZ) ); // set material color cone->m_material->setGreenForest(); cone->m_material->setStiffness(0.5 * stiffnessMax); // build collision detection tree cone->createAABBCollisionDetector(toolRadius); //----------------------------------------------------------------------- // WIDGETS //----------------------------------------------------------------------- // create a font cFont *font = NEW_CFONTCALIBRI20(); // create a label to display the haptic rate of the simulation labelHapticRate = new cLabel(font); labelHapticRate->m_fontColor.setBlack(); camera->m_frontLayer->addChild(labelHapticRate); // create a background cBackground* background = new cBackground(); camera->m_backLayer->addChild(background); // set background properties background->setCornerColors(cColorf(1.0, 1.0, 1.0), cColorf(1.0, 1.0, 1.0), cColorf(0.9, 0.9, 0.9), cColorf(0.9, 0.9, 0.9)); //----------------------------------------------------------------------- // OPEN GL - WINDOW DISPLAY //----------------------------------------------------------------------- // simulation in now running! simulationRunning = true; // initialize GLUT glutInit(&argc, argv); // retrieve the resolution of the computer display and estimate the position // of the GLUT window so that it is located at the center of the screen int screenW = glutGet(GLUT_SCREEN_WIDTH); int screenH = glutGet(GLUT_SCREEN_HEIGHT); int windowW = 0.7 * screenH; int windowH = 0.7 * screenH; int windowPosX = (screenW - windowH) / 2; int windowPosY = (screenH - windowW) / 2; // initialize the OpenGL GLUT window glutInitWindowPosition(windowPosX, windowPosY); glutInitWindowSize(windowW, windowH); if (USE_STEREO_DISPLAY) { glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_STEREO); camera->setUseStereo(true); } else { glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); camera->setUseStereo(false); } glutCreateWindow(argv[0]); glutDisplayFunc(updateGraphics); glutKeyboardFunc(keySelect); glutReshapeFunc(resizeWindow); glutSetWindowTitle("CHAI3D"); // create a mouse menu (right button) glutCreateMenu(menuSelect); glutAddMenuEntry("full screen", OPTION_FULLSCREEN); glutAddMenuEntry("window display", OPTION_WINDOWDISPLAY); glutAttachMenu(GLUT_RIGHT_BUTTON); //----------------------------------------------------------------------- // START SIMULATION //----------------------------------------------------------------------- // create a thread which starts the main haptics rendering loop cThread* hapticsThread = new cThread(); hapticsThread->start(updateHaptics, CTHREAD_PRIORITY_HAPTICS); // start the main graphics rendering loop glutTimerFunc(30, graphicsTimer, 0); glutMainLoop(); // close everything close(); // exit return (0); }
int loadHeightMap() { // create a texture file cTexture2D* newTexture = new cTexture2D(); world->addTexture(newTexture); // texture 2D bool fileload = newTexture->loadFromFile(RESOURCE_PATH("resources/images/map.bmp")); if (!fileload) { #if defined(_MSVC) fileload = newTexture->loadFromFile("../../../bin/resources/images/map.bmp"); #endif } if (!fileload) { printf("Error - Texture image failed to load correctly.\n"); close(); return (-1); } // get the size of the texture image (U and V) int texSizeU = newTexture->m_image.getWidth(); int texSizeV = newTexture->m_image.getHeight(); // check size of image if ((texSizeU < 1) || (texSizeV < 1)) { return (false); } // we look for the largest side int largestSide; if (texSizeU > texSizeV) { largestSide = texSizeU; } else { largestSide = texSizeV; } // The largest side of the map has a length of 1.0 // we now compute the respective size for 1 pixel of the image in world space. double size = 1.0 / (double)largestSide; // we will create an triangle based object. For centering puposes we // compute an offset for axis X and Y corresponding to the half size // of the image map. double offsetU = 0.5 * (double)texSizeU * size; double offsetV = 0.5 * (double)texSizeV * size; // For each pixel of the image, create a vertex int u,v; for (v=0; v<texSizeV; v++) { for (u=0; u<texSizeU; u++) { double px, py, tu, tv; // compute the height of the vertex cColorb color = newTexture->m_image.getPixelColor(u,v); double height = 0.1 * ((double)color.getR() + (double)color.getG() + (double)color.getB()) / (3.0 * 255.0); // compute the position of the vertex px = size * (double)u - offsetU; py = size * (double)v - offsetV; // create new vertex unsigned int index = object->newVertex(px, py, height); cVertex* vertex = object->getVertex(index); // compute texture coordinate tu = (double)u / texSizeU; tv = (double)v / texSizeV; vertex->setTexCoord(tu, tv); } } // Create a triangle based map using the above pixels for (v=0; v<(texSizeV-1); v++) { for (u=0; u<(texSizeU-1); u++) { // get the indexing numbers of the next four vertices unsigned int index00 = ((v + 0) * texSizeU) + (u + 0); unsigned int index01 = ((v + 0) * texSizeU) + (u + 1); unsigned int index10 = ((v + 1) * texSizeU) + (u + 0); unsigned int index11 = ((v + 1) * texSizeU) + (u + 1); // create two new triangles object->newTriangle(index00, index01, index10); object->newTriangle(index10, index01, index11); } } // apply texture to object object->setTexture(newTexture); object->setUseTexture(true); // compute normals object->computeAllNormals(true); // compute size of object object->computeBoundaryBox(true); cVector3d min = object->getBoundaryMin(); cVector3d max = object->getBoundaryMax(); // This is the "size" of the object cVector3d span = cSub(max, min); size = cMax(span.x, cMax(span.y, span.z)); // We'll center all vertices, then multiply by this amount, // to scale to the desired size. double scaleFactor = MESH_SCALE_SIZE / size; object->scale(scaleFactor); // compute size of object again object->computeBoundaryBox(true); // Build a collision-detector for this object, so // the proxy will work nicely when haptics are enabled. object->createAABBCollisionDetector(1.01 * proxyRadius, true, false); // set size of frame object->setFrameSize(0.2, true); // set size of normals object->setNormalsProperties(0.01, cColorf(1.0, 0.0, 0.0, 1.0), true); // render graphically both sides of triangles object->setUseCulling(false); // update global position object->computeGlobalPositions(); // success return (0); }
int main(int argc, char* argv[]) { //----------------------------------------------------------------------- // INITIALIZATION //----------------------------------------------------------------------- printf ("\n"); printf ("-----------------------------------\n"); printf ("CHAI 3D\n"); printf ("Demo: 25-cubic\n"); printf ("Copyright 2003-2009\n"); printf ("-----------------------------------\n"); printf ("\n\n"); printf ("Keyboard Options:\n\n"); printf ("[x] - Exit application\n"); printf ("\n\n"); // parse first arg to try and locate resources resourceRoot = string(argv[0]).substr(0,string(argv[0]).find_last_of("/\\")+1); //----------------------------------------------------------------------- // 3D - SCENEGRAPH //----------------------------------------------------------------------- // create a new world. world = new cWorld(); // set the background color of the environment // the color is defined by its (R,G,B) components. world->setBackgroundColor(1.0, 1.0, 1.0); // create a camera and insert it into the virtual world camera = new cCamera(world); world->addChild(camera); // position and oriente the camera camera->set( cVector3d (3.0, 0.0, 0.0), // camera position (eye) cVector3d (0.0, 0.0, 0.0), // lookat position (target) cVector3d (0.0, 0.0, 1.0)); // direction of the "up" vector // set the near and far clipping planes of the camera // anything in front/behind these clipping planes will not be rendered camera->setClippingPlanes(0.01, 10.0); // create a light source and attach it to the camera light = new cLight(world); camera->addChild(light); // attach light to camera light->setEnabled(true); // enable light source light->setPos(cVector3d( 2.0, 0.5, 1.0)); // position the light source light->setDir(cVector3d(-2.0, 0.5, 1.0)); // define the direction of the light beam //----------------------------------------------------------------------- // 2D - WIDGETS //----------------------------------------------------------------------- // create a 2D bitmap logo logo = new cBitmap(); // add logo to the front plane camera->m_front_2Dscene.addChild(logo); // load a "chai3d" bitmap image file bool fileload; fileload = logo->m_image.loadFromFile(RESOURCE_PATH("resources/images/chai3d-w.bmp")); if (!fileload) { #if defined(_MSVC) fileload = logo->m_image.loadFromFile("../../../bin/resources/images/chai3d-w.bmp"); #endif } // position the logo at the bottom left of the screen (pixel coordinates) logo->setPos(10, 10, 0); // scale the logo along its horizontal and vertical axis logo->setZoomHV(0.25, 0.25); // here we replace all wite pixels (1,1,1) of the logo bitmap // with transparent black pixels (1, 1, 1, 0). This allows us to make // the background of the logo look transparent. logo->m_image.replace( cColorb(0xff, 0xff, 0xff), // original RGB color cColorb(0xff, 0xff, 0xff, 0x00) // new RGBA color ); // enable transparency logo->enableTransparency(true); //----------------------------------------------------------------------- // HAPTIC DEVICES / TOOLS //----------------------------------------------------------------------- // create a haptic device handler handler = new cHapticDeviceHandler(); // get access to the first available haptic device cGenericHapticDevice* hapticDevice; handler->getDevice(hapticDevice, 0); // retrieve information about the current haptic device cHapticDeviceInfo info; if (hapticDevice) { info = hapticDevice->getSpecifications(); } // create a 3D tool and add it to the world tool = new cGeneric3dofPointer(world); world->addChild(tool); // connect the haptic device to the tool tool->setHapticDevice(hapticDevice); // initialize tool by connecting to haptic device tool->start(); // map the physical workspace of the haptic device to a larger virtual workspace. tool->setWorkspaceRadius(1.0); // define a radius for the tool (graphical display) tool->setRadius(0.05); // hide the device sphere. only show proxy. tool->m_deviceSphere->setShowEnabled(false); // set the physical readius of the proxy. proxyRadius = 0.05; tool->m_proxyPointForceModel->setProxyRadius(proxyRadius); tool->m_proxyPointForceModel->m_collisionSettings.m_checkBothSidesOfTriangles = false; // enable if objects in the scene are going to rotate of translate // or possibly collide against the tool. If the environment // is entirely static, you can set this parameter to "false" tool->m_proxyPointForceModel->m_useDynamicProxy = true; // read the scale factor between the physical workspace of the haptic // device and the virtual workspace defined for the tool double workspaceScaleFactor = tool->getWorkspaceScaleFactor(); // define a maximum stiffness that can be handled by the current // haptic device. The value is scaled to take into account the // workspace scale factor double stiffnessMax = info.m_maxForceStiffness / workspaceScaleFactor; //----------------------------------------------------------------------- // COMPOSE THE VIRTUAL SCENE //----------------------------------------------------------------------- // create a virtual mesh object = new cMesh(world); // add object to world world->addChild(object); // set the position of the object at the center of the world object->setPos(0.0, 0.0, 0.0); ///////////////////////////////////////////////////////////////////////// // create a cube ///////////////////////////////////////////////////////////////////////// const double HALFSIZE = 0.08; // face -x vertices[0][0] = object->newVertex(-HALFSIZE, HALFSIZE, -HALFSIZE); vertices[0][1] = object->newVertex(-HALFSIZE, -HALFSIZE, -HALFSIZE); vertices[0][2] = object->newVertex(-HALFSIZE, -HALFSIZE, HALFSIZE); vertices[0][3] = object->newVertex(-HALFSIZE, HALFSIZE, HALFSIZE); // face +x vertices[1][0] = object->newVertex( HALFSIZE, -HALFSIZE, -HALFSIZE); vertices[1][1] = object->newVertex( HALFSIZE, HALFSIZE, -HALFSIZE); vertices[1][2] = object->newVertex( HALFSIZE, HALFSIZE, HALFSIZE); vertices[1][3] = object->newVertex( HALFSIZE, -HALFSIZE, HALFSIZE); // face -y vertices[2][0] = object->newVertex(-HALFSIZE, -HALFSIZE, -HALFSIZE); vertices[2][1] = object->newVertex( HALFSIZE, -HALFSIZE, -HALFSIZE); vertices[2][2] = object->newVertex( HALFSIZE, -HALFSIZE, HALFSIZE); vertices[2][3] = object->newVertex(-HALFSIZE, -HALFSIZE, HALFSIZE); // face +y vertices[3][0] = object->newVertex( HALFSIZE, HALFSIZE, -HALFSIZE); vertices[3][1] = object->newVertex(-HALFSIZE, HALFSIZE, -HALFSIZE); vertices[3][2] = object->newVertex(-HALFSIZE, HALFSIZE, HALFSIZE); vertices[3][3] = object->newVertex( HALFSIZE, HALFSIZE, HALFSIZE); // face -z vertices[4][0] = object->newVertex(-HALFSIZE, -HALFSIZE, -HALFSIZE); vertices[4][1] = object->newVertex(-HALFSIZE, HALFSIZE, -HALFSIZE); vertices[4][2] = object->newVertex( HALFSIZE, HALFSIZE, -HALFSIZE); vertices[4][3] = object->newVertex( HALFSIZE, -HALFSIZE, -HALFSIZE); // face +z vertices[5][0] = object->newVertex( HALFSIZE, -HALFSIZE, HALFSIZE); vertices[5][1] = object->newVertex( HALFSIZE, HALFSIZE, HALFSIZE); vertices[5][2] = object->newVertex(-HALFSIZE, HALFSIZE, HALFSIZE); vertices[5][3] = object->newVertex(-HALFSIZE, -HALFSIZE, HALFSIZE); // create triangles for (int i=0; i<6; i++) { object->newTriangle(vertices[i][0], vertices[i][1], vertices[i][2]); object->newTriangle(vertices[i][0], vertices[i][2], vertices[i][3]); } // create a texture texture = new cTexture2D(); object->setTexture(texture); object->setUseTexture(true); // set material properties to light gray object->m_material.m_ambient.set(0.5f, 0.5f, 0.5f, 1.0f); object->m_material.m_diffuse.set(0.7f, 0.7f, 0.7f, 1.0f); object->m_material.m_specular.set(1.0f, 1.0f, 1.0f, 1.0f); object->m_material.m_emission.set(0.0f, 0.0f, 0.0f, 1.0f); // compute normals object->computeAllNormals(); // display triangle normals object->setShowNormals(true); // set length and color of normals object->setNormalsProperties(0.1, cColorf(1.0, 0.0, 0.0), true); // compute a boundary box object->computeBoundaryBox(true); // get dimensions of object double size = cSub(object->getBoundaryMax(), object->getBoundaryMin()).length(); // resize object to screen object->scale( 2.0 * tool->getWorkspaceRadius() / size); // compute collision detection algorithm object->createAABBCollisionDetector(1.01 * proxyRadius, true, false); // define a default stiffness for the object object->setStiffness(stiffnessMax, true); // define friction properties object->setFriction(0.2, 0.5, true); //----------------------------------------------------------------------- // OPEN GL - WINDOW DISPLAY //----------------------------------------------------------------------- // initialize GLUT glutInit(&argc, argv); // retrieve the resolution of the computer display and estimate the position // of the GLUT window so that it is located at the center of the screen int screenW = glutGet(GLUT_SCREEN_WIDTH); int screenH = glutGet(GLUT_SCREEN_HEIGHT); int windowPosX = (screenW - WINDOW_SIZE_W) / 2; int windowPosY = (screenH - WINDOW_SIZE_H) / 2; // initialize the OpenGL GLUT window glutInitWindowPosition(windowPosX, windowPosY); glutInitWindowSize(WINDOW_SIZE_W, WINDOW_SIZE_H); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow(argv[0]); glutDisplayFunc(updateGraphics); glutKeyboardFunc(keySelect); glutReshapeFunc(resizeWindow); glutSetWindowTitle("CHAI 3D"); // create a mouse menu (right button) glutCreateMenu(menuSelect); glutAddMenuEntry("full screen", OPTION_FULLSCREEN); glutAddMenuEntry("window display", OPTION_WINDOWDISPLAY); glutAttachMenu(GLUT_RIGHT_BUTTON); //----------------------------------------------------------------------- // START SIMULATION //----------------------------------------------------------------------- // simulation in now running simulationRunning = true; // create a thread which starts the main haptics rendering loop cThread* hapticsThread = new cThread(); hapticsThread->set(updateHaptics, CHAI_THREAD_PRIORITY_HAPTICS); // start the main graphics rendering loop glutMainLoop(); // close everything close(); // exit return (0); }
int main(int argc, char* argv[]) { //----------------------------------------------------------------------- // INITIALIZATION //----------------------------------------------------------------------- printf ("\n"); printf ("-----------------------------------\n"); printf ("CHAI3D\n"); printf ("Demo: 21-object\n"); printf ("Copyright 2003-2012\n"); printf ("-----------------------------------\n"); printf ("\n\n"); printf ("Keyboard Options:\n\n"); printf ("[1] - Texture (ON/OFF)\n"); printf ("[2] - Wireframe (ON/OFF)\n"); printf ("[3] - Collision tree (ON/OFF)\n"); printf ("[+] - Increase collision tree display depth\n"); printf ("[-] - Decrease collision tree display depth\n"); printf ("[x] - Exit application\n"); printf ("\n\n>\r"); // parse first arg to try and locate resources resourceRoot = string(argv[0]).substr(0,string(argv[0]).find_last_of("/\\")+1); //----------------------------------------------------------------------- // WORLD - CAMERA - LIGHTING //----------------------------------------------------------------------- // create a new world. world = new cWorld(); // set the background color of the environment world->m_backgroundColor.setBlack(); // create a camera and insert it into the virtual world camera = new cCamera(world); world->addChild(camera); // position and oriente the camera camera->set( cVector3d (3.0, 0.0, 0.6), // camera position (eye) cVector3d (0.0, 0.0, 0.0), // lookat position (target) cVector3d (0.0, 0.0, 1.0)); // direction of the (up) vector // set the near and far clipping planes of the camera // anything in front/behind these clipping planes will not be rendered camera->setClippingPlanes(0.01, 10.0); // Enable shadow casting camera->setUseShadowCasting(true); // create a light source light = new cSpotLight(world); // attach light to camera camera->addChild(light); // enable light source light->setEnabled(true); // position the light source light->setLocalPos( 0.0, 0.5, 0.0); // define the direction of the light beam light->setDir(-3.0,-0.5, 0.0); // enable this light source to generate shadows light->setShadowMapEnabled(true); // set lighting conditions light->m_ambient.set(0.4, 0.4, 0.4); light->m_diffuse.set(0.8, 0.8, 0.8); light->m_specular.set(1.0, 1.0, 1.0); //----------------------------------------------------------------------- // HAPTIC DEVICES / TOOLS //----------------------------------------------------------------------- // create a haptic device handler handler = new cHapticDeviceHandler(); // get access to the first available haptic device handler->getDevice(hapticDevice, 0); // retrieve information about the current haptic device cHapticDeviceInfo info = hapticDevice->getSpecifications(); // if the haptic devices carries a gripper, enable it to behave like a user switch hapticDevice->setEnableGripperUserSwitch(true); // create a 3D tool and add it to the world tool = new cToolCursor(world); world->addChild(tool); // connect the haptic device to the tool tool->setHapticDevice(hapticDevice); // initialize tool by connecting to haptic device tool->start(); // map the physical workspace of the haptic device to a larger virtual workspace. tool->setWorkspaceRadius(1.0); // define the radius of the tool (sphere) double toolRadius = 0.01; // define a radius for the tool tool->setRadius(toolRadius); // hide the device sphere. only show proxy. tool->setShowContactPoints(true, false); // enable if objects in the scene are going to rotate of translate // or possibly collide against the tool. If the environment // is entirely static, you can set this parameter to "false" tool->enableDynamicObjects(true); // read the scale factor between the physical workspace of the haptic // device and the virtual workspace defined for the tool double workspaceScaleFactor = tool->getWorkspaceScaleFactor(); // define a maximum stiffness that can be handled by the current // haptic device. The value is scaled to take into account the // workspace scale factor double stiffnessMax = info.m_maxLinearStiffness / workspaceScaleFactor; //----------------------------------------------------------------------- // CREATING OBJECT //----------------------------------------------------------------------- // create a virtual mesh object = new cMultiMesh(); // add object to world world->addChild(object); // load an object file bool fileload; fileload = object->loadFromFile(RESOURCE_PATH("resources/models/camera/camera.3ds")); if (!fileload) { #if defined(_MSVC) fileload = object->loadFromFile("../../../bin/resources/models/camera/camera.3ds"); #endif } if (!fileload) { printf("Error - 3D Model failed to load correctly.\n"); close(); return (-1); } // disable culling so that faces are rendered on both sides object->setUseCulling(false); // compute and display edges object->computeAllEdges(40); object->setShowEdges(true); // compute a boundary box object->computeBoundaryBox(true); // get dimensions of object double size = cSub(object->getBoundaryMax(), object->getBoundaryMin()).length(); // resize object to screen if (size > 0) { object->scale( 2.0 * tool->getWorkspaceRadius() / size); } // compute collision detection algorithm object->createAABBCollisionDetector(toolRadius); // define a default stiffness for the object object->setStiffness(stiffnessMax, true); // define some haptic friction properties object->setFriction(0.1, 0.2, true); // position object in scene object->rotateExtrinsicEulerAnglesDeg(-10, 0, 80, C_EULER_ORDER_XYZ); //----------------------------------------------------------------------- // WIDGETS //----------------------------------------------------------------------- // create a font cFont *font = NEW_CFONTCALIBRI20(); // create a label to display the haptic rate of the simulation labelHapticRate = new cLabel(font); labelHapticRate->m_fontColor.setBlack(); camera->m_frontLayer->addChild(labelHapticRate); // create a background cBackground* background = new cBackground(); camera->m_backLayer->addChild(background); // set background properties background->setCornerColors(cColorf(1.0, 1.0, 1.0), cColorf(1.0, 1.0, 1.0), cColorf(0.9, 0.9, 0.9), cColorf(0.9, 0.9, 0.9)); //----------------------------------------------------------------------- // OPEN GL - WINDOW DISPLAY //----------------------------------------------------------------------- // simulation in now running! simulationRunning = true; // initialize GLUT glutInit(&argc, argv); // retrieve the resolution of the computer display and estimate the position // of the GLUT window so that it is located at the center of the screen int screenW = glutGet(GLUT_SCREEN_WIDTH); int screenH = glutGet(GLUT_SCREEN_HEIGHT); int windowW = 0.7 * screenH; int windowH = 0.7 * screenH; int windowPosX = (screenW - windowH) / 2; int windowPosY = (screenH - windowW) / 2; // initialize the OpenGL GLUT window glutInitWindowPosition(windowPosX, windowPosY); glutInitWindowSize(windowW, windowH); if (USE_STEREO_DISPLAY) { glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_STEREO); camera->setUseStereo(true); } else { glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); camera->setUseStereo(false); } glutCreateWindow(argv[0]); glutDisplayFunc(updateGraphics); glutKeyboardFunc(keySelect); glutReshapeFunc(resizeWindow); glutSetWindowTitle("CHAI3D"); // create a mouse menu (right button) glutCreateMenu(menuSelect); glutAddMenuEntry("full screen", OPTION_FULLSCREEN); glutAddMenuEntry("window display", OPTION_WINDOWDISPLAY); glutAttachMenu(GLUT_RIGHT_BUTTON); //----------------------------------------------------------------------- // START SIMULATION //----------------------------------------------------------------------- // create a thread which starts the main haptics rendering loop cThread* hapticsThread = new cThread(); hapticsThread->start(updateHaptics, CTHREAD_PRIORITY_HAPTICS); // start the main graphics rendering loop glutTimerFunc(30, graphicsTimer, 0); glutMainLoop(); // close everything close(); // exit return (0); }