Пример #1
0
   void CQTOpenGLUserFunctions::DrawCircle(const CVector3& c_position,
                                           const CQuaternion& c_orientation,
                                           Real f_radius,
                                           const CColor& c_color,
                                           const bool b_fill,
                                           GLuint un_vertices) {
      /* Save attributes and current matrix */
      glPushAttrib(GL_POLYGON_BIT);
      /* Set color */
      SetColor(c_color);
      /* Disable face culling, to make the triangle visible from any angle */
	    glDisable(GL_CULL_FACE);
      /* Set polygon attributes */
	    glEnable(GL_POLYGON_SMOOTH);
      glPolygonMode(GL_FRONT_AND_BACK, b_fill ? GL_FILL : GL_LINE);
      /* Set position/orientation */
      Rototranslate(c_position, c_orientation);
      /*  Draw */
	    CVector2 cVertex(f_radius, 0.0f);
	    CRadians cAngle(CRadians::TWO_PI / un_vertices);
      glBegin(GL_POLYGON);
      glNormal3f(0.0f, 0.0f, 1.0f);
      for(size_t i = 0; i < un_vertices; ++i) {
         glVertex3f(cVertex.GetX(), cVertex.GetY(), 0.0f);
         cVertex.Rotate(cAngle);
      }
      glEnd();
      /* Restore saved stuff */
      glPopAttrib();
   }
 void CQTOpenGLEPuck::RenderLED() {
    /* Side surface */
    CVector2 cVertex(BODY_RADIUS, 0.0f);
    CRadians cAngle(CRadians::TWO_PI / m_unVertices);
    CVector2 cNormal(1.0f, 0.0f);
    glBegin(GL_QUAD_STRIP);
    for(GLuint i = 0; i <= m_unVertices / 8; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), 0.0f);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), LED_ELEVATION + LED_HEIGHT);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), LED_ELEVATION);
       cVertex.Rotate(cAngle);
       cNormal.Rotate(cAngle);
    }
    glEnd();
    /* Top surface  */
    cVertex.Set(BODY_RADIUS, 0.0f);
    CVector2 cVertex2(LED_UPPER_RING_INNER_RADIUS, 0.0f);
    glBegin(GL_QUAD_STRIP);
    glNormal3f(0.0f, 0.0f, 1.0f);      
    for(GLuint i = 0; i <= m_unVertices / 8; i++) {         
       glVertex3f(cVertex2.GetX(), cVertex2.GetY(), BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT);
       cVertex.Rotate(cAngle);
       cVertex2.Rotate(cAngle);
    }
    glEnd();
 }
//===========================================================================
void cDirectionalLight::setDir(const cVector3d& a_direction)
{

    // We arbitrarily point lights along the x axis of the stored
    // rotation matrix... this allows matrix transformations
    // to apply to lights.
    // m_localRot.setCol0(a_direction);

    cVector3d c0, c1, c2, t0, t1;
    a_direction.copyto(c0);

    // check vector
    if (c0.lengthsq() < 0.0001) {
        return;
    }

    // normalize direction vector
    c0.normalize();

    // compute 2 vector perpendicular to a_direction
    t0.set(0.0, 0.0, 1.0);
    t1.set(0.0, 1.0, 0.0);
    double a0 = cAngle(c0, t0);
    double a1 = cAngle(c0, t1);

    if (sin(a0) > sin(a1))
    {
        c0.crossr(t0, c1);
        c0.crossr(c1, c2);
    }
    else
    {
        c0.crossr(t1, c1);
        c0.crossr(c1, c2);
    }

    c1.normalize();
    c2.normalize();

    // update rotation matrix
    m_localRot.setCol(c0,c1,c2);
}
Пример #4
0
   void CQTOpenGLCylinder::MakeBody() {
      /* Since this shape can be stretched,
         make sure the normal vectors are unit-long */
      glEnable(GL_NORMALIZE);

      /* Set the material */
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, SPECULAR);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, SHININESS);
      glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, EMISSION);

      /* Let's start the actual shape */
      /* Side surface */
      CVector2 cVertex(1.0f, 0.0f);
      CRadians cAngle(CRadians::TWO_PI / m_unVertices);
      glBegin(GL_QUAD_STRIP);
      for(GLuint i = 0; i <= m_unVertices; i++) {
         glNormal3f(cVertex.GetX(), cVertex.GetY(), 0.0f);
         glVertex3f(cVertex.GetX(), cVertex.GetY(), 1.0f);
         glVertex3f(cVertex.GetX(), cVertex.GetY(), 0.0f);
         cVertex.Rotate(cAngle);
      }
      glEnd();
      /* Top disk */
      cVertex.Set(1.0f, 0.0f);
      glBegin(GL_POLYGON);
      glNormal3f(0.0f, 0.0f, 1.0f);
      for(GLuint i = 0; i <= m_unVertices; i++) {
         glVertex3f(cVertex.GetX(), cVertex.GetY(), 1.0f);
         cVertex.Rotate(cAngle);
      }
      glEnd();
      /* Bottom disk */
      cVertex.Set(1.0f, 0.0f);
      cAngle = -cAngle;
      glBegin(GL_POLYGON);
      glNormal3f(0.0f, 0.0f, -1.0f);
      for(GLuint i = 0; i <= m_unVertices; i++) {
         glVertex3f(cVertex.GetX(), cVertex.GetY(), 0.0f);
         cVertex.Rotate(cAngle);
      }
      glEnd();
      /* The shape definition is finished */

      /* We don't need it anymore */
      glDisable(GL_NORMALIZE);

   }
Пример #5
0
   void CQTOpenGLUserFunctions::DrawCircle(Real f_radius,
                                           const CVector3& c_center_offset,
                                           const CColor& c_color,
                                           const bool b_fill,
                                           const CQuaternion& c_orientation,
                                           GLuint un_vertices) {

	    glDisable(GL_LIGHTING);
	    glDisable(GL_CULL_FACE);

	    glColor3ub(c_color.GetRed(),
                 c_color.GetGreen(),
                 c_color.GetBlue());

	    CVector3 cVertex(f_radius, 0.0f, 0.0f);
	    CRadians cAngle(CRadians::TWO_PI / un_vertices);

      if(b_fill) {
         glBegin(GL_POLYGON);
      }
      else {
         glBegin(GL_LINE_LOOP);
      }
      CVector3 cNormalDirection(0.0f, 0.0f, 1.0f);
      cNormalDirection.Rotate(c_orientation);
      glNormal3f(cNormalDirection.GetX(),
                 cNormalDirection.GetY(),
                 cNormalDirection.GetZ());

      /* Compute the quaternion defining the rotation of the vertices used to draw the circle. */
      CQuaternion cVertexRotation;
      CVector3 cVertexRotationAxis(0.0f, 0.0f, 1.0f);
      cVertexRotationAxis.Rotate(c_orientation);
      cVertexRotation.FromAngleAxis(cAngle, cVertexRotationAxis);

	    cVertex.Rotate(c_orientation);
      for(GLuint i = 0; i <= un_vertices; i++) {
         glVertex3f(cVertex.GetX() + c_center_offset.GetX(),
                    cVertex.GetY() + c_center_offset.GetY(),
                    cVertex.GetZ() + c_center_offset.GetZ());
         cVertex.Rotate(cVertexRotation);
      }
      glEnd();

      glEnable(GL_CULL_FACE);
      glEnable(GL_LIGHTING);
   }
Пример #6
0
 void CQTOpenGLUserFunctions::DrawCylinder(const CVector3& c_position,
                                           const CQuaternion& c_orientation,
                                           Real f_radius,
                                           Real f_height,
                                           const CColor& c_color,
                                           GLuint un_vertices) {
    /* Save current matrix */
    glPushMatrix();
    /* Set color */
    SetColor(c_color);
    /* Set position/orientation */
    Rototranslate(c_position, c_orientation);
    /* Draw side surface */
    Real fHalfHeight = f_height * 0.5f;
    CVector2 cVertex(1.0f, 0.0f);
    CRadians cAngle(CRadians::TWO_PI / un_vertices);
    glBegin(GL_QUAD_STRIP);
    for(GLuint i = 0; i <= un_vertices; i++) {
       glNormal3f(cVertex.GetX(), cVertex.GetY(), 0.0f);
       glVertex3f(cVertex.GetX() * f_radius, cVertex.GetY() * f_radius,  fHalfHeight);
       glVertex3f(cVertex.GetX() * f_radius, cVertex.GetY() * f_radius, -fHalfHeight);
       cVertex.Rotate(cAngle);
    }
    glEnd();
    /* Draw top disk */
    cVertex.Set(f_radius, 0.0f);
    glBegin(GL_POLYGON);
    glNormal3f(0.0f, 0.0f, 1.0f);
    for(GLuint i = 0; i <= un_vertices; i++) {
       glVertex3f(cVertex.GetX(), cVertex.GetY(), fHalfHeight);
       cVertex.Rotate(cAngle);
    }
    glEnd();
    /* Draw bottom disk */
    cVertex.Set(f_radius, 0.0f);
    cAngle = -cAngle;
    glBegin(GL_POLYGON);
    glNormal3f(0.0f, 0.0f, -1.0f);
    for(GLuint i = 0; i <= un_vertices; i++) {
       glVertex3f(cVertex.GetX(), cVertex.GetY(), -fHalfHeight);
       cVertex.Rotate(cAngle);
    }
    glEnd();
    /* Restore saved matrix */
    glPopMatrix();
 }
 void CQTOpenGLEPuck::RenderBody() {
    /* Set material */
    SetGreenPlasticMaterial();
    CVector2 cVertex(BODY_RADIUS, 0.0f);
    CRadians cAngle(-CRadians::TWO_PI / m_unVertices);
    /* Bottom part */
    glBegin(GL_POLYGON);
    glNormal3f(0.0f, 0.0f, -1.0f);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION);
       cVertex.Rotate(cAngle);
    }
    glEnd();
    /* Side surface */
    cAngle = -cAngle;
    CVector2 cNormal(1.0f, 0.0f);
    cVertex.Set(BODY_RADIUS, 0.0f);
    glBegin(GL_QUAD_STRIP);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), 0.0f);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION + BODY_HEIGHT);
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION);
       cVertex.Rotate(cAngle);
       cNormal.Rotate(cAngle);
    }
    glEnd();
    /* Top part */
    glBegin(GL_POLYGON);
    cVertex.Set(LED_UPPER_RING_INNER_RADIUS, 0.0f);
    glNormal3f(0.0f, 0.0f, 1.0f);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glVertex3f(cVertex.GetX(), cVertex.GetY(), BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT);
       cVertex.Rotate(cAngle);
    }
    glEnd();
    /* Triangle to set the direction */
    SetLEDMaterial(1.0f, 1.0f, 0.0f);
    glBegin(GL_TRIANGLES);
    glVertex3f( BODY_RADIUS * 0.7,               0.0f, BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT + 0.001f);
    glVertex3f(-BODY_RADIUS * 0.7,  BODY_RADIUS * 0.3, BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT + 0.001f);
    glVertex3f(-BODY_RADIUS * 0.7, -BODY_RADIUS * 0.3, BODY_ELEVATION + BODY_HEIGHT + LED_HEIGHT + 0.001f);
    glEnd();
 }
 void CQTOpenGLEPuck::RenderWheel() {
    /* Set material */
    SetRedPlasticMaterial();
    /* Right side */
    CVector2 cVertex(WHEEL_RADIUS, 0.0f);
    CRadians cAngle(CRadians::TWO_PI / m_unVertices);
    CVector3 cNormal(-1.0f, -1.0f, 0.0f);
    cNormal.Normalize();
    glBegin(GL_POLYGON);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ());
       glVertex3f(cVertex.GetX(), -HALF_WHEEL_WIDTH, WHEEL_RADIUS + cVertex.GetY());
       cVertex.Rotate(cAngle);
       cNormal.RotateY(cAngle);
    }
    glEnd();
    /* Left side */
    cVertex.Set(WHEEL_RADIUS, 0.0f);
    cNormal.Set(-1.0f, 1.0f, 0.0f);
    cNormal.Normalize();
    cAngle = -cAngle;
    glBegin(GL_POLYGON);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ());
       glVertex3f(cVertex.GetX(), HALF_WHEEL_WIDTH, WHEEL_RADIUS + cVertex.GetY());
       cVertex.Rotate(cAngle);
       cNormal.RotateY(cAngle);
    }
    glEnd();
    /* Tire */
    cNormal.Set(1.0f, 0.0f, 0.0f);
    cVertex.Set(WHEEL_RADIUS, 0.0f);
    cAngle = -cAngle;
    glBegin(GL_QUAD_STRIP);
    for(GLuint i = 0; i <= m_unVertices; i++) {
       glNormal3f(cNormal.GetX(), cNormal.GetY(), cNormal.GetZ());
       glVertex3f(cVertex.GetX(), -HALF_WHEEL_WIDTH, WHEEL_RADIUS + cVertex.GetY());
       glVertex3f(cVertex.GetX(),  HALF_WHEEL_WIDTH, WHEEL_RADIUS + cVertex.GetY());
       cVertex.Rotate(cAngle);
       cNormal.RotateY(cAngle);
    }
    glEnd();
 }
Пример #9
0
//===========================================================================
void cODEGenericBody::createStaticPlane(const cVector3d& a_position,
										const cVector3d& a_normal)
{
    // object is static by default
    m_static = true;

    // temp variables
    cVector3d normal = a_normal;
    cVector3d offset(0,0,0);

    // check normal
    if (normal.length() == 0) { return; }

    // compute parameters
    normal.normalize();
    double a = normal.x;
    double b = normal.y;
    double c = normal.z;

    offset = cProject(a_position, normal);
    double d = offset.length();
    if (d > 0)
    {
        if (cAngle(offset, normal) > cDegToRad(90))
        {
            d = -d;
        }
    }

    // build fixed plane
    m_ode_geom = dCreatePlane(m_ODEWorld->m_ode_space, a, b, c, d);

    // store dynamic model type
    m_typeDynamicCollisionModel = ODE_MODEL_PLANE;

    // store dynamic model parameters
    m_paramDynColModel0 = normal.x;
    m_paramDynColModel1 = normal.y;
    m_paramDynColModel2 = normal.z;
    m_posOffsetDynColModel = a_position;
    m_rotOffsetDynColModel.identity();
}
Пример #10
0
void updateHaptics(void)
{
    // main haptic simulation loop
    while(simulationRunning)
    {
        // update position and orientation of tool
        tool->updatePose();

        // compute interaction forces
        tool->computeInteractionForces();

        // send forces to device
        tool->applyForces();

        // if the haptic device does track orientations, we automatically
        // oriente the drill to remain perpendicular to the tooth
        cVector3d pos = tool->m_proxyPointForceModel->getProxyGlobalPosition();
        cMatrix3d rot = tool->m_deviceGlobalRot;

        if (info.m_sensedRotation == false)
        {
            cVector3d pos = tool->m_proxyPointForceModel->getProxyGlobalPosition();
            rot.identity();

             cVector3d vx, vy, vz;
            cVector3d zUp (0,0,1);
            cVector3d yUp (0,1,0);
            vx = pos - tooth->getPos();
            if (vx.length() > 0.001)
            {
                vx.normalize();

                if (cAngle(vx,zUp) > 0.001)
                {
                    vy = cCross(zUp, vx);
                    vy.normalize();
                    vz = cCross(vx, vy);
                    vz.normalize();

                }
                else
                {
                    vy = cCross(yUp, vx);
                    vy.normalize();
                    vz = cCross(vx, vy);
                    vz.normalize();
                }

                rot.setCol(vx, vy, vz);
                drill->setRot(rot);
            }
        }


        int button = tool->getUserSwitch(0);
        if (button == 0)
        {
            lastPosDevice = pos;
            lastRotDevice = rot;
            lastPosObject = tooth->getPos();
            lastRotObject = tooth->getRot();
            lastDeviceObjectPos = cTrans(lastRotDevice) * ((lastPosObject - lastPosDevice) + 0.01*cNormalize(lastPosObject - lastPosDevice));
            lastDeviceObjectRot = cMul(cTrans(lastRotDevice), lastRotObject);
            tooth->setHapticEnabled(true, true);
            tool->setShowEnabled(true, true);
            drill->setShowEnabled(true, true);
        }
        else
        {
            tool->setShowEnabled(false, true);
            drill->setShowEnabled(false, true);
            cMatrix3d rotDevice01 = cMul(cTrans(lastRotDevice), rot);
            cMatrix3d newRot =  cMul(rot, lastDeviceObjectRot);
            cVector3d newPos = cAdd(pos, cMul(rot, lastDeviceObjectPos));
            tooth->setPos(newPos);
            tooth->setRot(newRot);
            world->computeGlobalPositions(true);
            tooth->setHapticEnabled(false, true);
        }

		//-----------------Jake--------------//

		char serialData[50];
		double pos1 = 0;
		double pos2 = 0;
	   
		if (sp->ReadData(serialData, strlen(serialData)) > 0)
		{
			if (sp->parse_num(serialData, pos1))
			{
				Sleep(50);
				if (pos1 > 0.3)
				{
 					pos1 = 0.126*pow(pos1,-1.07);
					pos1 = (pos1+pos1_1+pos1_2)/3;
					//pos1 = (pos1 + pos1_1 + pos1_2 + pos1_3 + pos1_4)/5;
					pos1_5 = pos1_4;
					pos1_4 = pos1_3;
					pos1_3 = pos1_2;
					pos1_2 = pos1_1;
					pos1_1 = pos1;

 					pos2 = 0.126*pow(pos2,-1.07);
					pos2 = (pos2 + pos2_1 + pos2_2 + pos2_3 + pos2_4)/5;
					pos2_5 = pos2_4;
					pos2_4 = pos2_3;
					pos2_3 = pos2_2;
					pos2_2 = pos2_1;
					pos2_1 = pos2;
				}
				else 
				{
					pos1 = previous_pos1;
					pos2 = previous_pos2;
				}

				printf("Received data %f and %f \n", pos1, pos2);
			} else 
			{
				printf("Conversion failed\n");
			}
			
		} else {
			printf("Receive failed\n");
		}

		if (pos_counter > 2)
		{
			double dx1 = pos1 - previous_pos1;
			double dx2 = pos2 - previous_pos2;

			if (abs(dx1) < 0.1)
			{
				overall_pos1 -= dx1*10;
				if (overall_pos1 < -0.1)
				{
					overall_pos1 = -0.1;
				} else if(overall_pos1 > 0)
				{
					overall_pos1 = 0;
				}
			}

			if (abs(dx2) < 0.1)
			{
				overall_pos2 -= dx2;
				if (overall_pos2 < -0.1)
				{
					overall_pos2 = -0.1;
				} else if(overall_pos2 > 0)
				{
					overall_pos2 = 0;
				}
			}
		} else {
			pos_counter++;
		}

		previous_pos1 = pos1;
		previous_pos2 = pos2;

		index_finger->setPos(pos.x - 0.15, pos.y, pos.z + overall_pos1);
		index_finger->setRot(rot);

		index_finger->computeInteractionForces();

		index_finger->updatePose();

		thumb->setPos(pos.x + 0.1, pos.y - 0.15 + overall_pos2, pos.z - 0.05);
		thumb->setRot(rot);

		thumb->computeInteractionForces();

		thumb->updatePose();

        // compute global reference frames for each object
        world->computeGlobalPositions(true);

		std::stringstream torque_str_tmp;

		double torque_temp1 = sqrt(pow(index_finger->m_lastComputedGlobalForce.x,2) + pow(index_finger->m_lastComputedGlobalForce.y,2) + pow(index_finger->m_lastComputedGlobalForce.z,2));
		double torque_temp2 = sqrt(pow(thumb->m_lastComputedGlobalForce.x,2) + pow(thumb->m_lastComputedGlobalForce.y,2) + pow(thumb->m_lastComputedGlobalForce.z,2));

		/*torque_str_tmp << std::setprecision(2) << torque_temp;

		const std::string& torque_to_send = torque_str_tmp.str();

		char to_send[50];
		strcpy(to_send, "T");
		strcat(to_send, torque_to_send.c_str());
		strcat(to_send, ";");
		*/

		char to_send[50];
		if (torque_temp1 > 0 && torque_temp2 > 0)
		{
			strcpy(to_send, "T");
			strcat(to_send, "1/1");
			strcat(to_send, ";");
		} else if (torque_temp1 == 0 && torque_temp2 > 0)
		{
			strcpy(to_send, "T");
			strcat(to_send, "0/1");
			strcat(to_send, ";");
		} else if (torque_temp1 > 0 && torque_temp2 == 0)
		{
			strcpy(to_send, "T");
			strcat(to_send, "1/0");
			strcat(to_send, ";");
		} else 
		{
			strcpy(to_send, "T");
			strcat(to_send, "0/0");
			strcat(to_send, ";");
		}

		if (sp->WriteData(to_send, strlen(to_send)))
		{
			printf("Sent %s\n", to_send);
		} else 
		{
			printf("Force data %s could not be sent\n", to_send);
		}

    }

    // exit haptics thread
    simulationFinished = true;
}
Пример #11
0
//===========================================================================
void cProxyPointForceAlgo::updateForce()
{
    // initialize variables
    double stiffness = 0.0;
    cVector3d normal;
    normal.zero();

    // if there are no contacts between proxy and environment, no force is applied
    if (m_numContacts == 0)
    {
        m_lastGlobalForce.zero();
        return;
    }

    //---------------------------------------------------------------------
    // stiffness and surface normal estimation
    //---------------------------------------------------------------------
    else if (m_numContacts == 1)
    {
        // compute stiffness
        stiffness = ( m_contactPoint0->m_triangle->getParent()->m_material.getStiffness() );

        // compute surface normal
        normal.add(m_contactPoint0->m_globalNormal);
    }

    // if there are two contact points, the stiffness is the average of the
    // stiffnesses of the two intersected triangles' meshes
    else if (m_numContacts == 2)
    {
        // compute stiffness
        stiffness = ( m_contactPoint0->m_triangle->getParent()->m_material.getStiffness() +
                      m_contactPoint1->m_triangle->getParent()->m_material.getStiffness() ) / 2.0;

        // compute surface normal
        normal.add(m_contactPoint0->m_globalNormal);
        normal.add(m_contactPoint1->m_globalNormal);
        normal.mul(1.0/2.0);
    }

    // if there are three contact points, the stiffness is the average of the
    // stiffnesses of the three intersected triangles' meshes
    else if (m_numContacts == 3)
    {
        // compute stiffness
        stiffness = ( m_contactPoint0->m_triangle->getParent()->m_material.getStiffness() +
                      m_contactPoint1->m_triangle->getParent()->m_material.getStiffness() +
                      m_contactPoint2->m_triangle->getParent()->m_material.getStiffness() ) / 3.0;

        // compute surface normal
        normal.add(m_contactPoint0->m_globalNormal);
        normal.add(m_contactPoint1->m_globalNormal);
        normal.add(m_contactPoint2->m_globalNormal);
        normal.mul(1.0/3.0);
    }

    //---------------------------------------------------------------------
    // computing a force (Hooke's law)
    //---------------------------------------------------------------------

    // compute the force by modeling a spring between the proxy and the device
    cVector3d force;
    m_proxyGlobalPos.subr(m_deviceGlobalPos, force);
    force.mul(stiffness);
    m_lastGlobalForce = force;

    // compute tangential and normal forces
    if ((force.lengthsq() > 0) && (m_numContacts > 0))
    {
        m_normalForce = cProject(force, normal);
        force.subr(m_normalForce, m_tangentialForce);
    }
    else
    {
        m_tangentialForce.zero();
        m_normalForce = force;
    }


    //---------------------------------------------------------------------
    // force shading (optional)
    //---------------------------------------------------------------------

    if ((m_useForceShading) && (m_numContacts == 1))
    {
        // get vertices and normals related to contact triangle
        cVector3d vertex0 = cAdd(m_contactPoint0->m_object->getGlobalPos(), cMul(m_contactPoint0->m_object->getGlobalRot(), m_contactPoint0->m_triangle->getVertex0()->getPos()));
        cVector3d vertex1 = cAdd(m_contactPoint0->m_object->getGlobalPos(), cMul(m_contactPoint0->m_object->getGlobalRot(), m_contactPoint0->m_triangle->getVertex1()->getPos()));
        cVector3d vertex2 = cAdd(m_contactPoint0->m_object->getGlobalPos(), cMul(m_contactPoint0->m_object->getGlobalRot(), m_contactPoint0->m_triangle->getVertex2()->getPos()));
        cVector3d normal0 = cMul(m_contactPoint0->m_object->getGlobalRot(), m_contactPoint0->m_triangle->getVertex0()->getNormal());
        cVector3d normal1 = cMul(m_contactPoint0->m_object->getGlobalRot(), m_contactPoint0->m_triangle->getVertex1()->getNormal());
        cVector3d normal2 = cMul(m_contactPoint0->m_object->getGlobalRot(), m_contactPoint0->m_triangle->getVertex2()->getNormal());

        // compute angles between normals. If the angles are very different, then do not apply shading.
        double angle01 = cAngle(normal0, normal1);
        double angle02 = cAngle(normal0, normal2);
        double angle12 = cAngle(normal1, normal2);

        if ((angle01 < m_forceShadingAngleThreshold) || (angle02 < m_forceShadingAngleThreshold) || (angle12 < m_forceShadingAngleThreshold))
        {
            double a0 = 0; 
						double a1 = 0;
            cProjectPointOnPlane(m_contactPoint0->m_globalPos, vertex0, vertex1, vertex2, a0, a1);

            cVector3d normalShaded = cAdd(
                       cMul(0.5, cAdd(cMul(a0, normal1), cMul((1-a0), normal0))),
                       cMul(0.5, cAdd(cMul(a1, normal2), cMul((1-a1), normal0)))
                       );
            normalShaded.normalize();

            if (cAngle(normalShaded, normal) > 1.0)
            {
                normalShaded.negate();
            }

            if (cAngle(normal, normalShaded) < m_forceShadingAngleThreshold)
            {
                double forceMagnitude = m_normalForce.length();
                force = cAdd( cMul(forceMagnitude, normalShaded), m_tangentialForce);
                m_lastGlobalForce = force;
                normal = normalShaded;

                // update tangential and normal forces again
                if ((force.lengthsq() > 0) && (m_numContacts > 0))
                {
                    m_normalForce = cProject(force, normal);
                    force.subr(m_normalForce, m_tangentialForce);
                }
                else
                {
                    m_tangentialForce.zero();
                    m_normalForce = force;
                }
            }
        }
    }
}
//==============================================================================
void cToolGripper::computeInteractionForces()
{
    // convert the angle of the gripper into a position in device coordinates. 
    // this value is device dependent.
    double gripperPositionFinger = 0.0;
    double gripperPositionThumb  = 0.0;

    if (m_hapticDevice->m_specifications.m_model == C_HAPTIC_DEVICE_OMEGA_7)
    {
        gripperPositionFinger = 0.040 * cSinRad( m_deviceGripperAngle + cDegToRad( 1.0));
        gripperPositionThumb  = 0.040 * cSinRad(-m_deviceGripperAngle + cDegToRad(-1.0));
    }
    else if (m_hapticDevice->m_specifications.m_model == C_HAPTIC_DEVICE_SIGMA_7)
    {
        gripperPositionFinger = 0.040 * cSinRad( m_deviceGripperAngle + cDegToRad( 1.0));
        gripperPositionThumb  = 0.040 * cSinRad(-m_deviceGripperAngle + cDegToRad(-1.0));
    }
    else
    {
        gripperPositionFinger = 0.040 * cSinRad( m_deviceGripperAngle + cDegToRad( 1.0));
        gripperPositionThumb  = 0.040 * cSinRad(-m_deviceGripperAngle + cDegToRad(-1.0));
    }

    // compute new position of thumb and finger 
    cVector3d lineFingerThumb = getGlobalRot().getCol1();    
    cVector3d pFinger = m_gripperWorkspaceScale * m_workspaceScaleFactor * gripperPositionFinger * lineFingerThumb;
    cVector3d pThumb  = m_gripperWorkspaceScale * m_workspaceScaleFactor * gripperPositionThumb  * lineFingerThumb;

    cVector3d posFinger, posThumb;
    if (m_hapticDevice->m_specifications.m_rightHand)
    {
        posFinger = m_deviceGlobalPos + cMul(m_deviceGlobalRot, (1.0 * pFinger));
        posThumb = m_deviceGlobalPos + cMul(m_deviceGlobalRot, (1.0 * pThumb));
    }
    else
    {
        posFinger = m_deviceGlobalPos + cMul(m_deviceGlobalRot, (-1.0 * pFinger));
        posThumb  = m_deviceGlobalPos + cMul(m_deviceGlobalRot, (-1.0 * pThumb));
    }

    // compute forces
    cVector3d forceThumb = m_hapticPointThumb->computeInteractionForces(posThumb, 
                                                                        m_deviceGlobalRot, 
                                                                        m_deviceGlobalLinVel, 
                                                                        m_deviceGlobalAngVel);

    cVector3d forceFinger = m_hapticPointFinger->computeInteractionForces(posFinger, 
                                                                          m_deviceGlobalRot, 
                                                                          m_deviceGlobalLinVel, 
                                                                          m_deviceGlobalAngVel);

    // compute torques
    double scl = 0.0;
    double factor = m_gripperWorkspaceScale * m_workspaceScaleFactor;
    if (factor > 0.0)
    {
        scl = 1.0 / factor;
    }
    cVector3d torque = scl * cAdd(cCross(cSub(posThumb, m_deviceGlobalPos), forceThumb), cCross(cSub(posFinger, m_deviceGlobalPos), forceFinger));

    // compute gripper force
    double gripperForce = 0.0;

    if ((m_hapticDevice->m_specifications.m_model == C_HAPTIC_DEVICE_OMEGA_7) ||
        (m_hapticDevice->m_specifications.m_model == C_HAPTIC_DEVICE_SIGMA_7))
    {
        cVector3d dir = posFinger - posThumb;
        if (dir.length() > 0.00001) 
        {
            dir.normalize ();
            cVector3d force = cProject (forceFinger, dir);
            gripperForce = force.length();
            if (force.length() > 0.001) 
            {
                double angle = cAngle(dir, force);
                if ((angle > C_PI/2.0) || (angle < -C_PI/2.0)) gripperForce = -gripperForce;
            }
        }
    }

    // gripper damping
    double gripperAngularVelocity = 0.0;
    m_hapticDevice->getGripperAngularVelocity(gripperAngularVelocity);
    double gripperDamping = -0.1 * m_hapticDevice->m_specifications.m_maxGripperAngularDamping * gripperAngularVelocity;

    // finalize forces, torques and gripper force
    m_lastComputedGlobalForce = forceThumb + forceFinger;
    m_lastComputedGlobalTorque = torque;
    m_lastComputedGripperForce = gripperForce + gripperDamping;
}
Пример #13
0
void updateHaptics(void)
{
    // main haptic simulation loop
    while(simulationRunning)
    {
        // update position and orientation of tool
        tool->updatePose();

        // compute interaction forces
        tool->computeInteractionForces();

        // send forces to device
        tool->applyForces();

        // if the haptic device does track orientations, we automatically
        // oriente the drill to remain perpendicular to the tooth
        cVector3d pos = tool->m_proxyPointForceModel->getProxyGlobalPosition();
        cMatrix3d rot = tool->m_deviceGlobalRot;

        if (info.m_sensedRotation == false)
        {
            cVector3d pos = tool->m_proxyPointForceModel->getProxyGlobalPosition();
            rot.identity();

            cVector3d vx, vy, vz;
            cVector3d zUp (0,0,1);
            cVector3d yUp (0,1,0);
            vx = pos - tooth->getPos();
            if (vx.length() > 0.001)
            {
                vx.normalize();

                if (cAngle(vx,zUp) > 0.001)
                {
                    vy = cCross(zUp, vx);
                    vy.normalize();
                    vz = cCross(vx, vy);
                    vz.normalize();

                }
                else
                {
                    vy = cCross(yUp, vx);
                    vy.normalize();
                    vz = cCross(vx, vy);
                    vz.normalize();
                }

                rot.setCol(vx, vy, vz);
                drill->setRot(rot);
            }
        }


        int button = tool->getUserSwitch(0);
        if (button == 0)
        {
            lastPosDevice = pos;
            lastRotDevice = rot;
            lastPosObject = tooth->getPos();
            lastRotObject = tooth->getRot();
            lastDeviceObjectPos = cTrans(lastRotDevice) * ((lastPosObject - lastPosDevice) + 0.01*cNormalize(lastPosObject - lastPosDevice));
            lastDeviceObjectRot = cMul(cTrans(lastRotDevice), lastRotObject);
            tooth->setHapticEnabled(true, true);
            tool->setShowEnabled(true, true);
            drill->setShowEnabled(true, true);
        }
        else
        {
            tool->setShowEnabled(false, true);
            drill->setShowEnabled(false, true);
            cMatrix3d rotDevice01 = cMul(cTrans(lastRotDevice), rot);
            cMatrix3d newRot =  cMul(rot, lastDeviceObjectRot);
            cVector3d newPos = cAdd(pos, cMul(rot, lastDeviceObjectPos));
            tooth->setPos(newPos);
            tooth->setRot(newRot);
            world->computeGlobalPositions(true);
            tooth->setHapticEnabled(false, true);
        }

        // compute global reference frames for each object
        world->computeGlobalPositions(true);
    }

    // exit haptics thread
    simulationFinished = true;
}
Пример #14
0
   void CQTOpenGLUserFunctions::DrawCylinder(Real f_radius,
                                             Real f_height,
                                             const CVector3& c_center_offset,
                                             const CColor& c_color,
                                             const CQuaternion& c_orientation,
                                             GLuint un_vertices) {

    	/* Draw top circle*/
    	CVector3 cCirclePos(0.0f, 0.0f, f_height * 0.5f);
    	cCirclePos.Rotate(c_orientation);
    	cCirclePos += c_center_offset;
    	DrawCircle(f_radius,
                 cCirclePos,
                 c_color,
                 true,
                 c_orientation,
                 un_vertices);

    	/* Draw bottom circle*/
    	cCirclePos.Set(0.0f, 0.0f, -f_height * 0.5f);
    	cCirclePos.Rotate(c_orientation);
    	cCirclePos += c_center_offset;
    	DrawCircle(f_radius,
                 cCirclePos,
                 c_color,
                 true,
                 c_orientation,
                 un_vertices);

    	/* Side surface */
      CVector3 cVertex1(f_radius, 0.0f,  f_height * 0.5f);
      CVector3 cVertex2(f_radius, 0.0f, -f_height * 0.5f);
      CRadians cAngle(CRadians::TWO_PI / un_vertices);

      /* Compute the quaternion defining the rotation of the vertices used to draw the side surface. */
      CQuaternion cVertexRotation;
      CVector3 cVertexRotationAxis(0.0f, 0.0f, 1.0f);
      cVertexRotationAxis.Rotate(c_orientation);
      cVertexRotation.FromAngleAxis(cAngle, cVertexRotationAxis);

      glDisable(GL_LIGHTING);
      glColor3ub(c_color.GetRed(),
                 c_color.GetGreen(),
                 c_color.GetBlue());

      glBegin(GL_QUAD_STRIP);

      /* Compute the normal direction of the starting edge. */
      CVector3 cNormalDirection(cVertex1.GetX(), cVertex1.GetY(), 0.0f);
      cNormalDirection.Rotate(c_orientation);
      glNormal3f(cNormalDirection.GetX(),
                 cNormalDirection.GetY(),
                 cNormalDirection.GetZ());

      /* Rotate the endpoints of the first edge.*/
      cVertex1.Rotate(c_orientation);
      cVertex2.Rotate(c_orientation);

      for(GLuint i = 0; i <= un_vertices; i++) {
         glVertex3f(cVertex1.GetX() + c_center_offset.GetX(),
                    c_center_offset.GetY() + cVertex1.GetY(),
                    c_center_offset.GetZ() + cVertex1.GetZ() );
         glVertex3f(cVertex2.GetX() + c_center_offset.GetX(),
                    c_center_offset.GetY() + cVertex2.GetY(),
                    c_center_offset.GetZ() + cVertex2.GetZ() );
         /* Rotate the vertices and the normal direction, set the new normal. */
         cVertex1.Rotate(cVertexRotation);
         cVertex2.Rotate(cVertexRotation);
         cNormalDirection.Rotate(cVertexRotation);
         glNormal3f(cNormalDirection.GetX(),
                    cNormalDirection.GetY(),
                    cNormalDirection.GetZ());
      }

      glEnd();
      glEnable(GL_LIGHTING);

   }
Пример #15
0
//===========================================================================
void cGELMesh::connectVerticesToSkeleton(bool a_connectToNodesOnly)
{
    // get number of vertices
    int numVertices = m_gelVertices.size();

    // for each deformable vertex we search for the nearest sphere or link
    for (int i=0; i<numVertices; i++)
    {
        // get current deformable vertex
        cGELVertex* curVertex = &m_gelVertices[i];

        // get current vertex position
        cVector3d pos = curVertex->m_vertex->getPos();

        // initialize constant
        double min_distance = 99999999999999999.0;
        cGELSkeletonNode* nearest_node = NULL;
        cGELSkeletonLink* nearest_link = NULL;

        // search for the nearest node
		list<cGELSkeletonNode*>::iterator itr;
        for(itr = m_nodes.begin(); itr != m_nodes.end(); ++itr)
        {
            cGELSkeletonNode* nextNode = *itr;
            double distance = cDistance(pos, nextNode->m_pos);
            if (distance < min_distance)
            {
                min_distance = distance;
                nearest_node = nextNode;
                nearest_link = NULL;
            }
        }

        // search for the nearest link if any
        if (!a_connectToNodesOnly)
        {
            list<cGELSkeletonLink*>::iterator j;
            for(j = m_links.begin(); j != m_links.end(); ++j)
            {
                cGELSkeletonLink* nextLink = *j;
                double angle0 = cAngle(nextLink->m_wLink01, cSub(pos, nextLink->m_node0->m_pos));
                double angle1 = cAngle(nextLink->m_wLink10, cSub(pos, nextLink->m_node1->m_pos));

                if ((angle0 < (CHAI_PI / 2.0)) && (angle1 < (CHAI_PI / 2.0)))
                {
                    cVector3d p = cProjectPointOnLine(pos,
                                                      nextLink->m_node0->m_pos,
                                                      nextLink->m_wLink01);

                    double distance = cDistance(pos, p);

                    if (distance < min_distance)
                    {
                        min_distance = distance;
                        nearest_node = NULL;
                        nearest_link = nextLink;
                    }
                }
            }
        }

        // attach vertex to nearest node if it exists
        if (nearest_node != NULL)
        {
            curVertex->m_node = nearest_node;
            curVertex->m_link = NULL;
            cVector3d posRel = cSub(pos, nearest_node->m_pos);
            curVertex->m_massParticle->m_pos = cMul(cTrans(nearest_node->m_rot), posRel);
        }

        // attach vertex to nearest link if it exists
        else if (nearest_link != NULL)
        {
            curVertex->m_node = NULL;
            curVertex->m_link = nearest_link;

            cMatrix3d rot;
            rot.setCol( nearest_link->m_A0,
                        nearest_link->m_B0,
                        nearest_link->m_wLink01);
            cVector3d posRel = cSub(pos, nearest_link->m_node0->m_pos);
            curVertex->m_massParticle->m_pos = cMul(cInv(rot), posRel);
        }
    }
}