HapticDevice::HapticDevice() { m_updateDeviceCallback = HD_INVALID_HANDLE; for(int i=0;i<NB_DEVICES_MAX;i++) { m_constraints[i] = NULL; m_itsConstraints[i] = NULL; m_oldButtons[i] = HD_INVALID_HANDLE; } m_nbDevices = 0; m_coll = false; cleanHistory(); //m_time = 0; }
void HapticDevice::feedback(btDynamicsWorld &dynamic) { for(unsigned int i=0;i<m_nbDevices;i++) { bool ground_collide = false; // free move if((m_hss[i].m_free.m_buttons & HD_DEVICE_BUTTON_1) != 0 )// (m_hss[i].m_free.m_buttons & HD_DEVICE_BUTTON_2)) { m_hss[i].m_free.m_done = true; //m_hss[i].m_free.m_force = hduVector3Dd(0,0,0); } if(m_constraints[i] != NULL) { btRigidBody * myBody = &m_constraints[i]->getRigidBodyB(); btTransform myTrans = myBody->getWorldTransform(); m_effRenderPos = myTrans.getOrigin(); //Check collision if(m_constraints[i]->getUserConstraintPtr() != NULL) { //std::cout<< " se cas la " <<std::endl; m_hss[i].m_free.m_nbCollision = 1; //if((m_hss[i].m_free.m_buttons & HD_DEVICE_BUTTON_1) != 0 && (m_oldButtons[i] & HD_DEVICE_BUTTON_1) == 0) btCollisionObject * object = static_cast<btCollisionObject *>(m_constraints[i]->getUserConstraintPtr()); if(object->getInternalType()== btCollisionObject::CO_RIGID_BODY) { btRigidBody * collideBody = static_cast<btRigidBody *>(object); // collide with ground if(collideBody == m_ground) { m_hss[i].m_free.m_nbCollision = 2; ground_collide = true; } // collide with other object if(collideBody->getInvMass()!=0 && collideBody != m_ground) { if(m_itsConstraints[i] == NULL ) { // catch it if colide with it if((m_hss[i].m_free.m_buttons & HD_DEVICE_BUTTON_1) == 0 ) { //create constraint btTransform bodyTrans = collideBody->getWorldTransform(); m_itsConstraints[i] = createConstraint(*myBody,*collideBody); dynamic.addConstraint(m_itsConstraints[i],true); m_newConstraint(m_ptr,collideBody,i); m_caught = collideBody; m_coll = true; m_devine = false; showTarget(collideBody); deactivateMove(); } }else // realise it when button 1 pressed if(m_freeT || (m_hss[i].m_free.m_buttons & HD_DEVICE_BUTTON_1) != 0) { //remove constraint dynamic.removeConstraint(m_itsConstraints[i]); delete m_itsConstraints[i]; m_itsConstraints[i]=NULL; m_deleteConstraint(m_ptr,collideBody,i); //m_hss[i].setThrown(NULL); m_hss[i].m_free.m_done = true; showTarget(collideBody); m_variator = 0; m_coll = false; deactivateMove(); } } } } else { m_hss[i].m_free.m_nbCollision = 0; //if((m_hss[i].m_free.m_buttons & HD_DEVICE_BUTTON_1) != 0 && (m_oldButtons[i] & HD_DEVICE_BUTTON_1) == 0) if(m_freeT || (m_hss[i].m_free.m_buttons & HD_DEVICE_BUTTON_1) != 0) { if(m_itsConstraints[i] != NULL ) { //remove constraint m_deleteConstraint(m_ptr,&m_itsConstraints[i]->getRigidBodyB(),i); dynamic.removeConstraint(m_itsConstraints[i]); delete m_itsConstraints[i]; m_itsConstraints[i]=NULL; m_hss[i].m_free.m_done = true; if(m_caught != NULL) showTarget(m_caught); m_coll = false; deactivateMove(); } } } if(m_itsConstraints[i]!=NULL ) m_hss[i].m_free.m_nbCollision = 1; else // launch an other target if((m_hss[i].m_free.m_buttons & HD_DEVICE_BUTTON_2) != 0 && (m_oldButtons[i] & HD_DEVICE_BUTTON_2) == 0) { //m_canLaunch = true; } m_oldButtons[i]=m_hss[i].m_free.m_buttons; //put back cursor world position into device referencial <<<<< ------------------------------ btTransform offset(btMatrix3x3::getIdentity(),btVector3(0,0,-0.5)); m_effectors[i].setOrigin(myTrans.getOrigin()); m_effectors[i].mult(m_effectors[i],offset); btVector3 pos = m_cameraViews[i]->inverse()(myTrans.getOrigin()); pos*=SCALE_WORLD_TO_DEVICE; m_hss[i].m_free.m_realPosition.set(pos.getX(),pos.getY(),pos.getZ()+OFFSET_TO_CAMERA); } btTransform camInv = m_cameraViews[i]->inverse(); // compute feed back for ground if(ground_collide) { m_hss[i].m_free.m_force = groundForce(true,&(m_hss[i].m_free.m_position),&camInv); }else m_hss[i].m_free.m_force = hduVector3Dd(0,0,0); // detecte the direction HDdouble deplacement = betweenTwoPoints(m_hss[i].m_free.m_atThrowPos,m_hss[i].m_free.m_position); HDdouble distanceMax = Distance_max; hduVector3Dd move = m_hss[i].m_free.m_oldPosition - m_hss[i].m_free.m_position; HDdouble selectedDistance = 0; if( m_devine && m_thrownRigids != NULL && m_thrownRigids->size()>0 && deplacement > distanceMax && m_sible == 0 /* && !m_targetChoosen */){ HDdouble distance = Quick_Distance_max; //unsigned int targ = 0; for(unsigned int j = 0; j<m_thrownRigids->size(); j++){ HDdouble d = distanceToTrajectory(m_hss[i].m_free.m_position,j,&camInv); if((d)<distance){ if(m_Thrown != (*m_thrownRigids)[j]){ m_hss[i].m_free.m_currentThrown = (*m_thrownRigids)[j]; distance = d; m_Thrown = (*m_thrownRigids)[j]; m_impactPos = m_possibleImpact[j]; m_targetChoosen = true; if(m_Feedback){ activateMove(); } selectedDistance = d; m_index = j; m_sible = Nbr_frame_wait; } } } if(m_targetChoosen){ //showTarget(m_Thrown); addPrevious(m_Thrown); } else m_sible = 0; //m_time = Time; } if(m_canLaunch){ //m_time = Time; m_hss[i].m_free.m_done = true; m_variator = 0.001; m_sible = 0; m_devine = true; deactivateMove(); cleanHistory(); m_hss[i].m_free.m_atThrowPos = m_hss[i].m_free.m_position; } m_hss[i].m_free.m_oldPosition = m_hss[i].m_free.m_position ; if(m_hss[i].m_free.m_currentThrown != NULL && m_posSet && m_Feedback ){ hduVector3Dd impact = invertTransform(m_impactPos, &camInv); hduVector3Dd pos(m_hss[i].m_free.m_position); btVector3 balltest = ((*m_thrownRigids)[0])->getWorldTransform().getOrigin(); hduVector3Dd test = invertTransform(&balltest, &camInv); m_velocity = m_hss[i].m_free.m_velocity.magnitude(); if(pos[2]-5 >= test[2]){ if(!m_hss[i].m_free.m_done){ //hduVector3Dd helpForce = ForceToImpact(&pos,&impact); hduVector3Dd helpForce = magneticForce(&pos, &impact, &camInv); //hduVector3Dd helpForce = atomeForce(&pos, &impact, &camInv); if(!helpForce.isZero(EPSILON)){ hduVector3Dd force = 1.0 * helpForce; m_hss[i].m_free.m_force = force; m_Force = force; }else { //m_hss[i].m_free.m_force = m_Force; } } } } hdScheduleSynchronous(sScheduleIn, &m_hss, HD_DEFAULT_SCHEDULER_PRIORITY); m_selectedDistance = selectedDistance; if(m_sible > 0) m_sible--; } }
// a slot to get a command to clean the history void ProcessingThread::deckShuffled(){ cleanHistory(&GameState); return; }