Пример #1
0
float RayMarcher::marchSecondary( const Ray &ray )
{
	const float RAY_EPSILON = 0.50f;
	float boxTimes[2];
	if( mBoundingBox.intersect( ray, boxTimes ) != 2 )
		return 0;
		
	Vec3f pointOfDeparture;
	if( boxTimes[0] >= 0 )
		pointOfDeparture = ray.calcPosition( boxTimes[0] );
	else
		pointOfDeparture = ray.calcPosition( boxTimes[1] );
	float span = ray.getOrigin().distance( pointOfDeparture );
	int numSteps = (int)( span / RAY_EPSILON );
	if( numSteps <= 0 ) 
		return 0;

	Vec3f step( ray.getDirection() );
	step *= RAY_EPSILON;

	Vec3f rayPos = ray.getOrigin(); 

	float result = 0;
	for( int i = 0; i < numSteps; ++i ) {
		float D = sampleDensity( rayPos ) * RAY_EPSILON;
		result += D * ( 1.0f - result );
		
		rayPos += step; 
	}

	return result;
}
Пример #2
0
ptc::IntersectDescr Rectangle::intersect( const Ray& ray )
{
	const double dir_dot = normal_.dot( ray.getDir() );
	
	const bool is_grazing = std::abs( dir_dot ) <= 1e-4;
	const bool is_wrong_side = !getIsDoubleSided() && dir_dot >= -1e-4;
	
	if( is_grazing || is_wrong_side )
	{
		return IntersectDescr( this );
	}

	const Vector center_vec = center_ - ray.getOrigin();
	const double distance = -normal_.dot( center_vec );

	const double param = distance / -dir_dot;

	const Vector intersect = ray.getOrigin() + param * ray.getDir();
	const Vector intersect_vec = intersect - center_;

	const bool is_right_vec_ok = std::abs( right_.dot( intersect_vec ) ) <= .5 * width_;
	const bool is_up_vec_ok = std::abs( up_.dot( intersect_vec ) ) <= .5 * height_;

	if( is_right_vec_ok && is_up_vec_ok )
	{
		return IntersectDescr( param, intersect, normal_, ray.getDir(), this );
	}

	return IntersectDescr( this );
}
	glm::vec3 rayTrace(Ray &ray, const float& t, const glm::vec3& normal, RayTracerState& state) {
		std::vector<std::shared_ptr<LightObject>>::iterator iter;
		glm::vec3 color;

		glm::vec3 p = ray.getOrigin() + t*ray.getDirection();

		for(iter = state.getLights().begin(); iter != state.getLights().end(); iter++){
			float shadow_value;
			shadow_value = (*iter)->PointInShadow(p, state);
			//skipping contribution from this light if the object is fully shadowed by it
			if(shadow_value <=0.00001f)
				continue;

			glm::vec3 pos = (*iter)->position;

			glm::vec3 diff = (*iter)->diff;
			glm::vec3 spec = (*iter)->spec;

			glm::vec3 v = glm::normalize(ray.getOrigin() - p);
			glm::vec3 l = glm::normalize(pos - p);
			glm::vec3 h = glm::normalize(v+l);
			glm::vec3 n = glm::normalize(normal);

			float diffuse = glm::max(0.0f, glm::dot(n, l));
			float specular = glm::pow( glm::max(0.0f, glm::dot(n, h)), 50.0f);

			glm::vec3 new_color = glm::vec3( (diff*diffuse)+(spec*specular) ) * shadow_value ;
			color += new_color;
		}
		color/=state.getLights().size();
		//glm::vec3 absnormal = glm::vec3(abs(normal.x),abs(normal.y),abs(normal.z)); 
		return color;//*shadefactor;
	}
Пример #4
0
Point UIManagerSpherical::projectRay(const Ray& ray) const
	{
	/* Check if the line defined by the ray intersects the sphere: */
	Scalar d2=Geometry::sqr(ray.getDirection());
	Vector oc=ray.getOrigin()-sphere.getCenter();
	Scalar ph=oc*ray.getDirection();
	Scalar det=Math::sqr(ph)-(Geometry::sqr(oc)-Math::sqr(sphere.getRadius()))*d2;
	if(det>=Scalar(0))
		{
		/* Calculate the point where the line exits the sphere: */
		det=Math::sqrt(det);
		return ray((-ph+det)/d2);
		}
	else
		{
		/* Return the projection of the ray's origin onto the sphere: */
		Vector d=ray.getOrigin()-sphere.getCenter();
		Scalar dLen=d.mag();
		if(dLen==Scalar(0))
			{
			d=getForwardDirection();
			dLen=d.mag();
			}
		return sphere.getCenter()+d*(sphere.getRadius()/dLen);
		}
	}
Пример #5
0
Vertex Rendering::shade(Ray intersect, Scene scene, Vertex viewerDirection) {
	// intersect is a ray with origin at the point of intersect,
	// and direction of the normal of the intersected polygon
	Vertex shade (0,0,0);
	
	vector<Vertex> lights = scene.getDirectionalLights();
	for (int a=0; a<lights.size(); a++) {
		// see if that light is blocked, if so, it's shadow
		Vertex light = Vertex(lights[a].get(0), lights[a].get(1), lights[a].get(2));
		Vertex color = Vertex(lights[a].get(3), lights[a].get(4), lights[a].get(5));
		light = light.scale(-1);
		if (!isShadowed(intersect.getOrigin(), light, scene, false)) {
			light = light.normalize();
			float gradient = max(0.0f, light.dot(intersect.getDirection()));
			float specular = intersect.getDirection().reflect(light.scale(-1)).dot(viewerDirection.scale(-1).normalize());
			specular = pow(max(0.0f, specular),specularConst);
			shade = shade.add(color.scale(gradient+specular));
		}
	}
	
	vector<Vertex> plights = scene.getPointLights();
	for (int a=0; a<plights.size(); a++) {
		Vertex light = Vertex(plights[a].get(0), plights[a].get(1), plights[a].get(2));
		Vertex color = Vertex(plights[a].get(3), plights[a].get(4), plights[a].get(5));
		light = light.sub(intersect.getOrigin());
		if (!isShadowed(intersect.getOrigin(), light, scene, true)) {
			light = light.normalize();
			float gradient = max(0.0f, light.dot(intersect.getDirection()));
			float specular = intersect.getDirection().reflect(light.scale(-1)).dot(viewerDirection.scale(-1).normalize());
			specular = pow(max(0.0f, specular),10);
			shade = shade.add(color.scale(gradient+specular));
		}
	}
	return shade;
}
Пример #6
0
bool Rect::shadowHit(const Ray& ray, float& tmin) const
{
	if(!castsShadows)
		return false;

	float t = glm::dot((corner - ray.getOrigin()),normal) / glm::dot(ray.getDirection(),normal);

	if(t<=KEpsilon)
		return false;

	glm::vec3 point = ray.getOrigin() + t * ray.getDirection();
	glm::vec3 d = point - v0;

	float dDota = glm::dot(d, v0);
	if(dDota<0.0 || dDota > aLenSquared)
		return false;

	float dDotb = glm::dot(d, v1);
	if(dDotb<0.0f || dDotb > bLenSquared)
		return false;

	tmin = t;

	return true;
}
Пример #7
0
Color Ray::shaded_color(const LightConstPtr& light, const Vector& lightPoint, const Ray& reflectedray, const Vector& normal, ObjektConstPtr& obj, const Color& textureColor)
{
	Color diffuse, specular;
	
	const Vector lightDir = light->getDirection(reflectedray.getOrigin(), lightPoint);
	const double lightIntensity = light->getItensity(reflectedray.getOrigin(), lightPoint);

	// Diffuse light
	double ldot = lightDir.dot(normal);
	if (1.0 + ldot > 1.0) {
		Color lambert = light->getColor().scmpy(ldot);
		diffuse = lambert.outprodc(obj->getProperty().getReflectance());
	}

	// Specular light
	double spec = reflectedray.getDirection().dot(lightDir);
	if (1.0 + spec > 1.0) {
		spec = pow(spec, obj->getProperty().getShininess());
		spec *= obj->getProperty().getSpecular();
		specular =  light->getColor().scmpy(spec);
	}

	Color reflected_color = diffuse.addcolor(specular);

	if (!textureColor.isNull())	{
		reflected_color = reflected_color.outprodc(textureColor);
	}
	
	return reflected_color.scmpy(lightIntensity);
} /* shaded_color() */
Пример #8
0
pair<Vec3, SceneObject*> collide(Ray &ray, vector<SceneObject*>& sceneObjects){
	// init the best impact point to the ray position
	Vec3 best_impact_point = ray.getOrigin();
	// get the origin of the ray
	Vec3 ray_origin = ray.getOrigin();
	// declare the best scene object;
	SceneObject* best_sceneObject = nullptr;
	// declare the best distance
	float best_dist = numeric_limits<float>::infinity();
	// declare the current distance
	float dist = 0.0;
	// declare the pair for the intersect function
	pair<bool, Vec3> pair_intersect;
	// declare impact point
	Vec3 impact_point;
	//for each object of the scene
	for (vector<SceneObject*>::iterator it = sceneObjects.begin(); it != sceneObjects.end(); it++){
		// determine if the ray intersect the object
		pair_intersect = (*it)->intersect(ray);
		if (pair_intersect.first){
			// compute the distance between the ray and the impact point
			impact_point = pair_intersect.second - ray_origin;
			dist = impact_point.length();
			// if it's the best
			if (best_dist > dist){
				best_dist = dist;
				best_sceneObject = *it;
				best_impact_point = pair_intersect.second;
			}
		}
	}
	return pair<Vec3, SceneObject*>(best_impact_point, best_sceneObject);
}
Пример #9
0
bool OsgSceneObject::intersectRay(const Ray& ray, Vector3f* hitPoint)
{
	Vector3f rstart = ray.getOrigin();
	
	// Compute reasonable ray length based on distance between ray origin and
	// owner scene node center.
	Vector3f center = getOwner()->getBoundCenter();
	float dir = (ray.getOrigin() - center).norm();
	Vector3f rend = ray.getPoint(dir * 2);

	osg::Vec3d orig(rstart[0], rstart[1], rstart[2]);
	osg::Vec3d end(rend[0], rend[1], rend[2]);


	Ref<osgUtil::LineSegmentIntersector> lsi = new osgUtil::LineSegmentIntersector(orig, end);
	osgUtil::IntersectionVisitor iv(lsi);

	myTransform->accept(iv);

	if(!lsi->containsIntersections()) return false;

	osgUtil::LineSegmentIntersector::Intersection i = lsi->getFirstIntersection();
	
	osg::Vec3d intersect = i.getWorldIntersectPoint();

	hitPoint->x() = intersect[0];
	hitPoint->y() = intersect[1];
	hitPoint->z() = intersect[2];
	return true;
}
Пример #10
0
pair<bool, Vec3> Planar::intersect(Ray &ray){
	// declare the impact point
	Vec3 impact_point = ray.getOrigin();

	// normalize the vector (n is already normalized)
	Vec3 l0 = ray.getOrigin();
	Vec3 l = ray.getDirection();

	// calcul the denominator
	float denom = l * n;
	// if the ray and the normal vector of the planar isn't parallel
	if (denom > 1e-6) {
		// calcul t for determinate if the ray intersect the planar
		float t = ((position - l0) * n) / denom;
		// calcul the impact point
		impact_point = l0 + l * t;
		// verif if the impact point is in the square
		if (impact_point.getX() < maxCoordinates().getX() && impact_point.getX() > minCoordinates().getX()
			&& impact_point.getY() < maxCoordinates().getY() && impact_point.getY() > minCoordinates().getY() 
			/*&& impact_point.getZ() <= maxCoordinates().getZ() && impact_point.getZ() >= minCoordinates().getZ()*/){
				return pair<bool, Vec3>(t >= 0, impact_point);
		}
		else{
			return pair<bool, Vec3>(false, impact_point);
		}
	}
	return pair<bool, Vec3>(false, impact_point);
}
Пример #11
0
bool Plane::intersect( Ray& ray, hpvec3& intersectionPoint ) {
	if( glm::abs(glm::dot(ray.getDirection(), m_normal)) < HP_EPSILON ) {
		return false;
	}
	hpreal t = -(glm::dot(ray.getOrigin(), m_normal) + glm::dot(m_origin, m_normal)) / glm::dot(ray.getDirection(), m_normal);
	intersectionPoint = ray.getOrigin() + t*ray.getDirection();
	return true;
}
Пример #12
0
bool Sphere::intersect(const Ray &r, Hit &h) const {




  // ==========================================
  // ASSIGNMENT:  IMPLEMENT SPHERE INTERSECTION
  // ==========================================

  // a = d (dot) d
  double a = r.getDirection().Dot3(r.getDirection());

  // b = 2d (dot) (orginPoint - centerPoint)
  double b = (2*(r.getDirection())).Dot3(r.getOrigin() - center);

  // c = (p_0 - p_c) dot (p_0-p_c) - r^2
  double c = (r.getOrigin() - center).Dot3(r.getOrigin() - center) - (radius*radius);

  // t = (-b +/- sqrt(b2 - 4 a c)) / (2 a)
  // if inside is negative, then it doesn't intersect the sphere
  // if zero just a slight glance of sphere
  // if two then you interect and leave

  double inside = (b*b) - 4*a*c;

  if(inside >= 0 ){ 
    //inside

    // get the first intersection point
    double t = ((-1*b) - sqrt(inside)) / (2*a);

    if(t < 0) return false;

    // get pt collision
    Vec3f pt = r.getOrigin() + t * r.getDirection();

    if(pt.Distance3f(r.getOrigin()) < EPSILON) return false;


    Vec3f norm((pt.x() - center.x())/radius, (pt.y() - center.y())/radius, (pt.z() - center.z())/radius);
    norm.Normalize();

    h.set(t,getMaterial(),norm);
    return true;

  }else{

    // Negative and therefore missed
    return false;
    
  }

  // return true if the sphere was intersected, and update
  // the hit data structure to contain the value of t for the ray at
  // the intersection point, the material, and the normal
  return false;
} 
Пример #13
0
bool
CollisionManager::isIntersecting(const Ray& ray, Entity* entity, Real& distance)
{
  // get a pointer to the collision model 
  ColDet::CollisionModel3D* mColModel = modelMap[entity->getMesh()->getName()];
  if(mColModel == NULL) return false;
      
  // set the world transform for the entity    
  {
    Matrix4 world; 
    entity->getParentSceneNode()->getWorldTransforms(&world);  
    
    float fMatrix[16];
    fMatrix[0] = world[0][0];
    fMatrix[1] = world[1][0];
    fMatrix[2] = world[2][0];
    fMatrix[3] = world[3][0];
    fMatrix[4] = world[0][1];
    fMatrix[5] = world[1][1];
    fMatrix[6] = world[2][1];
    fMatrix[7] = world[3][1];
    fMatrix[8] = world[0][2];
    fMatrix[9] = world[1][2];
    fMatrix[10] = world[2][2];
    fMatrix[11] = world[3][2];
    fMatrix[12] = world[0][3];
    fMatrix[13] = world[1][3];
    fMatrix[14] = world[2][3];
    fMatrix[15] = world[3][3];

    mColModel->setTransform(fMatrix); 
  }
  
  // convert the ray  
  float Origin[3], Direction[3]; 
  
  Origin[0] = ray.getOrigin().x; 
  Origin[1] = ray.getOrigin().y; 
  Origin[2] = ray.getOrigin().z; 

  Direction[0] = ray.getDirection().x; 
  Direction[1] = ray.getDirection().y; 
  Direction[2] = ray.getDirection().z;  

  // check for a collision 
  bool col = mColModel->rayCollision(Origin, Direction);      

  // for testing purposes 
//   mColModel->getCollidingTriangles(t1, t2, false); 
//   mColModel->getCollisionPoint(colPoint, false); 
  float collisionPoint[3];
  mColModel->getCollisionPoint(collisionPoint, false);
  Vector displacement = ray.getOrigin() - Vector(collisionPoint[0], collisionPoint[1], collisionPoint[2]);
  distance = displacement.length();

  return col; 
}
Пример #14
0
bool TrianglePatch::hit(const Ray &r,double tmax,double time,HitRecord &record)const{
	Vector3 p0=animation[0](vertex[0],time);
	Vector3 p1=animation[1](vertex[1],time);
	Vector3 p2=animation[2](vertex[2],time);

	Vector3 n0=animation[0](vertex[0]+normal[0],time)-p0;
	Vector3 n1=animation[1](vertex[1]+normal[1],time)-p1;
	Vector3 n2=animation[2](vertex[2]+normal[2],time)-p2;

	double A=p0.getX()-p1.getX();
	double B=p0.getY()-p1.getY();
	double C=p0.getZ()-p1.getZ();

	double D=p0.getX()-p2.getX();
	double E=p0.getY()-p2.getY();
	double F=p0.getZ()-p2.getZ();

	double G=r.getDirection().getX();
	double H=r.getDirection().getY();
	double I=r.getDirection().getZ();

	double J=p0.getX()-r.getOrigin().getX();
	double K=p0.getY()-r.getOrigin().getY();
	double L=p0.getZ()-r.getOrigin().getZ();

	double EIHF=E*I-H*F;
	double GFDI=G*F-D*I;
	double DHEG=D*H-E*G;

	double denom=(A*EIHF+B*GFDI+C*DHEG);

	double beta=(J*EIHF+K*GFDI+L*DHEG)/denom;
	if((beta<=0.0f)||(beta>=1.0f))
		return false;

	double AKJB=A*K-J*B;
	double JCAL=J*C-A*L;
	double BLKC=B*L-K*C;

	double gamma=(I*AKJB+H*JCAL+G*BLKC)/denom;
	if((gamma<=0.0f)||(gamma>=1.0f))
		return false;

	double t=-(F*AKJB+E*JCAL+D*BLKC)/denom;
	if((t>=0.0f)&&(t<=tmax)){
		record.t=t;
		record.material=std::make_shared<Material>(material);
		record.hitpoint=r.pointAt(t);
		record.normal=normalize(n0+n1+n2);
		record.UVcoord=(1.0f-beta-gamma)*texCoord[0]+beta*texCoord[1]+gamma*texCoord[2];
		return true;
	}

	return false;
}
Пример #15
0
    std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects ()
    {
        //get a ray pointing to the center of the viewport
        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
        mRender.getViewport()->getWidth()/2,
        mRender.getViewport()->getHeight()/2);
        btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
        btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y);

        return mEngine->rayTest2(from,to);
    }
Пример #16
0
float KDTreeRayTracer::findNearestObject(const Ray &r , Object*& nearObj)
{
	Vector ray_entry, ray_exit;
	float near_dist = INT_MAX;
	std::stack<BoundingBox*> box_stack;

	// push root on to stack
	box_stack.push(tree_root);

	while (!box_stack.empty()) {
		BoundingBox* cur_box = box_stack.top();
		box_stack.pop();

		// check if we are at a leaf node
		if (cur_box->box_depth == tree_depth) {
			// there are objects in leaf node
			if (cur_box->objs.size() > 0) { 
				std::list<Object*>::iterator it;
				for (it=cur_box->objs.begin(); it != 
						cur_box->objs.end(); it++) {
					Vector pt;
                    // if the ray doesn't intersect, continue
                    if(!(*it)->getRayIntersection(r, pt))
						continue;
                    // if the ray intersects outside the scene, continue
                    if (!scene.checkInScene(pt))
                        continue;
					float obj_dist = pt.length(r.getOrigin());
					if(obj_dist < near_dist)
					{
						near_dist = obj_dist;
						nearObj = *it;
					}
				}
				if (near_dist < INT_MAX) // we hit an object
					return near_dist;
			} else
				continue;
		} else { // we aren't at a leaf node yet
			if (cur_box->l_child->containsPoint(r.getOrigin())) {
				// ray origin is in l_child
				if (cur_box->r_child->intersectsRay(r))
					box_stack.push(cur_box->r_child);
				box_stack.push(cur_box->l_child);
			} else { // ray origin in r_child
				if (cur_box->l_child->intersectsRay(r))
					box_stack.push(cur_box->l_child);
				box_stack.push(cur_box->r_child);
			}				
		}
				
	}
	return near_dist;
}
Пример #17
0
IntersectionCompound Triangle::getIntersection(const Ray& ray) const{
	IntersectionCompound ic;
	if( ray.getDirection().dot(_normal)>-eps )//no lightnin
		return ic;

	ic.mat = 0;
	ic.px=ic.py=-1;
	ic.t = -1;
	//mehod from http://www.devmaster.net/wiki/Ray-triangle_intersection

	real distance = -((ray.getOrigin()-_v1).dot(_normal))/(ray.getDirection().dot(_normal));
	if(distance<eps){//no hit if the triangle is hit from behind
		//std::cout<<"behind object"<<std::endl;
		ic.t = -1;
		return ic;
	}

	Vector3 &point = ic.hitpoint;
	point = ray.getOrigin()+distance*ray.getDirection();
	ic.t=distance;

	//find dominat axis

	real p[2];
	p[0]= _dominant==0?(point[1]-_v1[1]):(point[0]-_v1[0]);
	p[1]= _dominant==2?(point[1]-_v1[1]):(point[2]-_v1[2]);


	real u = p[1]*_ud1  + p[0]*_ud2;
	if(u<-eps){//not hit
		ic.t = -1;
		return ic;
	}


	real v = p[1]* _vd1 + p[0]*_vd2;
	//ensure u,v,w \in [0,1]
	if( v<-eps or u+v>1+eps){ // not hit
		ic.t = -1;
		return ic;
	}

	//calculate correct color
	ic.mat = getMaterial();
	if(not _normalsSet )
		ic.normal = _normal;
	else
		ic.normal = u*_normals[1] + v*_normals[2] + (1-u-v)*_normals[0];
		ic.normal.normalize();
		//normals have to be initialiased with somethng useful!
		ic.px =  u*_px[1] + v*_px[2] + (1-u-v)*_px[0];
		ic.py =  u*_py[1] + v*_py[2] + (1-u-v)*_py[0];
	return ic;
}
Пример #18
0
BoxRayDragger::Interval BoxRayDragger::intersectBox(const Ray& ray,const Point& center,const Scalar halfSize[3])
	{
	/* Initialize the intersection interval to the full ray range: */
	Scalar l1=Scalar(0);
	Scalar l2=Math::Constants<Scalar>::max;
	
	/* Calculate the intersection interval of the ray with each box face and intersect the intervals: */
	for(int i=0;i<3;++i)
		{
		/* Calculate top and bottom faces: */
		Scalar top=center[i]+halfSize[i];
		Scalar bot=center[i]-halfSize[i];
		
		/* Calculate the ray intersections along this axis: */
		Scalar lf1,lf2;
		
		/* Check the direction of the ray relatively to the box: */
		if(ray.getDirection()[i]<Scalar(0))
			{
			/* Ray intersects top face first: */
			lf1=(top-ray.getOrigin()[i])/ray.getDirection()[i];
			lf2=(bot-ray.getOrigin()[i])/ray.getDirection()[i];
			}
		else if(ray.getDirection()[i]>Scalar(0))
			{
			/* Ray intersects bottom face first: */
			lf1=(bot-ray.getOrigin()[i])/ray.getDirection()[i];
			lf2=(top-ray.getOrigin()[i])/ray.getDirection()[i];
			}
		else if(center[i]-halfSize[i]<=ray.getOrigin()[i]&&ray.getOrigin()[i]<=center[i]+halfSize[i])
			{
			/* Ray is completely between the faces: */
			lf1=Scalar(0);
			lf2=Math::Constants<Scalar>::max;
			}
		else
			{
			/* Ray is completely outside the box: */
			lf1=Scalar(-1);
			lf2=Scalar(-1);
			}
		
		/* Intersect the calculated ray intersection with the complete interval: */
		if(l1<lf1)
			l1=lf1;
		if(l2>lf2)
			l2=lf2;
		}
	
	/* Return the result interval: */
	return Interval(l1,l2);
	}
Пример #19
0
	glm::vec3 rayTrace(Ray &ray, const float& t, const glm::vec3& normal, RayTracerState& state) {
		glm::vec3 p = ray.getOrigin() + t*ray.getDirection();
		
		glm::vec3 v = glm::normalize(ray.getOrigin() - p);
		glm::vec3 l = glm::normalize(this->pos - p);
		glm::vec3 h = glm::normalize(v + l);
		glm::vec3 n = glm::normalize(normal);

		float diffuse = glm::max(0.0f, glm::dot(n, l));
		float specular = glm::pow( glm::max(0.0f, glm::dot(n, h)), 30.0f);

		return glm::vec3( (diff*diffuse) + (spec*specular) );
	}
Пример #20
0
bool Triangle::intersects(const Ray& ray, float* distance /*= nullptr*/, Vec3* point /*= nullptr*/)
{
	float a,b,c,d,e,f,g,h,i,j,k,l;
	Vec3 dir = ray.getDirection();
	a = coords[0].x - coords[1].x;
	b = coords[0].y - coords[1].y;
	c = coords[0].z - coords[1].z;
	d = coords[0].x - coords[2].x;
	e = coords[0].y - coords[2].y;
	f = coords[0].z - coords[2].z;
	g = dir.x;
	h = dir.y;
	i = dir.z;
	j = coords[0].x - ray.getOrigin().x;
	k = coords[0].y - ray.getOrigin().y;
	l = coords[0].z - ray.getOrigin().z;

	float t, beta, gama, m;

	m = a*(e*i - h*f) + b*(g*f - d*i) + c*(d*h-e*g);
	beta = ( j*(e*i-h*f) + k*(g*f-d*i) + l*(d*h-e*g) ) / m;
	gama = ( i*(a*k-j*b) + h*(j*c-a*l) + g*(b*l-k*c) ) / m;
	t = 0- (f*(a*k-j*b) + e*(j*c-a*l) + d*(b*l-k*c)) / m;

	if (distance)
	{
		*distance = t;
	}
	Vec3 iteration(t*dir.x, t*dir.y, t*dir.z);
	if (point)
	{
		*point = Vec3(ray.getOrigin().x + iteration.x, ray.getOrigin().y + iteration.y, ray.getOrigin().z + iteration.z);
	}

	if (gama <= 0 || gama >= 1)
	{
		return false;
	}
		
	if (beta <= 0 || beta >= 1 - gama)
	{
		return false;
	}

	if (ray.getDirection().dot(normal) < 0)
	{
		return false;
	}
	
	return true;
}
Пример #21
0
Intersection Triangle::hit(Ray ray)
{

	ray.setOrigin(vec3(getInverseTransform() * vec4(ray.getOrigin(),1)));
	ray.setDirection(glm::normalize(vec3(getInverseTransform() * vec4(ray.getDirection(),0))));

	// R(t) = o + td;
	// ax + by + cz = d => n·X=d
	// n·R(t) = d
	// n · [o + td] = d
	// n·o + nt·d = d
	// t = (d-n·o)/(n·d)
	vec3 ab = m_b-m_a;
	vec3 ac = m_c-m_a;
	vec3 normal = glm::normalize(glm::cross(ab,ac));
	float nd = glm::dot(normal,ray.getDirection());
	if (nd == 0) // PARAREL
	{
		return Intersection(false);
	}
	float d = glm::dot(normal, m_a);
	float t = (d-glm::dot(normal,ray.getOrigin())) / nd;
	if (t < 0)
	{
		return Intersection(false);
	}
	vec3 pointq = ray.getOrigin() + t * ray.getDirection();
	vec3 ap = pointq - m_a; 
	vec3 bp = pointq - m_b; 
	vec3 cp = pointq - m_c; 
	vec3 bc = m_c - m_b;
	vec3 ca = m_a - m_c;

	float e1 = glm::dot(glm::cross(ab, ap),normal);
	float e2 = glm::dot(glm::cross(bc, bp),normal);
	float e3 = glm::dot(glm::cross(ca, cp),normal);

	if (e1 < 0 || e2 < 0 || e3 < 0)
	{
		return Intersection(false);
	}
	float dom = glm::dot(glm::cross(ab, ac),normal);
	float alpha = e2 /dom;
	float beta = e3/dom;
	float gamma = e1/dom;


	vec3 point = m_a*alpha + m_b*beta + m_c*gamma;

	return Intersection(true, point, normal);
}
Пример #22
0
void Controller::OnMouseMove(Flags nFlags, int x, int y)
{
	Point point(x,y);

	if (nFlags == LBUTTON)
	{
		Vec3 r;

		r.x = -(Float)(point.x - mouse.x)/3;
		r.y = (Float)(point.y - mouse.y)/3;

		r = cross(r, Vec3(0,0,1));

		Matrix rot = Matrix::Rotation( r.normalized(), r.getLen());
		m_Rotation = m_Rotation * rot;
	}

	if (nFlags == (LBUTTON|RBUTTON)  )
	{
		Vec3 r;

		r.x = -(Float)(point.x - mouse.x)/3;
		r.y = (Float)(point.y - mouse.y)/3;

		r = cross(r, Vec3(0,0,1));

		Matrix rot = Matrix::Rotation( r.normalized(), r.getLen());
		m_Rotation2 = m_Rotation2 * rot;
	}

	if (nFlags == RBUTTON )
	{
		Vec3 n = transform(Vec3(0,0,-1), m_Rotation.getInverted() );
		n = n.normalized();

		Plane ebene = Plane(n.x, n.y, n.z, 0);

		Ray a = getViewport().DPtoRay(mouse.x, mouse.y);
		Ray b = getViewport().DPtoRay(point.x, point.y);

		Float ta = 0, tb = 0;
		ebene.getIntersectionWithLine(a.getOrigin(), a.getPointAt(1), ta);
		ebene.getIntersectionWithLine(b.getOrigin(), b.getPointAt(1), tb);

		Vec3 d = a.getPointAt(ta) - b.getPointAt(tb);

		m_Translation = m_Translation + transform(d, m_Rotation );
	}

	mouse = point;
}
Пример #23
0
int VirtualInputDevice::pickButton(const InputDevice* device,const Ray& ray) const
	{
	int result=-1;
	Point buttonPos=device->getTransformation().getOrigin();
	buttonPos+=buttonOffset;
	buttonPos-=buttonPanelDirection*(Scalar(0.5)*buttonSpacing*Scalar(device->getNumButtons()-1));
	Vector buttonStep=buttonPanelDirection*buttonSpacing;
	Scalar bs=Scalar(glyphRenderer->getGlyphSize())*buttonSize*Scalar(0.5);
	Scalar lambdaMin=Math::Constants<Scalar>::max;
	for(int buttonIndex=0;buttonIndex<device->getNumButtons();++buttonIndex)
		{
		Scalar lMin=Scalar(0);
		Scalar lMax=lambdaMin;
		for(int i=0;i<3;++i)
			{
			Scalar l1,l2;
			if(ray.getDirection()[i]<Scalar(0))
				{
				l1=(buttonPos[i]+bs-ray.getOrigin()[i])/ray.getDirection()[i];
				l2=(buttonPos[i]-bs-ray.getOrigin()[i])/ray.getDirection()[i];
				}
			else if(ray.getDirection()[i]>Scalar(0))
				{
				l1=(buttonPos[i]-bs-ray.getOrigin()[i])/ray.getDirection()[i];
				l2=(buttonPos[i]+bs-ray.getOrigin()[i])/ray.getDirection()[i];
				}
			else if(buttonPos[i]-bs<=ray.getOrigin()[i]&&ray.getOrigin()[i]<buttonPos[i]+bs)
				{
				l1=Scalar(0);
				l2=lambdaMin;
				}
			else
				l1=l2=Scalar(-1);
			if(lMin<l1)
				lMin=l1;
			if(lMax>l2)
				lMax=l2;
			}
		
		if(lMin<lMax)
			{
			result=buttonIndex;
			lambdaMin=lMin;
			}
		
		/* Go to next button: */
		buttonPos+=buttonStep;
		}
	
	return result;
	}
    //-----------------------------------------------------------------------
    bool BspRaySceneQuery::processNode(const BspNode* node, const Ray& tracingRay, 
        RaySceneQueryListener* listener, Real maxDistance, Real traceDistance)
    {
        if (node->isLeaf())
        {
            return processLeaf(node, tracingRay, listener, maxDistance, traceDistance);
        }

        bool res = true;
        std::pair<bool, Real> result = tracingRay.intersects(node->getSplitPlane());
        if (result.first && result.second < maxDistance)
        {
            // Crosses the split plane, need to perform 2 queries
            // Calculate split point ray
            Vector3 splitPoint = tracingRay.getOrigin() 
                + tracingRay.getDirection() * result.second;
            Ray splitRay(splitPoint, tracingRay.getDirection());

            if (node->getSide(tracingRay.getOrigin()) == Plane::NEGATIVE_SIDE)
            {
                // Intersects from -ve side, so do back then front
                res = processNode(
                    node->getBack(), tracingRay, listener, result.second, traceDistance);
                if (!res) return res;
                
                res = processNode(
                    node->getFront(), splitRay, listener, 
                    maxDistance - result.second, 
                    traceDistance + result.second);
            }
            else
            {
                // Intersects from +ve side, so do front then back
                res = processNode(node->getFront(), tracingRay, listener, 
                    result.second, traceDistance);
                if (!res) return res;
                res = processNode(node->getBack(), splitRay, listener,
                    maxDistance - result.second, 
                    traceDistance + result.second);
            }
        }
        else
        {
            // Does not cross the splitting plane, just cascade down one side
            res = processNode(node->getNextNode(tracingRay.getOrigin()),
                tracingRay, listener, maxDistance, traceDistance);
        }

        return res;
    }
Пример #25
0
	vnl_matrix<double> CameraTransform(const Ray &View1, const Ray &View2)
	{
		//This function takes two rays (ie 2 sets of view points and view directions), and finds the matrix M between them (from V1 to V2)
		
		vgl_point_3d<double> A1 = View1.getOrigin();
		vgl_point_3d<double> A2 = View1.PointAlong(1.0);
		
		vgl_point_3d<double> B1 = View2.getOrigin();
		vgl_point_3d<double> B2 = View2.PointAlong(1.0);
		
		vtkSmartPointer<vtkLandmarkTransform> LandmarkTransform = vtkSmartPointer<vtkLandmarkTransform>::New();
		vtkSmartPointer<vtkPoints> SourcePoints = vtkSmartPointer<vtkPoints>::New();
		vtkSmartPointer<vtkPoints> TargetPoints = vtkSmartPointer<vtkPoints>::New();

		double A1array[3] = {A1.x(), A1.y(), A1.z()};
		SourcePoints->InsertNextPoint(A1array);
		
		double A2array[3] = {A2.x(), A2.y(), A2.z()};
		SourcePoints->InsertNextPoint(A2array);
		
		double B1array[3] = {B1.x(), B1.y(), B1.z()};
		TargetPoints->InsertNextPoint(B1array);
		
		double B2array[3] = {B2.x(), B2.y(), B2.z()};
		TargetPoints->InsertNextPoint(B2array);
		
		LandmarkTransform->SetSourceLandmarks(SourcePoints);
		LandmarkTransform->SetTargetLandmarks(TargetPoints);
		LandmarkTransform->SetModeToRigidBody();
		LandmarkTransform->Update();
	
		vnl_matrix<double> Trans(4,4);
		vtkMatrix4x4* M = LandmarkTransform->GetMatrix();
		
		//cout << M << endl;
		
		for(unsigned int r = 0; r < 4; r++)
		{
			for(unsigned int c = 0; c < 4; c++)
			{
				Trans(r,c) = M->GetElement(r,c);
			}
		}
		
		//cout << Trans << endl;
		
		return Trans;
		
	}
Пример #26
0
	std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
	{
		std::string handle = "";

        //get a ray pointing to the center of the viewport
        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
        mRender.getViewport()->getWidth()/2,
        mRender.getViewport()->getHeight()/2);
        //let's avoid the capsule shape of the player.
        centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection());
        btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
        btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y);

        return mEngine->rayTest(from,to);
    }
Пример #27
0
    Vector3 GridSource::getIntersectionEnd(const Ray &ray, Real maxDistance) const
    {
        AxisAlignedBox box((Real)0, (Real)0, (Real)0, (Real)mWidth / mPosXScale, (Real)mHeight / mPosYScale, (Real)mDepth / mPosZScale);
        Vector3 direction = ray.getDirection().normalisedCopy();
        Vector3 invertedDirection = (Real)-1.0 * direction;
        Vector3 origin = ray.getOrigin() + direction * box.getSize().length();

        Ray inverted(origin, invertedDirection);
        std::pair<bool, Real> intersection = inverted.intersects(box);
        if (intersection.first)
        {
            return origin + invertedDirection * intersection.second;
        }
        return ray.getOrigin() + direction * maxDistance;
    }
Пример #28
0
bool Torus::hit(const Ray& ray, float& tmin, ShadeRec& sr) const
{
	if(!bbox.hit(ray))
		return false;

	glm::vec3 origin = ray.getOrigin();
	glm::vec3 dir = ray.getDirection();

	float coefs[5];
	float roots[4];

	//define coefficients
	float sumDSquared = glm::dot(dir,dir);
	float e = glm::dot(origin,origin) - sweptRadiusSQ - tubeRadiusSQ;
	float f = glm::dot(origin,dir);
	float fourASquared = 4.0f * sweptRadiusSQ;

	coefs[0] = e * e - fourASquared * (tubeRadiusSQ - origin.y * origin.y);
	coefs[1] = 4.0f * f * e + 2.0f * fourASquared * origin.y * dir.y;
	coefs[2] = 2.0f * sumDSquared * e + 4.0f * f * f + fourASquared * dir.y * dir.y;
	coefs[3] = 4.0f * sumDSquared * f;
	coefs[4] = sumDSquared * sumDSquared;

	int numRealRoots = solveQuartic(coefs,roots);

	bool intersected = false;
	float t = kHugeValue;

	if(numRealRoots == 0)
		return false;

	for(int i=0;i<numRealRoots;i++)
		if(roots[i] > KEpsilon)
		{
			intersected = true;
			if(roots[i] < t)
				t = roots[i];
		}

	if(!intersected)
		return false;

	tmin = t;
	sr.localHitPoint = ray.getOrigin() + ray.getDirection() * t;
	sr.normal = computeNormals(sr.localHitPoint);

	return true;
}
Пример #29
0
bool Sphere::intersect(const Ray& ray, RaySurfIntersection& res)const{
    res.shp = NULL;

    //Transform ray to object space
    const Ray rOb = w2o(ray);

    const Vector o = Vector(rOb.getOrigin().x, rOb.getOrigin().y, rOb.getOrigin().z);
    const Vector d = rOb.getDir();
    const float A = d.dot(d);
    const float B = 2.0f * (d.dot(o));
    const float C = o.dot(o) - (r * r);


    struct MathUtils::QuadraticEqnRes<float> slv =
        MathUtils::solveQuadratic<float>(A, B, C);
    float tHitFinal = 0.0f; //After the below code this will eventually be set to
    //the first hit point in front of the camera
    if(slv.solCount == 0){
        return false;
    }else if(slv.solCount == 1){
        tHitFinal = slv.sol1;
        if(tHitFinal < 0.0f){
            //No solutions in front of camera
            return false;
        }
    }else{ //2 solutions
        //Find smallest t value that is > 0.0f
        if(slv.sol1 < 0.0f && slv.sol2 < 0.0f){
            //No solutions in front of camera
            return false;
        }else{
            //At least one hit in front of camera
            slv.sol1 = slv.sol1 < 0.0f ? Constants::MAX_FLOAT_VAL : slv.sol1;
            slv.sol2 = slv.sol2 < 0.0f ? Constants::MAX_FLOAT_VAL : slv.sol2;
            tHitFinal = std::min<float>(slv.sol1, slv.sol2);
        }
    }

    //Make sure hit is in front of camera
    Assert(tHitFinal >= 0.0f);

    res.tHit = tHitFinal;
    res.locWS = ray(res.tHit);
    Vector normalVecAtHit = res.locWS - o2w(Point(0.0f,0.0f,0.0f));
    res.n = normalVecAtHit.getNormalized();
    res.shp = this;
    return true;
}
	// ---------------------------------------------------------------------------------
	bool ConvexPolygon::isHitBy(const Ray& ray) const {
		// Create a RayStart->Edge defined plane. 
		// If the intersection of the ray to the polygon's plane is inside for all the planes, it is inside the poly
		// By inside, I mean the point is on positive side of the plane
		std::pair<bool, Real> intersection = ray.intersects(mPlane);
		
		if (!intersection.first) 
			return false;
		
		// intersection point
		Vector3 ip     = ray.getPoint(intersection.second);
		Vector3 origin = ray.getOrigin();
				
		unsigned int pointcount = mPoints.size();
		for (unsigned int idx = 0; idx < pointcount; idx++) {
			int iv2 = (idx + 1) % pointcount;
			
			Vector3 v1 = mPoints[idx];
			Vector3 v2 = mPoints[iv2];
			
			Plane frp(origin, v1, v2);
			
			// test whether the intersection is inside
			if (frp.getSide(ip) != Plane::POSITIVE_SIDE)
				return false;
		}
		
		return true;
	}