// Left hand effector's extend function for a single object. // Purpose: // - Extends effector until it touches the object or reaches the maximum length. void LeftVirtualHand::extend(arEffector& self, arInteractable* object, float maxLength) { // Return if grabbing an object. if(getGrabbedObject() != 0) return; // Reset tip to 0.0 ft. length. _currentLength = 0.0; setTipOffset(arVector3(0, 0, -_currentLength)); // Check if the maximum length has been reached or an object has been touched. while(_currentLength < maxLength && !ar_pollingInteraction(self, object)) { // If not, increase tip length by interaction distance. _currentLength += _interactionDistance; setTipOffset(arVector3(0, 0, -_currentLength)); } }
// Right hand effector's collision detection function for multiple objects. // Purpose: // - Determine closest object (based on center) that effector is touching. // Notes: // The list must be a list of Object instances, defined above. // This function does not account for rotation of the object or the effector. void RightVirtualHand::detectCollisions(arEffector& self, vector<arInteractable*>& objects) { // Return if grabbing an object. if(getGrabbedObject() != 0) return; // Set maximum distance for testing collision dection to 1000 ft. float maxDistance = 1000.0; // Track closest object and its distance. No object is initially closest. arInteractable* closestObject = 0; float closestDistance = maxDistance; // Step through list of objects and test each one for collisions. for(vector<arInteractable*>::iterator it=objects.begin(); it != objects.end(); ++it) { // Get information about object's position and dimensions. const arMatrix4 objectMatrix = (*it)->getMatrix(); arMatrix4 objectTransMatrix = ar_extractTranslationMatrix(objectMatrix); const float objectX = objectTransMatrix[12]; const float objectY = objectTransMatrix[13]; const float objectZ = objectTransMatrix[14]; const float objectLength = ((Object*)(*it))->getLength(); const float objectHeight = ((Object*)(*it))->getHeight(); const float objectWidth = ((Object*)(*it))->getWidth(); // Get information about effector's position and dimensions. arMatrix4 effectorTransMatrix = ar_extractTranslationMatrix(getMatrix()); const float effectorX = effectorTransMatrix[12]; const float effectorY = effectorTransMatrix[13]; const float effectorZ = effectorTransMatrix[14]; const float effectorLength = _size; const float effectorHeight = _size; const float effectorWidth = _size; // Determine if effector is within object along X-axis. if((objectX - objectLength/2.0) <= (effectorX + effectorLength/2.0) && (effectorX - effectorLength/2.0) <= (objectX + objectLength/2.0)) { // Determine if effector is within object along Y-axis. if((objectY - objectHeight/2.0) <= (effectorY + effectorHeight/2.0) && (effectorY - effectorHeight/2.0) <= (objectY + objectHeight/2.0)) { // Determine if effector is within object along Z-axis. if((objectZ - objectWidth/2.0) <= (effectorZ + effectorWidth/2.0) && (effectorZ - effectorWidth/2.0) <= (objectZ + objectWidth/2.0)) { // Collision detected. Now use selector to determine distance to center of the object. _selector.setMaxDistance(maxDistance); float objectDistance = _selector.calcDistance(self, objectMatrix); // Determine if object is closest so far. if(objectDistance < closestDistance) { // If so, remember object and distance to object. closestObject = *it; closestDistance = objectDistance; } }}} } // Check if an object was touched. if(closestObject != 0) { // If so, set selector's distance to match object's distance. _selector.setMaxDistance(closestDistance); setInteractionSelector(_selector); //cout << "object was selected?" << '\n'; if(getOnButton(1) == 1) { //cout << "object was selected" << '\n'; Object* oby = (Object*)closestObject; oby->_selected = !oby->_selected; } } else { // If not, set selector's distance to size of effector. _selector.setMaxDistance(_size); setInteractionSelector(_selector); } }
// Left hand effector's extend function for multiple objects. // Purpose: // - Extends effector until it touches an object or reaches the maximum length. void LeftVirtualHand::extend(arEffector& self, vector<arInteractable*>& objects, float maxLength) { // Return if grabbing an object. if(getGrabbedObject() != 0) return; // Reset tip to 0.0 ft. length. _currentLength = 0.0; setTipOffset(arVector3(0, 0, -_currentLength)); list<arInteractable*> objectlist; std::copy(objects.begin (), objects.end (), std::back_inserter(objectlist)); // Check if the maximum length has been reached or an object has been touched. while(_currentLength < maxLength && !ar_pollingInteraction(self, objectlist)) { // If not, increase tip length by interaction distance. _currentLength += _interactionDistance; setTipOffset(arVector3(0, 0, -_currentLength)); } if(selectionMode == 3 && ar_pollingInteraction(self, objectlist)) //if it interacted { //cout << "hit an object" << '\n'; //find out which object it interacted with vector<arInteractable*>::iterator i; for(i=objects.begin(); i != objects.end(); ++i) { if(ar_pollingInteraction(self, *i)) { Object *oby = ((Object*)(*i)); oby->_selected = !oby->_selected; selectionMode = 0; } } selectionMode = 0; } else if(selectionMode==3) { selectionMode = 0; } else if(selectionMode == 1) { leftSelectedObjects.clear(); upSelectedObjects.clear(); rightSelectedObjects.clear(); downSelectedObjects.clear(); int numObjects = 0; vector<arInteractable*>::iterator i; for(i=objects.begin(); i != objects.end(); ++i) { // get object location Object* oby = ((Object*)(*i)); arMatrix4 objLoc = oby->getMatrix(); // if object is in cone, then add to selected list float x[] = {objLoc[12], objLoc[13], objLoc[14]}; float height = getLength(); float radius = height/2.f; arMatrix4 tp = getBaseMatrix(); arMatrix4 bm = getMatrix(); float t[] = {tp[12],tp[13],tp[14]}; float b[] = {bm[12],bm[13],bm[14]}; if(isLyingInCone(x, t, b, radius, height)) { if((numObjects) % 4 == 0) { leftSelectedObjects.push_back(oby); } else if(numObjects % 4 == 1) { upSelectedObjects.push_back(oby); } else if(numObjects % 4 == 2) { rightSelectedObjects.push_back(oby); } else if(numObjects % 4 == 3) { downSelectedObjects.push_back(oby); } ++numObjects; } } if(numObjects == 0) { selectionMode = 0; } else if(numObjects == 1) { //if only one object, select it selectionMode = 0; Object* oby = leftSelectedObjects.front(); //set the one object to selected oby->_selected = !oby->_selected; } else { //else selectionMode = 2, selected lists have all the items selectionMode = 2; } } }