Пример #1
0
//Caculate the click location using one of the sixense controllers. Scale is not applied
QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const {
    Application* application = Application::getInstance();
    GLCanvas* glWidget = application->getGLWidget();
    MyAvatar* myAvatar = application->getAvatar();

    glm::vec3 tip = myAvatar->getLaserPointerTipPosition(palm);
    glm::vec3 eyePos = myAvatar->getHead()->getEyePosition();
    glm::quat invOrientation = glm::inverse(myAvatar->getOrientation());
    //direction of ray goes towards camera
    glm::vec3 dir = invOrientation * glm::normalize(application->getCamera()->getPosition() - tip);
    glm::vec3 tipPos = invOrientation * (tip - eyePos);

    QPoint rv;

    if (OculusManager::isConnected()) {
        float t;

        //We back the ray up by dir to ensure that it will not start inside the UI.
        glm::vec3 adjustedPos = tipPos - dir;
        //Find intersection of crosshair ray. 
        if (raySphereIntersect(dir, adjustedPos, _oculusUIRadius * myAvatar->getScale(), &t)){
            glm::vec3 collisionPos = adjustedPos + dir * t;
            //Normalize it in case its not a radius of 1
            collisionPos = glm::normalize(collisionPos);
            //If we hit the back hemisphere, mark it as not a collision
            if (collisionPos.z > 0) {
                rv.setX(INT_MAX);
                rv.setY(INT_MAX);
            } else {

                float u = asin(collisionPos.x) / (_textureFov)+0.5f;
                float v = 1.0 - (asin(collisionPos.y) / (_textureFov)+0.5f);

                rv.setX(u * glWidget->width());
                rv.setY(v * glWidget->height());
            }
        } else {
            //if they did not click on the overlay, just set the coords to INT_MAX
            rv.setX(INT_MAX);
            rv.setY(INT_MAX);
        }
    } else {
        glm::dmat4 projection;
        application->getProjectionMatrix(&projection);

        glm::vec4 clipSpacePos = glm::vec4(projection * glm::dvec4(tipPos, 1.0));
        glm::vec3 ndcSpacePos;
        if (clipSpacePos.w != 0) {
            ndcSpacePos = glm::vec3(clipSpacePos) / clipSpacePos.w;
        }

        rv.setX(((ndcSpacePos.x + 1.0) / 2.0) * glWidget->width());
        rv.setY((1.0 - ((ndcSpacePos.y + 1.0) / 2.0)) * glWidget->height());
    }
    return rv;
}
Пример #2
0
ngl::Real SphericalObstacle::findPossibleCollisionPoint(const MovingObject* _object, ngl::Vec4& o_iPoint, ngl::Vec4& o_iNormal) const
{
    ngl::Real distSqr = std::numeric_limits<ngl::Real>::max();

    ngl::Vec4 rPos =_object->getPosition();
    ngl::Vec4 rDir = _object->getHeadingDir();
    ngl::Vec4 sPos = this->getPosition();
    ngl::Real sInflatedRadius = this->getBoundingRadius() + _object->getBoundingRadius();
    distSqr = raySphereIntersect(rPos, rDir, sPos, sInflatedRadius, o_iPoint, o_iNormal);

    return distSqr;
}
Пример #3
0
//Finds the collision point of a world space ray
bool ApplicationCompositor::calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const {
    MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
    
    glm::quat inverseOrientation = glm::inverse(myAvatar->getOrientation());

    glm::vec3 relativePosition = inverseOrientation * (position - myAvatar->getDefaultEyePosition());
    glm::vec3 relativeDirection = glm::normalize(inverseOrientation * direction);

    float t;
    if (raySphereIntersect(relativeDirection, relativePosition, _oculusUIRadius * myAvatar->getScale(), &t)){
        result = position + direction * t;
        return true;
    }

    return false;
}
Пример #4
0
//Finds the collision point of a world space ray
bool CompositorHelper::calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const {
    auto UITransform = getUiTransform();
    auto relativePosition4 = glm::inverse(UITransform) * vec4(position, 1);
    auto relativePosition = vec3(relativePosition4) / relativePosition4.w;
    auto relativeDirection = glm::inverse(glm::quat_cast(UITransform)) * direction;

    float uiRadius = _hmdUIRadius; // * myAvatar->getUniformScale(); // FIXME - how do we want to handle avatar scale

    float instersectionDistance;
    if (raySphereIntersect(relativeDirection, relativePosition, uiRadius, &instersectionDistance)){
        result = position + glm::normalize(direction) * instersectionDistance;
        return true;
    }

    return false;
}
Пример #5
0
//Finds the collision point of a world space ray
bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const {
    Application* application = Application::getInstance();
    MyAvatar* myAvatar = application->getAvatar();
    
    glm::quat orientation = myAvatar->getOrientation();

    glm::vec3 relativePosition = orientation * (position - myAvatar->getDefaultEyePosition());
    glm::vec3 relativeDirection = orientation * direction;

    float t;
    if (raySphereIntersect(relativeDirection, relativePosition, _oculusUIRadius * myAvatar->getScale(), &t)){
        result = position + direction * t;
        return true;
    }

    return false;
}
Пример #6
0
/* If something is hit, returns the finite intersection point p, 
   the normal vector n to the surface at that point, and the surface
   material m. If no hit, returns an infinite point (p->w = 0.0) */
void firstHit(ray* r, point* p, vector* n, material* *m) {
  int i;
  int index;
  int flag_cyl, flag_hyp;
  double t = 0;     /* parameter value at first hit */
  int hit = FALSE;

  //SURFACE_TYPE 	objects[objnum] = { PLAIN, SPHERE, SPHERE, SPHERE, CYLINDER, HYPERBOLOID };
  int 		hits[objnum]	= { FALSE, FALSE,  FALSE,  FALSE,  FALSE,    FALSE  };
  double 	tvalues[objnum] = { -1.0,  -1.0,   -1.0,   -1.0,  -1.0,     -1.0   };

  for (i = 0; i < objnum; ++i) {
	switch (i) {

	   case 0:   
			hits[i] = rayPlainIntersect(r,pln1,&tvalues[i]);
			  
			if (hits[i]) { 
				index = i;
				hit = TRUE; 
			  }

			  break;

	   case 1:  
			 hits[i] = raySphereIntersect(r,sph0,&tvalues[i]);
			 
			 if (hits[i]) { 
				index = i;
				hit = TRUE; 
			 }

			  break;

	   case 2:  
			 hits[i] = raySphereIntersect(r,sph1,&tvalues[i]);
			 
			 if (hits[i]) { 
				index = i;
			 	hit = TRUE; 
			 }
			 
			 break;

	   case 3:  
			 hits[i] = raySphereIntersect(r,sph2,&tvalues[i]);
			 
			 if (hits[i]) { 
				index = i;
			 	hit = TRUE; 
			 }
			 
			 break;

	   case 4: hits[i] = rayCylinderIntersect(r,cyl0,&tvalues[i],&flag_cyl);
			  
			  if (hits[i]) { 
				index = i;
				hit = TRUE; 
			  }
			  break; 

	   case 5: hits[i] = rayHyperbolIntersect(r,hyp0,&tvalues[i],&flag_hyp);
			  
			  if (hits[i]) { 
				index = i;
				hit = TRUE; 
			  }
			  break;


	   default: 	  break;	
	}
  }

  if ( hit ) {

  	findMin(tvalues, objnum, &t, &index);
	findPointOnRay(r, t, p);

	switch (index) {
	   case 0:      *m = pln1->m;
			findPlainNormal(pln1,p,n);
			break;
	   case 1:	*m = sph0->m;
			findSphereNormal(sph0,p,n);
			break;

	   case 2:	*m = sph1->m;
			findSphereNormal(sph1,p,n);
			break;	

	   case 3:	*m = sph2->m;
			findSphereNormal(sph2,p,n);
			break;	

	   case 4:	*m = cyl0->m;
			findCylinderNormal(cyl0,p,n,flag_cyl);
			break;

	   case 5:	*m = hyp0->m;
			findHyperbolNormal(hyp0,p,n,flag_hyp);
			break;

	
	   default:	break;
	}
  } 

  else { /* no hit */
         p->w = 0.0;
  }
}