Example #1
0
void Octree::_FattenedRayLookup(int nindex,const Ray3D& ray,Real radius,vector<int>& nodeindices) const
{
  const OctreeNode& node = nodes[nindex];
  //this is kinda slower than it needs to be... can determine intersecting
  //children directly without testing all bb's
  if(IsLeaf(node)) {
    //fine grained test
    if(ray.distance(node.bb) <= radius)
      nodeindices.push_back(nindex);
  }
  else {
    vector<pair<Real,int> > children;
    for(int i=0;i<8;i++) {
      Real tmin = 0;
      Real tmax = Inf;
      AABB3D fattened = nodes[node.childIndices[i]].bb;
      fattened.bmin -= Vector3(radius);
      fattened.bmax += Vector3(radius);
      if(ray.intersects(fattened,tmin,tmax))
	children.push_back(pair<Real,int>(tmin,node.childIndices[i]));
    }
    //loop through children, sorted by distance
    sort(children.begin(),children.end());
    for(size_t i=0;i<children.size();i++)
      _FattenedRayLookup(children[i].second,ray,radius,nodeindices);
  }
}
Example #2
0
bool RayTracer::render () {
    Ray3D ray;

    ray.setOrigin (Vector3 (0, 0, 5));

    float sigmaX = static_cast<float> (_left);
    float sigmaY = static_cast<float> (_top);

    for (int curScanLine = 0; curScanLine < _bitmap.getHeight (); curScanLine++) {
        for (int x = 0; x < _bitmap.getWidth (); x++) {
            ray.setDirection (Vector3 (sigmaX, sigmaY, 0) - ray.getOrigin ());	//no need to normalize - Ray3D does this automatically for us!

            Color pixelColor = traceRay (ray, 999999999.0f);

            if (_bitmap.putPixel (x, curScanLine, pixelColor) != E_SUCCESS) {
                return (_done = false);
            }

            sigmaX += _deltaX;
        }

        sigmaX = static_cast<float> (_left);
        sigmaY += _deltaY;
    }

    _done = true;

    return _done;
}
Example #3
0
static
bool F_Hit_Translate_Handle_At_Center( APlaceable* o, const EdSceneViewport& viewport )
{
	const Ray3D	eyeRay = GetEyeRay(viewport);
	const FLOAT	dist = eyeRay.Distance( o->GetOrigin() );
	const FLOAT	pickingDist = F_Get_Translate_Handle_Radius( eyeRay.origin, o->GetOrigin() );
	return dist < pickingDist;
}
bool Ray3DRect3DIntersection(const Rect3D & rect, const Ray3D & ray, float & t)
{
    return Ray3DRect3DIntersection(
        rect.origin(),
        rect.right(),
        rect.up(),
        ray.origin(),
        ray.direction(),
        t);
}
glm::vec2 Rect3DRay3DIntersectionPoint(
    const Rect3D & rect, const Ray3D & ray, bool & valid)
{
    return Rect3DRay3DIntersectionPoint(
        rect.origin(),
        rect.right(),
        rect.up(),
        ray.origin(),
        ray.direction(),
        valid);
}
Example #6
0
void Ray3D::closestPoint(const Ray3D& r,Real& t,Real& u) const
{
  Line3D::closestPoint(r,t,u);
  if(t < 0) {
    t=0;
    u=r.closestPointParameter(source);
  }
  if(u < 0) {
    u=0;
    t=r.closestPointParameter(r.source);
  }
  if(t < 0) t=0;
}
Example #7
0
/**
 * A ray is represented by l0 + l * t = p
 *      l0 - ray origin
 *      l  - ray direction
 *      t  - parameter
 *      p  - point on plane
 * A plane is represented by (p - p0) dot n = 0 (because perpendicular)
 *      p0 - a point representing the distance from the origin
 *      n  - normal of plane
 * Solving for t by substituting p gives that
 * t = [ (p0 - l0) dot n ] / [ l dot n ]
 */
double Plane::findIntersection(const Ray3D & ray) const {
    Vector3D rayDirection = ray.getDirection();
    Vector3D l = rayDirection;
    Vector3D n = normal;
    double ldotn = l.dotProduct(n);
    if (0 == ldotn) { // Ray is || to plane
        return -1; // Never intersects
    } else {
        Vector3D p0 = normal * distance;
        Vector3D l0 = ray.getOrigin();
        double numerator = (p0 - l0).dotProduct(n);
        return numerator / ldotn;
    }
}
Example #8
0
int OctreePointSet::RayCast(const Ray3D& r,Real radius) const
{
  vector<int> raynodes;
  FattenedRayLookup(r,radius,raynodes);
  Vector3 temp;
  Real r2 = radius*radius;
  for(size_t i=0;i<raynodes.size();i++) {
    const vector<Vector3>& pts = pointLists[raynodes[i]];
    const vector<int>& bids = idLists[raynodes[i]];
    Real closest = Inf;
    int result = -1;
    for(size_t k=0;k<pts.size();k++) {
      Real t = r.closestPoint(pts[k],temp);
      if(pts[k].distanceSquared(temp) <= r2) {
	if(t < closest) {
	  closest = t;
	  result = bids[k];
	}
      }
    }
    if(result >= 0)
      return result;
  }
  return -1;
}
Example #9
0
bool Triangle3::intersectsLocal(const Ray3D& ray) const {
    Vector3D n = faceNormal();
    double nd = n.dot(ray.direction);

    if (nd < std::numeric_limits<double>::epsilon()) {
        return false;
    }

    double d = n.dot(points[0]);
    double t = (d - n.dot(ray.origin)) / nd;

    if (t < 0.0) {
        return false;
    }

    Vector3D q = ray.pointAt(t);

    Vector3D q01 = (points[1] - points[0]).cross(q - points[0]);
    if (n.dot(q01) <= 0.0) {
        return false;
    }

    Vector3D q12 = (points[2] - points[1]).cross(q - points[1]);
    if (n.dot(q12) <= 0.0) {
        return false;
    }

    Vector3D q02 = (points[0] - points[2]).cross(q - points[2]);
    if (n.dot(q02) <= 0.0) {
        return false;
    }

    return true;
}
Example #10
0
void Octree::RayLookup(const Ray3D& ray,vector<int>& nodeindices) const
{
  nodeindices.resize(0);
  Real tmin=0,tmax=Inf;
  if(!ray.intersects(nodes[0].bb,tmin,tmax)) 
    return;
  _RayLookup(0,ray,nodeindices);
}
Example #11
0
void Octree::FattenedRayLookup(const Ray3D& ray,Real radius,vector<int>& nodeindices) const
{
  nodeindices.resize(0);
  Real tmin=0,tmax=Inf;
  AABB3D fattened = nodes[0].bb;
  fattened.bmin -= Vector3(radius);
  fattened.bmax += Vector3(radius);
  if(!ray.intersects(fattened,tmin,tmax)) 
    return;
  _FattenedRayLookup(0,ray,radius,nodeindices);
}
Example #12
0
SurfaceRayIntersection3 Triangle3::closestIntersectionLocal(
        const Ray3D& ray) const {
    SurfaceRayIntersection3 intersection;
    Vector3D n = faceNormal();
    double nd = n.dot(ray.direction);

    if (nd < std::numeric_limits<double>::epsilon()) {
        intersection.isIntersecting = false;
        return intersection;
    }

    double d = n.dot(points[0]);
    double t = (d - n.dot(ray.origin)) / nd;

    if (t < 0.0) {
        intersection.isIntersecting = false;
        return intersection;
    }

    Vector3D q = ray.pointAt(t);

    Vector3D q01 = (points[1] - points[0]).cross(q - points[0]);
    if (n.dot(q01) <= 0.0) {
        intersection.isIntersecting = false;
        return intersection;
    }

    Vector3D q12 = (points[2] - points[1]).cross(q - points[1]);
    if (n.dot(q12) <= 0.0) {
        intersection.isIntersecting = false;
        return intersection;
    }

    Vector3D q02 = (points[0] - points[2]).cross(q - points[2]);
    if (n.dot(q02) <= 0.0) {
        intersection.isIntersecting = false;
        return intersection;
    }

    double a = area();
    double b0 = 0.5 * q12.length() / a;
    double b1 = 0.5 * q02.length() / a;
    double b2 = 0.5 * q01.length() / a;

    Vector3D normal = b0 * normals[0] + b1 * normals[1] + b2 * normals[2];

    intersection.isIntersecting = true;
    intersection.distance = t;
    intersection.point = q;
    intersection.normal = normal.normalized();

    return intersection;
}
Example #13
0
Color RayTracer::traceRay (Ray3D ray, float distance) {
    Primitive* closestPrim = NULL;
    float newDistance;
    Color color (0.0, 0.0, 0.0);

    for (int i = 0; i < _scene->getNumberOfPrimitives (); i++) {
        newDistance = _scene->getPrimitive (i)->findIntersectionWith (ray, distance);
        if ((newDistance >= 0.0) && (newDistance < distance)) {
            closestPrim = _scene->getPrimitive (i);
            distance = newDistance;
        }
    }

    if (closestPrim == NULL) {
        return color;
    }

    if (closestPrim->getIsLight ()) {
        color = closestPrim->getColor ();
        return color;
    }

    // calculate diffuse lighting
    Vector3 pointOfIntersection = ray.getDirection () * distance + ray.getOrigin ();
    Vector3 normal = closestPrim->getNormalAt (pointOfIntersection);
    for (int i = 0; i < _scene->getNumberOfPrimitives (); i++) {
        Primitive* light = _scene->getPrimitive (i);
        if (!light->getIsLight ()) { 
            // wait, this isn't actually a light ...
            continue;
        }

        Vector3 lightDir = light->getOrigin () - pointOfIntersection;
        lightDir.normalize();
        float lightCoef = normal.dotProduct (lightDir);
        color = color + closestPrim->getColor () * light->getColor () * lightCoef;
    }

    return color;
}
Example #14
0
bool UVSphere::shadowHit(const Ray3D& r, float tmin, float tmax, float time) const
{

	Vector3D temp = r.getOrigin() - center;

	double a = dotProduct(r.getDirection(), r.getDirection());
	double b = 2*dotProduct(r.getDirection(), temp);
	double c = dotProduct(temp, temp) - radius*radius;

	double disc = b*b -4*a*c;
	//is there some intersection

	if(disc > 0.0) {
		disc = sqrt(disc);
		double t = (-b - disc) / (2.0*a);
		if (t < tmin)
			t = (-b + disc) /(2.0*a);
		if (t < tmin || t > tmax)
			return false;
		return true;
	}
	return false;
}
Example #15
0
// Return distance from ray origin to intersection
// See comments for variables and the equations in Plane.cpp's findIntersection
double Triangle::findIntersection(const Ray3D & ray) const {
    // See if the ray intersects the bounding box
    // *** With bounding box
    if (!Object::intersectsBBox(ray)) { return -1; }
    // First check if the ray intersects with the plane (use same calculations)
    Vector3D rayDirection = ray.getDirection();
    Vector3D rayOrigin = ray.getOrigin();
    double ldotn = rayDirection.dotProduct(normal);
    if (0 == ldotn) { // Ray is || to triangle
        return -1;
    } else {
        Vector3D p0 = normal * distance;
        double distanceToPlane = (p0 - rayOrigin).dotProduct(normal) / ldotn;
        // Then see if the point is inside the triangle (3 conditions)
        // Q is the point of intersection
        Vector3D Q = (rayDirection * distanceToPlane) + rayOrigin;
        Vector3D sideCA = epC - epA;
        Vector3D segQA = Q - epA;
        // 1. (CA x QA) * n >= 0
        if (sideCA.crossProduct(segQA).dotProduct(normal) < 0) {
            return -1;
        }
        Vector3D sideBC = epB - epC;
        Vector3D segQC = Q - epC;
        // 2. (BC x QC) * n >= 0
        if (sideBC.crossProduct(segQC).dotProduct(normal) < 0) {
            return -1;
        }
        Vector3D sideAB = epA - epB;
        Vector3D segQB = Q - epB;
        // 3. (AB x QB) * n >= 0
        if (sideAB.crossProduct(segQB).dotProduct(normal) < 0) {
            return -1;
        }
        return distanceToPlane;
    }
}
SurfaceRayIntersection3 ImplicitSurfaceSet3::closestIntersectionLocal(
    const Ray3D& ray) const {
    buildBvh();

    const auto testFunc = [](const Surface3Ptr& surface, const Ray3D& ray) {
        SurfaceRayIntersection3 result = surface->closestIntersection(ray);
        return result.distance;
    };

    const auto queryResult = _bvh.closestIntersection(ray, testFunc);
    SurfaceRayIntersection3 result;
    result.distance = queryResult.distance;
    result.isIntersecting = queryResult.item != nullptr;
    if (queryResult.item != nullptr) {
        result.point = ray.pointAt(queryResult.distance);
        result.normal = (*queryResult.item)->closestNormal(result.point);
    }
    return result;
}
Example #17
0
void OctreePointSet::RayQuery(const Ray3D& r,Real radius,vector<Vector3>& points,vector<int>& ids) const
{
  points.resize(0);
  ids.resize(0);
  vector<int> raynodes;
  FattenedRayLookup(r,radius,raynodes);
  Vector3 temp;
  Real r2 = radius*radius;
  for(size_t i=0;i<raynodes.size();i++) {
    const vector<Vector3>& pts = pointLists[raynodes[i]];
    const vector<int>& bids = idLists[raynodes[i]];
    for(size_t k=0;k<pts.size();k++) {
      r.closestPoint(pts[k],temp);
      if(pts[k].distanceSquared(temp) <= r2) {
	points.push_back(pts[k]);
	ids.push_back(bids[k]);
      }
    }
  }
}
Example #18
0
void Octree::_RayLookup(int nindex,const Ray3D& ray,vector<int>& nodeindices) const
{
  const OctreeNode& node = nodes[nindex];
  //this is kinda slower than it needs to be... can determine intersecting
  //children directly without testing all bb's
  if(IsLeaf(node)) nodeindices.push_back(nindex);
  else {
    vector<pair<Real,int> > children;
    for(int i=0;i<8;i++) {
      Real tmin = 0;
      Real tmax = Inf;
      if(ray.intersects(nodes[node.childIndices[i]].bb,tmin,tmax))
	children.push_back(pair<Real,int>(tmin,node.childIndices[i]));
    }
    //loop through children, sorted by distance
    sort(children.begin(),children.end());
    for(size_t i=0;i<children.size();i++)
      _RayLookup(children[i].second,ray,nodeindices);
  }
}
Example #19
0
bool UVSphere::hit(const Ray3D& r, float tmin, float tmax, float time, HitRecord& record) const
{
	Vector3D temp = r.getOrigin() - center;

	double a = dotProduct(r.getDirection(), r.getDirection());
	double b = 2*dotProduct(r.getDirection(), temp);
	double c = dotProduct(temp, temp) - radius*radius;

	double disc = b*b -4*a*c;
	//is there some intersection

	if(disc > 0.0) {
		disc = sqrt(disc);
		double t = (-b - disc) / (2.0*a);
		if (t < tmin)
			t = (-b + disc) /(2.0*a);
		if (t < tmin || t > tmax)
			return false;

		record.t = t;
		record.p = record.texp = (r.getOrigin() + t*r.getDirection());
		record.uvw.initFromW((record.p - center) / radius);

		Vector3D n = (record.p - center) / radius;
		float twopi = 6.28318530718f;
		float theta = acos(n.getZ());
		float phi = atan2(n.getY(), n.getX());
		if (phi < 0.0f) phi+= twopi;

		float one_over_2pi = .159154943029f;
		float one_over_pi = .318309886184f;
		float pi = 3.14159;
		record.uv = Vector2D(phi*one_over_2pi, (pi-theta)*one_over_pi);

		record.mat_ptr = material;
		return true;
	}
	return false;
}
Example #20
0
bool TransformWidget::Hover(int x,int y,Camera::Viewport& viewport,double& distance)
{
  Real globalScale = 1.0;
  if(scaleToScreen) {
    float sx,sy,sz;
    viewport.project(T.t,sx,sy,sz);
    globalScale = sz/viewport.scale;
  }
  distance = Inf;
  int oldHoverItem = hoverItem;
  hoverItem = -1;
  Ray3D r;
  viewport.getClickSource(x,y,r.source);
  viewport.getClickVector(x,y,r.direction);
  //check origin
  if(enableTranslation && enableOriginTranslation) {
    Sphere3D s;
    s.center = T.t;
    s.radius = originRadius*globalScale;
    Real tmin,tmax;
    if(s.intersects(r,&tmin,&tmax)) {
      distance = tmin;
      hoverItem = 0;
    }
  }
  //check translation axes
  for(int i=0;i<3;i++) {
    if(!enableTranslation) break;
    if(!enableTranslationAxes[i]) continue;
    Line3D axisLine;
    axisLine.source = T.t;
    axisLine.direction = Vector3(T.R.col(i));
    Real t,u;
    axisLine.closestPoint(r,t,u);
    t = Clamp(t,0.0,axisLength*globalScale);
    u = Clamp(u,0.0,Inf);
    Vector3 paxis,pray;
    axisLine.eval(t,paxis);
    r.eval(u,pray);
    if(paxis.distanceSquared(pray) <= Sqr(axisRadius*globalScale)) {
      if(u < distance) {
	distance = u;
	hoverItem = 1+i;
      }
    }
  }
  if(enableRotation) {
    //check rotation rings
    Circle3D c;
    c.center = T.t;
    for(int i=0;i<3;i++) {
      if(!enableRotationAxes[i]) continue;
      c.axis = Vector3(T.R.col(i));
      c.radius = ringOuterRadius*globalScale;
      Real t;
      if(c.intersects(r,&t) && t >= 0) {
	c.radius = ringInnerRadius*globalScale;
	if(!c.intersects(r,NULL)) {
	  if(t < distance) {
	    distance = t;
	    hoverItem = i+4;
	  }
	}
      }
    }
  }
  if(enableRotation && enableOuterRingRotation) {
    //check outer ring
    Circle3D c;
    c.center = T.t;
    viewport.getViewVector(c.axis);
    c.radius = (ringOuterRadius+arrowHeight)*globalScale;
    Real t;
    if(c.intersects(r,&t) && t >= 0) {
      c.radius = (ringInnerRadius+arrowHeight)*globalScale;
      if(!c.intersects(r,NULL)) {
	if(t < distance) {
	  distance = t;
	  hoverItem = 7;
	}
      }
    }
    clickAxis = c.axis;
  }
  if(hoverItem != oldHoverItem) Refresh();
  r.eval(distance,hoverPos);
  return hoverItem != -1;
}
Example #21
0
TEST(Ray3, PointAt) {
    Ray3D ray;
    EXPECT_EQ(Vector3D(4.5, 0.0, 0.0), ray.pointAt(4.5));
}
bool Intersect(const Ray3D & ray, const Sphere & sphere)
{
    auto nray = ray.normalized();
    return NormalizedRay3DSphereIntersection(nray.origin(), nray.direction(), sphere.position(), sphere.radius());
}