예제 #1
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')
    {
        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);
    }
}
예제 #2
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')
    {
        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);
    }
}
예제 #3
0
파일: 52-GEL-duck.cpp 프로젝트: jateeq/FYDP
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);
}
예제 #4
0
파일: 23-tooth.cpp 프로젝트: jateeq/FYDP
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);
        }
    }
}
예제 #5
0
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;
}
예제 #6
0
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);
}
예제 #7
0
파일: 20-map.cpp 프로젝트: jateeq/FYDP
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);
}
예제 #8
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);
}
예제 #9
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);
}