Esempio n. 1
0
//===========================================================================
cCamera::cCamera(cWorld* a_parentWorld)
{
    // set default values for clipping planes
    setClippingPlanes(0.1, 1000.0);

    // set default field of view angle
    setFieldViewAngle(45);

    // set parent world
    m_parentWorld = a_parentWorld;

    // position and orient camera, looking down the negative x-axis
    // (the robotics convention)
    set(
          cVector3d(0,0,0),       // Local Position of camera.
          cVector3d(-1,0,0),      // Local Look At position
          cVector3d(0,0,1)        // Local Up Vector
        );

    // set default stereo parameters
    m_stereoFocalLength = 5.0;
    m_stereoEyeSeparation = 0.5;

    // disable multipass transparency rendering by default
    m_useMultipassTransparency = 0;

    m_performingDisplayReset = 0;

    memset(m_projectionMatrix,0,sizeof(m_projectionMatrix));
}
Esempio n. 2
0
void Carro::rotacionarEixos(double delta){
        if(fabs(steeringAngle+delta)<=ANGULOLIMITE) {
                steeringAngle += delta;
                eixo1->rotate(cVector3d(0,1,0),delta);
                eixo2->rotate(cVector3d(0,1,0),delta);
        }
}
cMatrix3d InputManager::GetCameraTransformations()
{
	cMatrix3d cam;

	//Col0 has Position
	cam.setCol0(cVector3d(transforms.xPos, transforms.yPos, transforms.zPos));
	
	//Col1 has Gaze
	dvec4 gazeCamSpace = dvec4( 0, 0, 1, 1);
	dvec4 gazeWorldSpace = camToWorld * gazeCamSpace;
	cam.setCol1(cVector3d(gazeWorldSpace.x, gazeWorldSpace.y, gazeWorldSpace.z));

	//Col2 has Up
	cVector3d up;
	if(transforms.elevation == 0)
	{
		//If Looking straight down, change the up vector to the heading
		up = cVector3d(cos(d2r(transforms.heading)), 0, sin(d2r(transforms.heading)));
	}
	else if(transforms.elevation == 180)
	{
		//If looking straight up, change the up vector to the negative heading
		up = cVector3d(0 - cos(d2r(transforms.heading)), 0, 0 - sin(d2r(transforms.heading)));
	}
	else
	{
		up = cVector3d(0,1,0);
	}
	cam.setCol2(up);

	return cam;
}
Esempio n. 4
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')
    {
        // enable gravity
        ODEWorld->setGravity(cVector3d(0.0, 0.0, -9.81));
    }

    // option 2:
    if (key == '2')
    {
        // disable gravity
        ODEWorld->setGravity(cVector3d(0.0, 0.0, 0.0));
    }
}
//==============================================================================
void cDrawArrow(const cVector3d& a_arrowStart, 
                const cVector3d& a_arrowTip, 
                const double a_width)
{
#ifdef C_USE_OPENGL

    glPushMatrix();

    // We don't really care about the up vector, but it can't
    // be parallel to the arrow...
    cVector3d up = cVector3d(0,1,0);
    cVector3d arrow = a_arrowTip-a_arrowStart;
    arrow.normalize();
    double d = fabs(cDot(up,arrow));
    if (d > .9)
    {
        up = cVector3d(1,0,0);
    }

    cLookAt(a_arrowStart, a_arrowTip, up);
    double distance = cDistance(a_arrowTip,a_arrowStart);

    // This flips the z axis around
    glRotatef(180,1,0,0);

    // create a new OpenGL quadratic object 
    GLUquadricObj *quadObj;
    quadObj = gluNewQuadric();

    #define ARROW_CYLINDER_PORTION 0.75
    #define ARRROW_CONE_PORTION (1.0 - 0.75)

    // set rendering style
    gluQuadricDrawStyle(quadObj, GLU_FILL);

    // set normal-rendering mode
    gluQuadricNormals(quadObj, GLU_SMOOTH);

    // render a cylinder and a cone
    glRotatef(180,1,0,0);
    gluDisk(quadObj,0,a_width,10,10);
    glRotatef(180,1,0,0);

    gluCylinder(quadObj, a_width, a_width, distance*ARROW_CYLINDER_PORTION, 10, 10);
    glTranslated(0, 0, ARROW_CYLINDER_PORTION*distance);

    glRotatef(180, 1, 0, 0);
    gluDisk(quadObj, 0, a_width*2.0, 10, 10);
    glRotatef(180,1,0,0);

    gluCylinder(quadObj, a_width*2.0, 0.0, distance*ARRROW_CONE_PORTION, 10, 10);

    // delete our quadric object
    gluDeleteQuadric(quadObj);

    glPopMatrix();

#endif
}
Esempio n. 6
0
void HugMe::InitRemoteWorld()
{
	m_worldRemote = new cWorld();

	// Create a mesh - we will build a cube manually, and later let the
	// user load 3d models
	m_remoteHumanModel.SetParentWorld(m_worldRemote);
	m_remoteHumanModel.ShowAvatar(m_config.m_bShowAvatar);

	// for debug
	m_pContactPoint = new cMesh(m_worldRemote);
	m_worldRemote->addChild(m_pContactPoint);
	m_pContactPoint->loadFromFile("Blender/ContactPoint.obj");
	m_pContactPoint->translate(CHAI_LARGE, CHAI_LARGE, CHAI_LARGE);
	m_pContactPoint->computeGlobalPositions();
	m_pContactPoint->setHapticEnabled(false, true);
	ShowContactPoint(m_config.m_bShowContactpoint);

	// set camera position and orientation
	// 
	// We choose to put it out on the positive z axis, so things appear
	// the way OpenGL users expect them to appear, with z going in and
	// out of the plane of the screen.
	double angle;
	angle = atan(240.0*m_pixelWidth/m_focalLength)*180.0/3.141592;
	if(!m_camera) {
		m_camera = new cCamera(m_worldRemote);
		int result = m_camera->set(cVector3d(0.0,0.0,0.0),   // position of camera
				  cVector3d(0.0, 0.0, -1.0),   // camera looking at origin
				  cVector3d(0.0, 1.0, 0.0));  // orientation of camera (standing up)
		m_camera->setFieldViewAngle(angle);
		m_camera->setClippingPlanes(1.0, (double)m_primaryDistance+(double)m_depthDistance);
	}

	if(!m_light) {
		// Turn on one light...
		m_light = new cLight(m_worldRemote);

		m_light->setEnabled(true);

		// Put the light somewhere that looks nice
		m_light->setDirectionalLight(true);
		m_light->setPos(cVector3d(1000.0, 1000.0, 1000));
		m_light->setDir(cVector3d(0.0, 0.0, -1.0));
		m_light->m_ambient.set(0.6f, 0.6f, 0.6f, 1.0f);
		m_light->m_diffuse.set(0.7f, 0.7f, 0.7f, 1.0f);
		m_light->m_specular.set(0.5f, 0.5f, 0.5f, 1.0f);
		// Don't make it a spotlight
		m_light->setCutOffAngle(120.0);
	}

	// Create a display for graphic rendering
	m_viewport = new cViewport(m_hWnd, m_camera, false);
}
Esempio n. 7
0
void Carro::movimentar(double passo){

        roda1->rotate(cVector3d(0,0,1),passo);
        roda2->rotate(cVector3d(0,0,1),passo);
        roda3->rotate(cVector3d(0,0,1),passo);
        roda4->rotate(cVector3d(0,0,1),passo);
        double dangle = -passo*RAIORODA*tan(steeringAngle)/DISTANCIAEIXOS;
        carAngle+= dangle;
        meio->rotate(cVector3d(0,1,0),dangle);
        this->translate(-passo*RAIORODA*cos(carAngle),0,passo*RAIORODA*sin(carAngle));
}
Esempio n. 8
0
//===========================================================================
bool cEffectVibration::computeForce(const cVector3d& a_toolPos,
                                  const cVector3d& a_toolVel,
                                  const unsigned int& a_toolID,
                                  cVector3d& a_reactionForce)
{
    if (m_parent->m_interactionInside)
    {
        // read vibration parameters
        double vibrationFrequency = m_parent->m_material.getVibrationFrequency();
        double vibrationAmplitude = m_parent->m_material.getVibrationAmplitude();

        // read time
        double time = clock.getCurrentTimeSeconds();

        // compute force magnitude
        double forceMag = vibrationAmplitude * sin(2.0 * CHAI_PI *vibrationFrequency * time);

        a_reactionForce = cMul(forceMag, cVector3d(1, 0, 0));
        return (true);
    }
    else
    {
        // the tool is located outside the object, so zero reaction force
        a_reactionForce.zero();
        return (false);
    }
}
cVector3d InputManager::RotateVector(const cVector3d& vec)
{
	dvec4 glmVec = dvec4(vec.x, vec.y, vec.z, 1);
	dvec4 newVec = rotateToWorld * glmVec;
	//might need to negate z coordinate
	return cVector3d(newVec.x, newVec.y, 0 - newVec.z);
}
Esempio n. 10
0
void updateCameraPosition()
{
    // check values
    if (cameraDistance < 0.1) { cameraDistance = 0.1; }
    if (cameraAngleV > 89) { cameraAngleV = 89; }
    if (cameraAngleV < 10) { cameraAngleV = 10; }

    // compute position of camera in space
    cVector3d pos = cAdd(
                        cameraPosition,
                        cVector3d(
                            cameraDistance * cCosDeg(cameraAngleH) * cCosDeg(cameraAngleV),
                            cameraDistance * cSinDeg(cameraAngleH) * cCosDeg(cameraAngleV),
                            cameraDistance * cSinDeg(cameraAngleV)
                        )
                    );

    // compute lookat position
    cVector3d lookat = cameraPosition;

    // define role orientation of camera
    cVector3d up(0.0, 0.0, 1.0);

    // set new position to camera
    camera->set(pos, lookat, up);

    // recompute global positions
    world->computeGlobalPositions(true);
}
// overriden from class cProxyPointForceAlgo
cVector3d ch_proxyPointForceAlgo::computeForcesD(const cVector3d& a_toolPos, const cVector3d& a_toolVel)
{
    // update device position
    m_deviceGlobalPos = a_toolPos;

    // check if world has been defined; if so, compute forces
    if (m_world != NULL)
    {
        // compute next best position of proxy
        computeNextBestProxyPosition(m_deviceGlobalPos, a_toolVel);

        // update proxy to next best position
        m_proxyGlobalPos = m_nextBestProxyGlobalPos;

        // compute force vector applied to device
        updateForce();

        // return result
        return (m_lastGlobalForce);
    }

    // if no world has been defined in which algorithm operates, there is no force
    else
    {
        return (cVector3d(0.0, 0.0, 0.0));
    }
}
Esempio n. 12
0
void HapticLoop(void* param)
{
  // simulation in now ON
    Crecord_playerApp* app = (Crecord_playerApp*)(param);

  // read position from haptic device
  app->tool->updatePose();

  // compute forces
  app->tool->computeForces();

  // get last interaction force in global coordinate frame
  app->m_interactionForce = cMul(cTrans(app->object->getRot()), cSub(app->tool->m_lastComputedGlobalForce, app->object->getPos()));

  app->tool->applyForces();

  // figure out if we're touching the record
  cProxyPointForceAlgo * algo = app->tool->getProxy();
  if (algo->getContactObject() == app->m_recordMesh)
  {
    if (!app->m_inContact)
    {
      app->m_inContact = true;
      app->m_RFDInitialAngle = app->m_rotPos - app->m_lastGoodPosition*CHAI_PI/180;
    }
    app->animateObject(app->m_interactionForce);
  }
  else
  {
    app->animateObject(cVector3d(0.0, 0.0, 0.0));
    app->m_inContact = false;
  }
}
Esempio n. 13
0
//===========================================================================
cCamera::cCamera(cWorld* a_parentWorld)
{
    // set parent world
    m_parentWorld = a_parentWorld;
	
	// set default values for clipping planes
    setClippingPlanes(0.1, 1000.0);

    // set default field of view angle
    setFieldViewAngle(45);

    // position and orient camera, looking down the negative x-axis
    // (the robotics convention)
    set(
          cVector3d(0,0,0),       // Local Position of camera.
          cVector3d(-1,0,0),      // Local Look At position
          cVector3d(0,0,1)        // Local Up Vector
        );


    // by default we use a persepctive camera
    m_perspectiveMode = true;

    // width of orthographic view. (not active by default)
    m_orthographicWidth = 0.0;

    // set default stereo parameters
    m_stereoFocalLength		= 2.0;
    m_stereoEyeSeparation	= 0.07;

    // disable multipass transparency rendering by default
    m_useMultipassTransparency = false;

	// enable shadow rendering
	m_useShadowCasting = false;

    // enable stereo display
    m_useStereo = false;

    // reset display status
    m_resetDisplay = false;

    // create front and back layers
    m_frontLayer = new cWorld();
    m_backLayer = new cWorld();
}
Esempio n. 14
0
__fastcall TActiveFormX::TActiveFormX(TComponent* AOwner) : TActiveForm(AOwner)
{

    // create a new world
    world = new cWorld();

    // set background color
    world->setBackgroundColor(0.0f,0.0f,0.0f);

    // Create a camera
    camera = new cCamera(world);
    world->addChild(camera);

    // Create a light source and attach it to camera
    light = new cLight(world);
    light->setEnabled(true);
    light->setPos(cVector3d(2,1,1));

    // define camera position
    cameraAngleH = 10;
    cameraAngleV = 20;
    cameraDistance = 2.0;
    flagCameraInMotion = false;
    updateCameraPosition();
    camera->setClippingPlanes(0.01, 10.0);

    // create a display for graphic rendering
    viewport = new cViewport(Panel1->Handle, camera, true);
    viewport->setStereoOn(false);

    // create a mesh - we will build a simple cube, and later let the
    // user load 3d models
    object = new cMesh(world);
    world->addChild(object);

    // create a nice little cube
    createCube(object, 0.2);

    // define a material property for this object
    cMaterial material;
    material.m_ambient.set( 0.4, 0.2, 0.2, 1.0 );
    material.m_diffuse.set( 0.8, 0.6, 0.6, 1.0 );
    material.m_specular.set( 0.9, 0.9, 0.9, 1.0 );
    material.setShininess(100);
    material.setStiffness(20 );
    object->m_material = material;

    // update camera position
    updateCameraPosition();

    // don't start the haptics loop yet
    flagSimulationOn = false;
    flagHasExitedSimulation = true;
}
//===========================================================================
int cPhantomDevice::getPosition(cVector3d& a_position)
{
	// check if drivers are installed
	if (!m_driverInstalled) return (-1);

    double x,y,z;
    int error = hdPhantomGetPosition(m_deviceID, &x, &y, &z);
    a_position = m_specifications.m_positionOffset + cVector3d(x, y, z);
    estimateLinearVelocity(a_position);
    return (error);
}
Esempio n. 16
0
void OscPrismCHAI::on_size()
{
    // reposition vertices
    int i,n;
    n = m_pPrism->getNumVertices();
    for (i=0; i<n; i++) {
        cVector3d pos = m_pPrism->getVertex(i)->getPos();
        pos.elementMul(cVector3d(1.0/fabs(pos.x), 1.0/fabs(pos.y), 1.0/fabs(pos.z)));
        pos.elementMul(m_size/2.0);
        m_pPrism->getVertex(i)->setPos(pos);
    }
}
Esempio n. 17
0
int ODEObject::push_handler(const char *path, const char *types,
                            lo_arg **argv, int argc,
                            void *data, void *user_data)
{
    OscObject *me = static_cast<OscObject*>(user_data);
    ODEObject *ode_object = static_cast<ODEObject*>(me->special());
    cVector3d(argv[0]->f, argv[1]->f, argv[2]->f).copyto(me->m_force);
    dBodyAddForceAtPos(ode_object->body(),
                       argv[0]->f, argv[1]->f, argv[2]->f,
                       argv[3]->f, argv[4]->f, argv[5]->f);
    return 0;
}
void updateGraphics(void)
{
    // render world
    camera->renderView(displayW, displayH);

    // Swap buffers
    glutSwapBuffers();

    // check for any OpenGL errors
    GLenum err;
    err = glGetError();
    if (err != GL_NO_ERROR) printf("Error:  %s\n", gluErrorString(err));

    // inform the GLUT window to call updateGraphics again (next frame)
    if (simulationRunning)
    {
        glutPostRedisplay();
    }

    // rotate the following objcts to create some animation
    object1->rotate(cVector3d(0,0,1),  0.02);
    object3->rotate(cVector3d(1,1,1), -0.01);
}
Esempio n. 19
0
OscCursorCHAI::OscCursorCHAI(cWorld *world, const char *name, OscBase *parent)
    : OscSphere(NULL, name, parent)
{
    // create the cursor object
    m_pCursor = new cMeta3dofPointer(world);
    world->addChild(m_pCursor);

    // User data points to the OscObject, used for identification
    // during object contact.
    m_pCursor->setUserData(this, 1);

    // replace the potential proxy algorithm with our own
    cGenericPointForceAlgo *old_proxy, *new_proxy;
    old_proxy = m_pCursor->m_pointForceAlgos[1];
    new_proxy = new cODEPotentialProxy(
        dynamic_cast<cPotentialFieldForceAlgo*>(old_proxy));
    m_pCursor->m_pointForceAlgos[1] = new_proxy;
    delete old_proxy;

    if (m_pCursor->initialize()) {
        m_bInitialized = false;
        printf("[%s] Could not initialize.\n", simulation()->type_str());
    } else {
        m_bInitialized = true;
        m_pCursor->start();

        printf("[%s] Using %s device.\n",
               simulation()->type_str(), device_str());
    }

    // rotate the cursor to match visual rotation
    m_pCursor->rotate(cVector3d(0,0,1),-90.0*M_PI/180.0);

    // make it a cursor tuned for a dynamic environment
    ((cProxyPointForceAlgo*)m_pCursor->m_pointForceAlgos[0])
    ->enableDynamicProxy(true);

    // this is necessary for the above rotation to take effect
    m_pCursor->computeGlobalPositions();

    // set up mass as zero to begin (transparent proxy)
    m_mass.set(0);

    // no extra force to begin with
    m_nExtraForceSteps = 0;

    m_pSpecial = new CHAIObject(this, m_pCursor, world);
}
Esempio n. 20
0
int main(int argc, char* argv[])
{
    //-----------------------------------------------------------------------
    // INITIALIZATION
    //-----------------------------------------------------------------------

    printf ("\n");
    printf ("-----------------------------------\n");
    printf ("CHAI3D\n");
    printf ("Demo: 04-shapes\n");
    printf ("Copyright 2003-2012\n");
    printf ("-----------------------------------\n");
    printf ("\n\n");
    printf ("Keyboard Options:\n\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.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 

/*	camera->set( cVector3d (0.0, 0.0, -3.0),    // camera position (eye)
		cVector3d (0.0, 0.0, 0.0),    // lookat position (target)
		cVector3d (-1.0, 0.0, 0.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 multi-pass rendering to handle transparent objects
    camera->setUseMultipassTransparency(true);

    // create a light source
    light = new cDirectionalLight(world);

    // add light to world
    world->addChild(light);

    // enable light source
    light->setEnabled(true);                   

    // define the direction of the light beam
    light->setDir(-1.0, 0.0, 0.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 hapticDeviceInfo = hapticDevice->getSpecifications();

    // 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(2.0);

    // define a radius for the tool
    tool->setRadius(0.03);

    // read the scale factor between the physical workspace of the haptic
    // device and the virtual workspace defined for the tool
    double workspaceScaleFactor = tool->getWorkspaceScaleFactor();

	// my device open		**********************MINE
	deltaCtrl.ConnectDevice();
	//double R[3][3] = {0,0,-1,0,-1,0,-1,0,0};
	//deltaCtrl.SetRotation(R);	


    //-----------------------------------------------------------------------
    // CREATING OBJECTS
    //-----------------------------------------------------------------------

    // temp variable
    cGenericEffect* newEffect;

    // stiffness properties
    double maxStiffness	= hapticDeviceInfo.m_maxLinearStiffness / workspaceScaleFactor;
	double maxLinearForce = hapticDeviceInfo.m_maxLinearForce;
	
	// pull up stiffness
	maxStiffness =300;

    // create a sphere 0
	sphere0 = new cShapeSphere(0.1);
	world->addChild(sphere0);
	sphere0->setLocalPos(0.0,-0.7, 0.0);
	sphere0->m_material->setRedFireBrick();
    newEffect = new cEffectSurface(sphere0);
    sphere0->addEffect(newEffect);
	sphere0->m_material->setStiffness(0.4 * maxStiffness);

    // create a sphere 1
	sphere1 = new cShapeSphere(0.1);
	world->addChild(sphere1);
	sphere1->setLocalPos(0.0, 0.7, 0.0);
	sphere1->m_material->setRedFireBrick();
    newEffect = new cEffectSurface(sphere1);
    sphere1->addEffect(newEffect);
	sphere1->m_material->setStiffness(0.4 * maxStiffness);

    // create a line
	line = new cShapeLine(sphere0->getLocalPos(), sphere1->getLocalPos());
	world->addChild(line);
	line->m_material->setWhite();
    newEffect = new cEffectMagnet(line);
    line->addEffect(newEffect);
	line->m_material->setMagnetMaxDistance(0.05);
	line->m_material->setMagnetMaxForce(0.1 * maxLinearForce);
	line->m_material->setStiffness(0.1 * maxStiffness);

	// create a cylinder
	cylinder = new cShapeCylinder(0.25, 0.25, 0.2);
	world->addChild(cylinder);
	cylinder->setLocalPos(0.0, 0.0, 0.0);
	cylinder->rotateAboutGlobalAxisDeg(cVector3d(1.0, 0.0, 0.0), 90);
	cylinder->m_material->setBlueCornflower();
    newEffect = new cEffectSurface(cylinder);
    cylinder->addEffect(newEffect);
	cylinder->m_material->setStiffness(0.8 * maxStiffness);

    
    //-----------------------------------------------------------------------
    // WIDGETS
    //-----------------------------------------------------------------------

    // create a font
    cFont *font = NEW_CFONTCALIBRI20();
    
    // create a label to display the haptic rate of the simulation
    labelHapticRate = new cLabel(font);
    camera->m_frontLayer->addChild(labelHapticRate);


    //-----------------------------------------------------------------------
    // 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 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);
    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);
}
Esempio n. 21
0
int main(int argc, char* argv[])
{

    // display pretty message
    printf ("\n");
    printf ("  ===================================\n");
    printf ("  CHAI 3D\n");
    printf ("  Viewmesh Demo\n");
    printf ("  Copyright 2006\n");
    printf ("\n  Use the left mouse button to rotate the model\n");
    printf ("\n  Use the middle mouse button to move the model\n");
    printf ("\n  Use the right mouse button to switch to fullscreen\n");
    printf ("  ===================================\n");
    printf ("\n");

    // make sure the user specified a mesh
    if (argc < 2)
    {
      printf("Usage: %s [mesh_filename]\n\n",argv[0]);
      return -1;
    }

    // create a new world
    world = new cWorld();

    loadMesh(argv[1]);

    if (object == 0) {
        printf("Could not load model %s\n\n",argv[1]);
        return -1;
    }

    // set background color
    world->setBackgroundColor(0.0f,0.0f,0.0f);

    // create a camera
    camera = new cCamera(world);
    world->addChild(camera);

    // set camera position and orientation
    // 
    // We choose to put it out on the positive z axis, so things appear
    // the way OpenGL users expect them to appear, with z going in and
    // out of the plane of the screen.
    int result = camera->set(
        cVector3d(0,0,4),           // position of camera
        cVector3d(0.0, 0.0, 0.0),   // camera looking at origin
        cVector3d(0.0, 1.0, 0.0)    // orientation of camera (standing up)
        );

    // load a little chai bitmap logo which will located at the bottom of the screen
    logo = new cBitmap();
    logo->m_image.loadFromFile("./resources/images/chai3d.bmp");
    logo->setPos(10,10,0);
    camera->m_front_2Dscene.addChild(logo);

    // we replace the background color of the logo (black) with a transparent color.
    // we also enable transparency
    logo->m_image.replace(cColorb(0,0,0), cColorb(0,0,0,0));
    logo->enableTransparency(true);

    // Create a light source and attach it to the camera
    light = new cLight(world);
    light->setEnabled(true);
    light->setPos(cVector3d(2,0.5,1));
    light->setDir(cVector3d(-2,0.5,1));
    camera->addChild(light);

    // create a tool and add it to the world.
    tool = new cMeta3dofPointer(world, false);

    // This is what we would do if we _didn't_ want the tool to
    // move around as a child of the camera
    //   world->addChild(tool);
    // Rotate the tool so its axes align with our opengl-like axes
    //   tool->rotate(cVector3d(0,0,1),-90.0*M_PI/180.0);
    //   tool->rotate(cVector3d(1,0,0),-90.0*M_PI/180.0);

    // set up a nice-looking workspace for the phantom so 
    // it fits nicely with our models
    tool->setPos(-4.0, 0.0, 0.0);
    tool->setWorkspace(2.0,2.0,2.0);         
    tool->setRadius(0.05);      
    camera->addChild(tool);

    // initialize the GLUT windows
    glutInit(&argc, argv);
    glutInitWindowSize(512, 512);
    glutInitWindowPosition(0, 0);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(draw);
    glutKeyboardFunc(key);
    glutReshapeFunc(resizeWindow);
    glutSetWindowTitle("CHAI 3D");

    // create a mouse menu
    glutCreateMenu(menuCallback);
    glutAddMenuEntry("Full Screen", OPTION_FULLSCREEN);
    glutAddMenuEntry("Window Display", OPTION_WINDOWDISPLAY);
    glutAttachMenu(GLUT_RIGHT_BUTTON);

    glutMotionFunc(mouseMove);
    glutMouseFunc(mouseDown);

    // Make sure the haptic device knows where he is in the camera frame
    world->computeGlobalPositions(true);

    // set up the device
    tool->initialize();

    // open communication to the device
    tool->start();

    // start haptic timer callback
    timer.set(0, hapticsLoop, NULL);

    // update display
    glutTimerFunc(30, updateDisplay, 0);

    // start main graphic rendering loop
    glutMainLoop();
    return 0;
}
Esempio n. 22
0
BOOL Crecord_playerApp::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 Crecord_playerDlg;
  m_pMainWnd = g_main_dlg;

  g_main_dlg->Create(IDD_record_player_DIALOG,NULL);
    
    // create a new world
  world = new cWorld();

  // set background color
  world->setBackgroundColor(0.0f,0.0f,0.0f);

  // Create a camera
  camera = new cCamera(world);
  world->addChild(camera);

  // Create a light source and attach it to camera
  light = new cLight(world);
  light->setEnabled(true);
  light->setPos(cVector3d(2,1,1));

  // define camera position
  flagCameraInMotion = false;

  camera->set(cVector3d(2,0,1), cVector3d(0,0,0), cVector3d(0,0,1));

  // create a display for graphic rendering
  viewport = new cViewport(g_main_dlg->m_gl_area_hwnd, camera, true);
  viewport->setStereoOn(false);

  // init var
  m_rotPos = 0;
  m_rotVel = 0;
  m_inertia = 0.04;
  m_clock.initialize();
  m_lastGoodPosition = 0.0;

  m_reduction = 5.4*10;
  m_cpt = 120*4;          
  m_desiredPos = 0.0;
  m_P = 0.4;
  m_I = 0.0014;
  m_integratorVal = 0.0;
  m_D = 0.02;

  m_lastAngle = 0.0;

  m_velocity = 0;
  m_velocityOld = 0;

  m_RFDInitialAngle = 0.0;
  m_inContact = false;

  LoadModel(TURNTABLE_MODEL);

  object->translate(0,0,-0.3);

  // set stiffness
  double stiffness = (double)35;
  object->setStiffness(stiffness, true);

  // Initialize sound device and create audio stream
  if (!BASS_Init(1,44100,0,0,NULL))
      _cprintf("Init error %d\n", BASS_ErrorGetCode());
    
  // Load a record onto the record player
  load_record(0);
  
  object->computeGlobalPositions(false);
  world->computeGlobalPositions(false);

  return TRUE;
}
//==============================================================================
void cDirectionalLight::setDir(const double a_x, const double a_y, const double a_z)
{
    setDir(cVector3d(a_x, a_y, a_z));
}
Esempio n. 24
0
void __fastcall TForm1::MassSpringFormCreate(TObject *Sender)
{
    m_floor = 0;
    m_floor_spring_constant = DEFAULT_FLOOR_SPRING_CONSTANT;

    // init world scale
    scale = 2.0;

    // create a world
    world = new cWorld();

    // set background properties
    world->setBackgroundColor(0.2,0.2,0.2);

    // create a camera in world
    camera  = new cCamera(world);
    world->addChild(camera);

    // set camera position and orientation
    camera->set(   cVector3d(0.0, 0.0, 7.0),   // position of camera.
                   cVector3d(0.0, 0.0, 0.0),   // camera looking at origin.
                   cVector3d(0.0, 1.0, 0.0));  // orientation of camera. (standing up.)

    // Create a light source and attach it to camera
    light = new cLight(world);
    camera->addChild(light);
    light->setEnabled(true);
    light->setPos(cVector3d(0,2,4));
    light->rotate(cVector3d(0,0,1), cDegToRad(180));

    // create a display for graphic rendering
    viewport = new cViewport(Panel1->Handle, camera, false);

    // create a tool
    tool = new cMeta3dofPointer(world, 0, true);
    tool->initialize();
    tool->setRenderingMode(RENDER_DEVICE);

    // Rotate the tool so its axes align with our opengl-like axes
    tool->rotate(cVector3d(0,0,1),-90.0*M_PI/180.0);
    tool->rotate(cVector3d(1,0,0),-90.0*M_PI/180.0);
    tool->computeGlobalPositions();

    tool->setWorkspace(3.5*scale, 3.5*scale, 3.5*scale);
    tool->setRadius(scale / 70.0);

    // tool becomes a child of the camera which we can control from
    world->addChild(tool);

    // Create a mesh to represent the floor
    m_floor = new cMesh(world);
    world->addChild(m_floor);

    // Fill in meaningful vertex positions
    m_floor->newVertex(-FLOOR_X_SIZE/2.0,  FLOOR_Y_POSITION, -FLOOR_Z_SIZE/2.0);
    m_floor->newVertex(-FLOOR_X_SIZE/2.0,  FLOOR_Y_POSITION,  FLOOR_Z_SIZE/2.0);
    m_floor->newVertex( FLOOR_X_SIZE/2.0,  FLOOR_Y_POSITION,  FLOOR_Z_SIZE/2.0);
    m_floor->newTriangle(0,1,2);

    m_floor->newVertex( FLOOR_X_SIZE/2.0,  FLOOR_Y_POSITION, -FLOOR_Z_SIZE/2.0);
    m_floor->newVertex(-FLOOR_X_SIZE/2.0,  FLOOR_Y_POSITION, -FLOOR_Z_SIZE/2.0);
    m_floor->newVertex( FLOOR_X_SIZE/2.0,  FLOOR_Y_POSITION,  FLOOR_Z_SIZE/2.0);
    m_floor->newTriangle(3,4,5);

    for(int n=0; n<6; n++)
    {
      cVertex* curVertex = m_floor->getVertex(n);
      curVertex->setNormal(0,1,0);
    }

    // Give him some material properties...
    cMaterial material;
    material.m_ambient.set( 0.2, 0.2, 0.2, 1.0 );
    material.m_diffuse.set( 0.6, 0.6, 0.6, 1.0 );
    material.m_specular.set( 0.9, 0.9, 0.9, 1.0 );
    material.setShininess(100);
    m_floor->m_material = material;

    // Create an initial ball
    CBall* b = new CBall();
    m_active_balls.push_back(b);
    cVector3d pos(-1.0,0,1.0);
    b->setPos(pos);
    world->addChild(b);

    // Create a series of masses connected by springs
    for(int i=1; i<INITIAL_NUM_BALLS; i++) {
      add_ball();
    }
    simulationOn = false;
}
bool ch_proxyPointForceAlgo::computeNextProxyPositionWithContraints22(const cVector3d& a_goalGlobalPos, const cVector3d& a_toolVel)
{
    // The proxy is now constrained by two triangles and can only move along
    // a virtual line; we now calculate the nearest point to the original
    // goal (device position) along this line by projecting the ideal
    // goal onto the line.
    //
    // The line is expressed by the cross product of both surface normals,
    // which have both been oriented to point away from the device
    cVector3d line;
    m_collisionRecorderConstraint0.m_nearestCollision.m_globalNormal.crossr(m_collisionRecorderConstraint1.m_nearestCollision.m_globalNormal, line);

    // check result.
    if (line.equals(cVector3d(0,0,0)))
    {
        m_nextBestProxyGlobalPos = m_proxyGlobalPos;
        m_algoCounter = 0;
        m_numContacts = 2;
        return (false);
    }

    line.normalize();

    // Compute the projection of the device position (goal) onto the line; this
    // gives us the new goal position.
    cVector3d goalGlobalPos = cProjectPointOnLine(a_goalGlobalPos, m_proxyGlobalPos, line);

    // A vector from the proxy to the goal
    cVector3d vProxyToGoal;
    goalGlobalPos.subr(m_proxyGlobalPos, vProxyToGoal);

    // If the distance between the proxy and the goal position (device) is
    // very small then we can be considered done.
    if (goalAchieved(m_proxyGlobalPos, goalGlobalPos))
    {
        m_nextBestProxyGlobalPos = m_proxyGlobalPos;
        m_algoCounter = 0;
        m_numContacts = 2;
        return (false);
    }

    // compute the normalized form of the vector going from the
    // current proxy position to the desired goal position
    cVector3d vProxyToGoalNormalized;
    vProxyToGoal.normalizer(vProxyToGoalNormalized);

    // Test whether the path from the proxy to the goal is obstructed.
    // For this we create a segment that goes from the proxy position to
    // the goal position plus a little extra to take into account the
    // physical radius of the proxy.
    cVector3d targetPos = goalGlobalPos +
                          cMul(m_epsilonCollisionDetection, vProxyToGoalNormalized);

    // setup collision detector
    m_collisionSettings.m_collisionRadius = m_radius;

    // search for collision
    m_collisionSettings.m_adjustObjectMotion = false;
    m_collisionRecorderConstraint2.clear();
    bool hit = m_world->computeCollisionDetection( m_proxyGlobalPos,
               targetPos,
               m_collisionRecorderConstraint2,
               m_collisionSettings);

    // check if collision occurred between proxy and goal positions.
    double collisionDistance;
    if (hit)
    {
        collisionDistance = sqrt(m_collisionRecorderConstraint2.m_nearestCollision.m_squareDistance);
        if (collisionDistance > (cDistance(m_proxyGlobalPos, goalGlobalPos) + CHAI_SMALL))
        {
            hit = false;
        }
        else
        {
            // a collision has occurred and we check if the distance from the
            // proxy to the collision is smaller than epsilon. If yes, then
            // we reduce the epsilon term in order to avoid possible "pop through"
            // effect if we suddenly push the proxy "up" again.
            if (collisionDistance < m_epsilon)
            {
                m_epsilon = collisionDistance;
                if (m_epsilon < m_epsilonMinimalValue)
                {
                    m_epsilon = m_epsilonMinimalValue;
                }
            }
        }
    }

    // If no collision occurs, we move the proxy to its goal, unless
    // friction prevents us from doing so
    if (!hit)
    {
        cVector3d normal = cMul(0.5,cAdd(m_collisionRecorderConstraint0.m_nearestCollision.m_globalNormal,
                                         m_collisionRecorderConstraint1.m_nearestCollision.m_globalNormal));

        testFrictionAndMoveProxy(goalGlobalPos,
                                 m_proxyGlobalPos,
                                 normal,
                                 m_collisionRecorderConstraint1.m_nearestCollision.m_triangle->getParent(), a_toolVel);
        m_numContacts = 2;
        m_algoCounter = 0;

        return (false);
    }

    //-----------------------------------------------------------------------
    // THIRD COLLISION OCCURES:
    //-----------------------------------------------------------------------
    // We want the center of the proxy to move as far toward the triangle as it can,
    // but we want it to stop when the _sphere_ representing the proxy hits the
    // triangle.  We want to compute how far the proxy center will have to
    // be pushed _away_ from the collision point - along the vector from the proxy
    // to the goal - to keep a distance m_radius between the proxy center and the
    // triangle.
    //
    // So we compute the cosine of the angle between the normal and proxy-goal vector...
    double cosAngle = vProxyToGoalNormalized.dot(m_collisionRecorderConstraint2.m_nearestCollision.m_globalNormal);

    // Now we compute how far away from the collision point - _backwards_
    // along vProxyGoal - we have to put the proxy to keep it from penetrating
    // the triangle.
    //
    // If only ASCII art were a little more expressive...
    double distanceTriangleProxy = m_epsilon / cAbs(cosAngle);
    if (distanceTriangleProxy > collisionDistance) {
        distanceTriangleProxy = cMax(collisionDistance, m_epsilon);
    }

    // We compute the projection of the vector between the proxy and the collision
    // point onto the normal of the triangle.  This is the direction in which
    // we'll move the _goal_ to "push it away" from the triangle (to account for
    // the radius of the proxy).

    // A vector from the most recent collision point to the proxy
    cVector3d vCollisionToProxy;
    m_proxyGlobalPos.subr(m_contactPoint2->m_globalPos, vCollisionToProxy);

    // Move the proxy to the collision point, minus the distance along the
    // movement vector that we computed above.
    //
    // Note that we're adjusting the 'proxy' variable, which is just a local
    // copy of the proxy position.  We still might decide not to move the
    // 'real' proxy due to friction.
    cVector3d vColNextGoal;
    vProxyToGoalNormalized.mulr(-distanceTriangleProxy, vColNextGoal);
    cVector3d nextProxyPos;
    m_contactPoint2->m_globalPos.addr(vColNextGoal, nextProxyPos);

    // we can now set the next position of the proxy
    m_nextBestProxyGlobalPos = nextProxyPos;
    m_algoCounter = 0;
    m_numContacts = 3;

    // TODO: There actually should be a third friction test to see if we
    // can make it to our new goal position, but this is generally such a
    // small movement in one iteration that it's irrelevant...

    return (true);
}
Esempio n. 26
0
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);
}
Esempio n. 27
0
void updateHaptics(void)
{
	// reset simulation clock
	simClock.reset();
	simClock.start();

    // main haptic simulation loop
    while(simulationRunning)
    {
        // read position from haptic device
        cVector3d pos;
        hapticDevice->getPosition(pos);
        pos.mul(workspaceScaleFactor);
        device->setPos(pos);

        // init temp variable
        cVector3d force;
        force.zero();

        // compute reaction forces
        list<cGELMesh*>::iterator i;

        // model water level
        for(i = defWorld->m_gelMeshes.begin(); i != defWorld->m_gelMeshes.end(); ++i)
        {
            cGELMesh *nextItem = *i;

            if (nextItem->m_useMassParticleModel)
            {
                int numVertices = nextItem->m_gelVertices.size();
                for (int i=0; i<numVertices; i++)
                {
                   cVector3d nodePos = nextItem->m_gelVertices[i].m_massParticle->m_pos;
                   cVector3d force = cVector3d(-0.002 * nodePos.x, -0.002 * nodePos.y, 0.0);
                   if (nodePos.z < level)
                   {
                        double depth = nodePos.z - level;
                        force.add(cVector3d(0,0,-100*depth));
                   }
                   nextItem->m_gelVertices[i].m_massParticle->setExternalForce(force);
                }
            }

            if (nextItem->m_useSkeletonModel)
            {
                list<cGELSkeletonNode*>::iterator i;
                for(i = nextItem->m_nodes.begin(); i != nextItem->m_nodes.end(); ++i)
                {
                    cGELSkeletonNode* node = *i;
                    cVector3d nodePos = node->m_pos;
                    double radius = node->m_radius;
                    cVector3d force = cVector3d(-0.01 * nodePos.x, -0.01 * (nodePos.y), 0.0);
                    if ((nodePos.z-radius) < level)
                    {
                        double depth = (nodePos.z-radius) - level;
                        force.add(cVector3d(0,0,-1.0 * depth));
                        node->m_vel.mul(0.95);
                    }
                    node->setExternalForce(force);
                }
            }
        }


        // compute haptic feedback
		for(i = defWorld->m_gelMeshes.begin(); i != defWorld->m_gelMeshes.end(); ++i)
		{
			cGELMesh *nextItem = *i;

			if (nextItem->m_useMassParticleModel)
			{
				int numVertices = nextItem->m_gelVertices.size();
				for (int i=0; i<numVertices; i++)
				{
				cVector3d nodePos = nextItem->m_gelVertices[i].m_massParticle->m_pos;
				cVector3d f = computeForce(pos, deviceRadius, nodePos, radius, stiffness);
				if (f.lengthsq() > 0)
				{
					cVector3d tmpfrc = cNegate(f);
					nextItem->m_gelVertices[i].m_massParticle->setExternalForce(tmpfrc);
				}
				force.add(cMul(1.0, f));
				}
			}

			if (nextItem->m_useSkeletonModel)
			{
				list<cGELSkeletonNode*>::iterator i;
				for(i = nextItem->m_nodes.begin(); i != nextItem->m_nodes.end(); ++i)
				{
					cGELSkeletonNode* node = *i;
					cVector3d nodePos = node->m_pos;
					double radius = node->m_radius;
					cVector3d f = computeForce(pos, deviceRadius, nodePos, radius, stiffness);
					if (f.lengthsq() > 0)
					{
						cVector3d tmpfrc = cNegate(f);
						node->setExternalForce(tmpfrc);
					}
					force.add(cMul(4.0, f));
				}
			}
		}

        // integrate dynamics
		double interval = simClock.stop();
		simClock.reset();
		simClock.start();

        if (interval > 0.001) { interval = 0.001; }
        defWorld->updateDynamics(interval);

        // scale force
        force.mul(0.6 * deviceForceScale);

        // water viscosity
        if ((pos.z - deviceRadius) < level)
        {
            // read damping properties of haptic device
            cHapticDeviceInfo info = hapticDevice->getSpecifications();
            double Kv = 0.8 * info.m_maxLinearDamping;

            // read device velocity
            cVector3d linearVelocity;
            hapticDevice->getLinearVelocity(linearVelocity);

            // compute a scale factor [0,1] proportional to percentage
            // of tool volume immersed in the water
            double val = (level - (pos.z - deviceRadius)) / (2.0 * deviceRadius);
            double scale = cClamp(val, 0.1, 1.0);

            // compute force
            cVector3d forceDamping = cMul(-Kv * scale, linearVelocity);
            force.add(forceDamping);
        }

        // send forces to haptic device
        hapticDevice->setForce(force);
    }

    // exit haptics thread
    simulationFinished = true;
}
Esempio n. 28
0
int main(int argc, char* argv[])
{
    //-----------------------------------------------------------------------
    // INITIALIZATION
    //-----------------------------------------------------------------------

    printf ("\n");
    printf ("-----------------------------------\n");
    printf ("CHAI3D\n");
    printf ("Demo:  10-oring\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 ("[x] - Exit application\n");
    printf ("\n\n>\r");

    // parse first arg to try and locate resources
    string 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.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);

    // 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();

    // 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 a radius for the tool
    tool->setRadius(0.03);

    // 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
    //-----------------------------------------------------------------------

    // create a torus object (o-ring)
    object = new cShapeTorus(0.24, 0.50);

    // add object to world
    world->addChild(object);

    // set the position of the object at the center of the world
    object->setLocalPos(0.0, 0.0, 0.0);

    // rotate object of 90 degrees around its y-axis so that it
    // stands vertically
    object->rotateAboutGlobalAxisDeg( cVector3d(0, 1, 0), 90);

    // set the material stiffness to 100% of the maximum permitted stiffness
    // of the haptic device
    object->m_material->setStiffness(1.00 * stiffnessMax);

    // set some environmental texture and material properties
    object->m_texture = new cTexture2d();

    // load texture file
	bool fileload = object->m_texture->loadFromFile(RESOURCE_PATH("resources/images/spheremap-6.jpg"));
	if (!fileload)
	{
		//fileload = object->m_texture->loadFromFile("../../../bin/resources/images/spheremap-6.jpg");
		fileload = object->m_texture->loadFromFile("resources/images/spheremap-6.jpg");
	}
	if (!fileload)
	{
		printf("Error - Texture image failed to load correctly.\n");
		close();
		return (-1);
	}

    // setup texture and material properties
    object->setUseTexture(true);
    object->m_texture->setSphericalMappingEnabled(true);
    object->m_material->m_ambient.set(0.9, 0.9, 0.9);
    object->m_material->m_diffuse.set(0.9, 0.9, 0.9);
    object->m_material->m_specular.set(1.0, 1.0, 1.0);

    // create a haptic effect for this object so that the operator can
    // feel its surface
    cEffectSurface* newEffect = new cEffectSurface(object);
    object->addEffect(newEffect);


    //-----------------------------------------------------------------------
    // WIDGETS
    //-----------------------------------------------------------------------

    // create a font
    cFont *font = NEW_CFONTCALIBRI20();
    
    // create a label to display the haptic rate of the simulation
    labelHapticRate = new cLabel(font);
    camera->m_frontLayer->addChild(labelHapticRate);

    level = new cLevel();
    camera->m_frontLayer->addChild(level);
    level->setLocalPos(100,100,0);
    level->setRange(0.0, 25.0);

    dial = new cDial();
    camera->m_frontLayer->addChild(dial);
    dial->setSingleIncrementDisplay(false);
    dial->setLocalPos(600,100,0);
    dial->setRange(0.0, 5.0);
    dial->setSize(60);
    dial->setValue0(0.0);


    //-----------------------------------------------------------------------
    // 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 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);
    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);
}
Esempio n. 29
0
int main(int argc, char* argv[])
{
    //-----------------------------------------------------------------------
    // INITIALIZATION
    //-----------------------------------------------------------------------

    printf ("\n");
    printf ("-----------------------------------\n");
    printf ("CHAI3D\n");
    printf ("Demo: 40-ODE-cubic\n");
    printf ("Copyright 2003-2011\n");
    printf ("-----------------------------------\n");
    printf ("\n\n");
    printf ("Instructions:\n\n");
    printf ("- Use haptic device and user switch to manipulate cubes \n");
    printf ("\n\n");
    printf ("Keyboard Options:\n\n");
    printf ("[1] - Enable gravity\n");
    printf ("[2] - Disable gravity\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->m_backgroundColor.setWhite();

    // 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 (2.5, 0.0, 0.3),    // camera position (eye)
        cVector3d (0.0, 0.0, -0.5),    // 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.1, 4.0);
    camera->setUseShadowCasting(true);
    camera->setUseMultipassTransparency(true);

    // create a light source and attach it to the camera
    light = new cSpotLight(world);
    world->addChild(light);                   // attach light to camera
    light->setEnabled(true);                   // enable light source
    light->setLocalPos(cVector3d( 1.5, 0.5, 1.5));  // position the light source
    light->setDir(cVector3d(-1.0, -0.5, -1.0));  // define the direction of the light beam
    light->m_ambient.set(0.6, 0.6, 0.6);
    light->m_diffuse.set(0.8, 0.8, 0.8);
    light->m_specular.set(0.8, 0.8, 0.8);
    light->m_shadowMap->setEnabled(true);
    light->setCutOffAngleDeg(40);
  //  light->setDisplaySettings(0.05, 4.0, true);
    //light->setDisplayEnabled(true);
    //light->setShowFrame(true);
    //light->setShowEnabled(true);

    cDirectionalLight* light2 = new cDirectionalLight(world);
    world->addChild(light2);                   // attach light to camera
    light2->setEnabled(true);                   // enable light source
    light2->setDir(cVector3d(-1.0, 0.0, -1.0));  // define the direction of the light beam
    light2->m_ambient.set(0.3, 0.3, 0.3);
    light2->m_diffuse.set(0.6, 0.6, 0.6);
    light2->m_specular.set(0.0, 0.0, 0.0);

    //-----------------------------------------------------------------------
    // 2D - WIDGETS
    //-----------------------------------------------------------------------

	/*
    // create a 2D bitmap logo
    logo = new cBitmap();

    // add logo to the front plane
    camera->m_frontLayer->addChild(logo);

    // load a "chai3d" bitmap image file
    logo->setImage (NEW_CHAI3D_LOGO());

    // position the logo at the bottom left of the screen (pixel coordinates)
    logo->setLocalPos(10, 10, 0);

    // scale the logo along its horizontal and vertical axis
    logo->setZoom(0.25, 0.25);

    // 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->setTransparentColor(0x00, 0x00, 0x00, 0x00);

    // enable transparency
    logo->setUseTransparency(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 cToolGripper(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.3);

    // define a radius for the tool (graphical display)
    tool->setRadius(0.03);

    // hide the device sphere. only show proxy.
    tool->setShowContactPoints(true, false);

    // set the physical readius of the proxy.
    proxyRadius = 0.03;
    tool->setRadiusContact(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->enableDynamicObjects(true);

    // ajust the color of the tool
   // tool->m_materialProxy = tool->m_materialProxyButtonPressed;

    // 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
    stiffnessMax = info.m_maxLinearStiffness / workspaceScaleFactor;

    // create a small white line that will be enabled every time the operator
    // grasps an object. The line indicated the connection between the
    // position of the tool and the grasp position on the object
    graspLine = new cShapeLine(cVector3d(0,0,0), cVector3d(0,0,0));
    world->addChild(graspLine);
    graspLine->m_colorPointA.set(1.0, 1.0, 1.0);
    graspLine->m_colorPointB.set(1.0, 1.0, 1.0);
    graspLine->setShowEnabled(false);


    //-----------------------------------------------------------------------
    // COMPOSE THE VIRTUAL SCENE
    //-----------------------------------------------------------------------

    // create an ODE world to simulate dynamic bodies
    ODEWorld = new cODEWorld(world);

    // add ODE world as a node inside world
    world->addChild(ODEWorld);

    // set some gravity
    ODEWorld->setGravity(cVector3d(0.0, 0.0, -9.81));

    // create a new ODE object that is automatically added to the ODE world
    ODEBody0 = new cODEGenericBody(ODEWorld);
    ODEBody1 = new cODEGenericBody(ODEWorld);
    ODEBody2 = new cODEGenericBody(ODEWorld);

    // create a virtual mesh  that will be used for the geometry
    // representation of the dynamic body
    cMesh* object0 = new cMesh();
    cMesh* object1 = new cMesh();
    cMesh* object2 = new cMesh();

    // crate a cube mesh
    double boxSize = 0.2;
    createCube(object0, boxSize);
    createCube(object1, boxSize);
    createCube(object2, boxSize);

    // define some material properties for each cube
    cMaterial mat0, mat1, mat2;
    mat0.m_ambient.set(0.8, 0.1, 0.4);
    mat0.m_diffuse.set(1.0, 0.15, 0.5);
    mat0.m_specular.set(1.0, 0.2, 0.8);
	mat0.setRedIndian();
	mat0.m_specular.set(0.0, 0.0, 0.0);
    mat0.setStiffness(0.5 * stiffnessMax);
    mat0.setDynamicFriction(0.6);
    mat0.setStaticFriction(0.6);
    object0->setMaterial(mat0);

    mat1.m_ambient.set(0.2, 0.6, 0.0);
    mat1.m_diffuse.set(0.2, 0.8, 0.0);
    mat1.m_specular.set(0.2, 1.0, 0.0);
	mat1.setBlueRoyal();
	mat1.m_specular.set(0.0, 0.0, 0.0);
    mat1.setStiffness(0.5 * stiffnessMax);
    mat1.setDynamicFriction(0.6);
    mat1.setStaticFriction(0.6);
    object1->setMaterial(mat1);

    mat2.m_ambient.set(0.0, 0.2, 0.6);
    mat2.m_diffuse.set(0.0, 0.2, 0.8);
    mat2.m_specular.set(0.0, 0.2, 1.0);
	mat2.setGreenDarkSea();
	mat2.m_specular.set(0.0, 0.0, 0.0);
    mat2.setStiffness(0.5 * stiffnessMax);
    mat2.setDynamicFriction(0.6);
    mat2.setStaticFriction(0.6);
    object2->setMaterial(mat2);

    // add mesh to ODE object
    ODEBody0->setImageModel(object0);
    ODEBody1->setImageModel(object1);
    ODEBody2->setImageModel(object2);

    // create a dynamic model of the ODE object. Here we decide to use a box just like
    // the object mesh we just defined
    ODEBody0->createDynamicBox(boxSize, boxSize, boxSize);
    ODEBody1->createDynamicBox(boxSize, boxSize, boxSize, false, cVector3d(1,1,1));
    ODEBody2->createDynamicBox(boxSize, boxSize, boxSize);

    // define some mass properties for each cube
    ODEBody0->setMass(0.05);
    ODEBody1->setMass(0.05);
    ODEBody2->setMass(0.05);

    // set position of each cube
    cVector3d tmpvct;
    tmpvct = cVector3d(0.0,-0.6, -0.5);
    ODEBody0->setPosition(tmpvct);
    tmpvct = cVector3d(0.0, 0.6, -0.5);
    ODEBody1->setPosition(tmpvct);
    tmpvct = cVector3d(0.0, 0.0, -0.5);
    ODEBody2->setPosition(tmpvct);

    // rotate central cube of 45 degrees (just to show hoe this works!)
    cMatrix3d rot;
    rot.identity();
    rot.rotateAboutGlobalAxisRad(cVector3d(0,0,1), cDegToRad(45));
    ODEBody0->setRotation(rot);

    // we create 6 static walls to contains the 3 cubes within a limited workspace
    ODEGPlane0 = new cODEGenericBody(ODEWorld);
    ODEGPlane1 = new cODEGenericBody(ODEWorld);
    ODEGPlane2 = new cODEGenericBody(ODEWorld);
    ODEGPlane3 = new cODEGenericBody(ODEWorld);
    ODEGPlane4 = new cODEGenericBody(ODEWorld);
    ODEGPlane5 = new cODEGenericBody(ODEWorld);

    double size = 1.0;
    ODEGPlane0->createStaticPlane(cVector3d(0.0, 0.0,  2.0 *size), cVector3d(0.0, 0.0 ,-1.0));
    ODEGPlane1->createStaticPlane(cVector3d(0.0, 0.0, -size), cVector3d(0.0, 0.0 , 1.0));
    ODEGPlane2->createStaticPlane(cVector3d(0.0,  size, 0.0), cVector3d(0.0,-1.0, 0.0));
    ODEGPlane3->createStaticPlane(cVector3d(0.0, -size, 0.0), cVector3d(0.0, 1.0, 0.0));
    ODEGPlane4->createStaticPlane(cVector3d( size, 0.0, 0.0), cVector3d(-1.0,0.0, 0.0));
    ODEGPlane5->createStaticPlane(cVector3d(-0.8 * size, 0.0, 0.0), cVector3d( 1.0,0.0, 0.0));

    //////////////////////////////////////////////////////////////////////////
    // Create some reflexion
    //////////////////////////////////////////////////////////////////////////

	/*
    // we create an intermediate node to which we will attach
    // a copy of the object located inside the world
    cGenericObject* reflexion = new cGenericObject();

    // set this object as a ghost node so that no haptic interactions or
    // collision detecting take place within the child nodes added to the
    // reflexion node.
    reflexion->setGhostEnabled(true);

    // add reflexion node to world
    world->addChild(reflexion);

    // turn off culling on each object (objects now get rendered on both sides)
    object0->setUseCulling(false, true);
    object1->setUseCulling(false, true);
    object2->setUseCulling(false, true);

    // create a symmetry rotation matrix (z-plane)
    cMatrix3d rotRefexion;
    rotRefexion.set(1.0, 0.0, 0.0,
                    0.0, 1.0, 0.0,
                    0.0, 0.0, -1.0);
    reflexion->setLocalRot(rotRefexion);
    reflexion->setLocalPos(0.0, 0.0, -2.005);

    // add objects to the world
    reflexion->addChild(ODEWorld);
    reflexion->addChild(tool);
	*/

    //////////////////////////////////////////////////////////////////////////
    // Create a Ground
    //////////////////////////////////////////////////////////////////////////

    // create mesh to model ground surface
    cMesh* ground = new cMesh();
    world->addChild(ground);
	//cCreateCylinder(ground, 0.01, 2.0, 36, 1, true, true);


    // create 4 vertices (one at each corner)
    double groundSize = 1.3;
    int vertices0 = ground->newVertex(-groundSize, -1.0 *groundSize, 0.0);
    int vertices1 = ground->newVertex( groundSize, -1.0 *groundSize, 0.0);
    int vertices2 = ground->newVertex( groundSize,  1.0 *groundSize, 0.0);
    int vertices3 = ground->newVertex(-groundSize,  1.0 *groundSize, 0.0);

    // compose surface with 2 triangles
    ground->newTriangle(vertices0, vertices1, vertices2);
    ground->newTriangle(vertices0, vertices2, vertices3);

    // compute surface normals
    ground->computeAllNormals();

    // position ground at the right level
    ground->setLocalPos(0.0, 0.0, -1.0);

    // define some material properties and apply to mesh
    cMaterial matGround;
    matGround.setStiffness(0.5 * stiffnessMax);
    matGround.setDynamicFriction(0.2);
    matGround.setStaticFriction(0.0);
  //  matGround.m_ambient.set(0.0, 0.0, 0.0);
  //  matGround.m_diffuse.set(0.0, 0.0, 0.0);
  //  matGround.m_specular.set(0.0, 0.0, 0.0);
	matGround.setWhite();
	matGround.m_emission.setGrayLevel(0.2);
	ground->setMaterial(matGround);

    // enable and set transparency level of ground
   // ground->setTransparencyLevel(0.7);
   // ground->setUseTransparency(true);

    // setup collision detector
    ground->createAABBCollisionDetector(proxyRadius);


    //-----------------------------------------------------------------------
    // 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("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
    //-----------------------------------------------------------------------

    // simulation in now running
    simulationRunning = true;

    // 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);
    }
Esempio n. 30
0
//===========================================================================
bool cEffectMagnet::computeForce(const cVector3d& a_toolPos,
                                  const cVector3d& a_toolVel,
                                  const unsigned int& a_toolID,
                                  cVector3d& a_reactionForce)
{
    // compute distance from object to tool
    double distance = cDistance(a_toolPos, m_parent->m_interactionProjectedPoint);

    // get parameters of magnet
    double magnetMaxForce = m_parent->m_material.getMagnetMaxForce();
    double magnetMaxDistance = m_parent->m_material.getMagnetMaxDistance();
    double stiffness = m_parent->m_material.getStiffness();
    double forceMagnitude = 0;

    if ((distance > 0) && (distance < magnetMaxDistance) && (stiffness > 0))
    {
        double limitLinearModel = magnetMaxForce / stiffness;
        cClamp(limitLinearModel, 0.0, 0.5 * distance);

        if (distance < limitLinearModel)
        {
            // apply local linear model near magnet
            forceMagnitude = stiffness * distance;
        }
        else
        {
            // compute quadratic model
            cMatrix3d sys;
            sys.m[0][0] = limitLinearModel * limitLinearModel;
            sys.m[0][1] = limitLinearModel;
            sys.m[0][2] = 1.0;
            sys.m[1][0] = magnetMaxDistance * magnetMaxDistance;
            sys.m[1][1] = magnetMaxDistance;
            sys.m[1][2] = 1.0;
            sys.m[2][0] = 2.0 * limitLinearModel;
            sys.m[2][1] = 1.0;
            sys.m[2][2] = 0.0;
            sys.invert();

            cVector3d param;
            sys.mulr(cVector3d(magnetMaxForce, 0.0, -1.0), param);

            // apply quadratic model
            double val = distance - limitLinearModel;
            forceMagnitude = param.x * val * val + param.y * val + param.z;
        }

        // compute magnetic force
        a_reactionForce = cMul(forceMagnitude, cNormalize(cSub(m_parent->m_interactionProjectedPoint, a_toolPos)));

        // add damping component
        double viscosity = m_parent->m_material.getViscosity();
        cVector3d viscousForce = cMul(-viscosity, a_toolVel);
        a_reactionForce.add(viscousForce);

        return (true);
    }
    else
    {
        // the tool is located outside the magnet zone
        a_reactionForce.zero();
        return (false);
    }
}