Пример #1
0
/// Returns the distance of the given ray to this line.
/// @param d [out] Receives the distance along this line that specifies the closest point on this line to the given point.
/// @param d2 [out] Receives the distance along the other line that specifies the closest point on that line to this line.
float Ray::Distance(const Ray &other, float *d, float *d2) const
{
    float u2;
    float3 c = ClosestPoint(other, d, &u2);
    if (d2) *d2 = u2;
    return c.Distance(other.GetPoint(u2));
}
Пример #2
0
bool Polygon::Intersects(const Ray &ray) const
{
	float d;
	if (!PlaneCCW().Intersects(ray, &d))
		return false;
	return Contains(ray.GetPoint(d));
}
Пример #3
0
bool Circle::IntersectsDisc(const Ray &ray) const
{
	float d;
	bool intersectsPlane = ray.Intersects(ContainingPlane(), &d);
	if (intersectsPlane)
		return false;
	return ray.GetPoint(d).DistanceSq(pos) <= r*r;
}
Пример #4
0
	int Plane::Intersect(Ray& ray, IntersectResult* result) {
		Normal3dF normal(0, 1, 0);
		float dotA = ray.d.Dot(normal);
		if (dotA >= 0) {
			result = &IntersectResult::NoHit;
			return 0;
		}
		float dotB = normal.Dot(ray.o - position);
		float distance = -dotB / dotA;
		*result = IntersectResult(this, distance, ray.GetPoint(distance), normal);
		return 0;
	}	
Пример #5
0
bool Triangle::Intersects(const Ray &r, float *d, float3 *intersectionPoint) const
{
    float u, v, t;
    bool success = IntersectLineTri(r.pos, r.dir, a, b, c, u, v, t);
    if (!success || t <= 0.f)
        return false;
    if (d)
        *d = t;
    if (intersectionPoint)
        *intersectionPoint = r.GetPoint(t);
    return success;
}
Пример #6
0
bool Triangle::Intersects(const Ray &r, float *d, float3 *intersectionPoint) const
{
	float u, v;
	float t = IntersectLineTri(r.pos, r.dir, a, b, c, u, v);
	bool success = (t >= 0 && t != FLOAT_INF);
	if (!success)
		return false;
	if (d)
		*d = t;
	if (intersectionPoint)
		*intersectionPoint = r.GetPoint(t);
	return success;
}
Пример #7
0
	//http://www.qiujiawei.com/triangle-intersect/
	int Triangle::Intersect(Ray& ray, IntersectResult* result) {
		const VectorArray& vertices = mesh->vertices;
		const Vector3dF& p0 = vertices[indexes[0]];
		const Vector3dF& p1 = vertices[indexes[1]];
		const Vector3dF& p2 = vertices[indexes[2]];
		const Vector3dF&& e1 = p1 - p0;
		const Vector3dF&& e2 = p2 - p0;
		if (mesh->normals[tri_idx].isEmpty()) {
			mesh->normals[tri_idx] = (e1.Cross(e2)).Normalize();
			if (mesh->reverse) {
				mesh->normals[tri_idx] = -mesh->normals[tri_idx];
			
			}
			
		}
		const Normal3dF& normal = mesh->normals[tri_idx];
		float nDotRay = normal.Dot(ray.d);
		if (mesh->face == 0) { //only front face
			if (nDotRay >= 0) {
				return 0;
			}
		}
		else if (mesh->face == 1) { //only back face
			if (nDotRay <= 0) {
				return 0;
			}
		}
		//printf("nDotRay %.1f ray.d: %.2f,%.2f,%.2f len:%.1f  n: %.1f,%.1f,%.1f\n", nDotRay, ray.d.x, ray.d.y, ray.d.z, ray.d.Length(), normal.x, normal.y, normal.z);

		const Vector3dF& s = ray.o - p0;
		const Vector3dF& s1 = ray.d.Cross(e2);
		Real d = s1.Dot(e1);
		if (almost_equal(d, Real(0), 2))
			return 0;
		d = 1. / d;
		const Vector3dF& s2 = s.Cross(e1);
		const Real& r1 = s2.Dot(e2);
		const Real& r2 = s1.Dot(s);
		const Real& r3 = s2.Dot(ray.d);
		const Real& t = r1 * d;
		const Real& b1 = r2 * d;
		if (b1 < 0. || b1 > 1.)
			return 0;
		const Real& b2 = r3 * d;
		if (b2 < 0. || b1 + b2 > 1.)
			return 0;
		const Vector3dF&& position = ray.GetPoint(t);
		*result = IntersectResult(mesh, t, std::forward<const Vector3dF>(position), normal);
		return 0;
	}
Пример #8
0
vec Plane::ClosestPoint(const Ray &ray) const
{
	assume(ray.IsFinite());
	assume(!IsDegenerate());

	// The plane and a ray have three configurations:
	// 1) the ray and the plane don't intersect: the closest point is the ray origin point.
	// 2) the ray and the plane do intersect: the closest point is the intersection point.
	// 3) the ray is parallel to the plane: any point on the ray projected to the plane is a closest point.
	float denom = Dot(normal, ray.dir);
	if (denom == 0.f)
		return Project(ray.pos); // case 3)
	float t = (d - Dot(normal, ray.pos)) / denom;
	if (t >= 0.f && t < 1e6f) // Numerical stability check: Instead of checking denom against epsilon, check the resulting t for very large values.
		return ray.GetPoint(t); // case 2)
	else
		return Project(ray.pos); // case 1)
}
Пример #9
0
 bool operator()(KdTree<Triangle> &tree, const KdTreeNode &leaf, const Ray &ray, float tNear, float tFar)
 {
     u32 *bucket = tree.Bucket(leaf.bucketIndex);
     assert(bucket);
     while(*bucket != KdTree<Triangle>::BUCKET_SENTINEL)
     {
         const Triangle &tri = tree.Object(*bucket);
         float u, v, t;
         t = Triangle::IntersectLineTri(ray.pos, ray.dir, tri.a, tri.b, tri.c, u, v);
         bool intersects = t < std::numeric_limits<float>::infinity();
         if (intersects && t >= tNear && t <= tFar && t < result.t)
         {
             result.t = t;
             result.pos = ray.GetPoint(t);
             result.triangleIndex = *bucket;
             result.submeshIndex = (u32)-1;
             result.barycentricUV = float2(u,v);
         }
         ++bucket;
         
     }
     return result.t < std::numeric_limits<float>::infinity(); // If we hit a triangle, no need to visit any farther nodes, since we are only interested in the nearest hit.
 }
Пример #10
0
float Ray::Distance(const Ray &other, float &d, float &d2) const
{
	vec c = ClosestPoint(other, d, d2);
	return c.Distance(other.GetPoint(d2));
}
Пример #11
0
Color trace(const Scene& scene, Ray ray, int depth)
{
    const Color background(0,0,0);
    const int maxDepth = 3;
    if (depth >= maxDepth)
        return background;

    Color color(0,0,0);
    double distance = 0;
    const Primitive* prim = NULL;
    int intersectionType = 0;

    findNearsetIntersection(scene, ray, &prim, &distance, &intersectionType);

    if (prim != NULL)
    {
        if (prim->IsIlluminative())
        {
            return prim->GetMaterial().GetColor();
        }

        const Vector3 intersectionPoint = ray.GetPoint(distance);
        const Vector3 n = prim->GetNormal(intersectionPoint);

        if (prim->GetMaterial().GetDiffuse() > 0)
        {
            for (Scene::ConstIterator it = scene.Begin(); it != scene.End(); it++)
            {
                const double intensive = getIntensity((*it), intersectionPoint, n, scene);

                if (intensive != .0)
                {
                    Vector3 x = (prim->GetMaterial().GetColor());
                    Vector3 y = ((*it)->GetMaterial().GetColor());

                    color = color + (intensive * prim->GetMaterial().GetDiffuse()) * x * y;
                }
            }
        }

        //refraction
        {
            const Vector3 x = ray.GetDirection();
            const Vector3 y = intersectionType * (-n);

            double n;
            if (intersectionType == IntersectOutside)
                n = 1.0 / prim->GetMaterial().GetRefractionRate();
            else
                n = prim->GetMaterial().GetRefractionRate();

            const double sin_1 = sqrt(1 - Dot(x,y));
            const double sin_2 = n * sin_1;

            if (sin_2 < 1)
            {
                const double cos_2 = sqrt(1 - sin_2);
                Vector3 xPerpendicular = x - Dot(x,y)*y;
                Vector3 z = cos_2 * y + sin_2 * xPerpendicular;
                z.Normalize();

                if (prim->GetMaterial().GetRefraction() > 0)
                {
                    if (intersectionType == IntersectInside)
                    {
                        color = color +
                            prim->GetMaterial().GetRefraction() *
                            exp(-prim->GetMaterial().GetAbsorptionRate()*distance) *
                            trace(scene, Ray(intersectionPoint, z), depth + 1);
                    }
                    else
                        color = color +
                            prim->GetMaterial().GetRefraction() * trace(scene, Ray(intersectionPoint, z), depth + 1);
                }
            }
        }

        //reflection
        if (prim->GetMaterial().GetReflection() > 0)
        {
            const Vector3 a = ray.GetDirection();
            Vector3 newA = a - 2 * (Dot(a,n)) * n;
            color = color + prim->GetMaterial().GetReflection() * trace(scene, Ray(intersectionPoint, newA), depth + 1);
        }
    }
    return color;
}