Пример #1
0
Geometry::HitResult<double> Section::
intersectRay(const Geometry::Ray<double,3>& ray) const
{
    /* based on "Fast, Minimum Storage Ray/Triangle Intersection" by Tomas
       Moeller and Ben Trumbore */
    Geometry::Vector<double,3> rayOrig(ray.getOrigin()[0],ray.getOrigin()[1],ray.getOrigin()[2]);
    const Geometry::Vector<double,3>& rayDir = ray.getDirection();

    /* begin calculating determinant - also used to calculate U parameter */
    Geometry::Vector<double,3> pvec = Geometry::cross(rayDir, end);
    /* if determinant is near zero, ray lies in plane of triangle */
    Scalar det = start * pvec;

    if (det>-EPSILON && det<EPSILON)
        return Geometry::HitResult<double>();

    Scalar invDet = Scalar(1) / det;

    /* calculate U parameter and test bounds */
    Scalar u = (rayOrig*pvec) * invDet;
    if (u < Scalar(0))
        return Geometry::HitResult<double>();

    /* prepare to test V parameter */
    Geometry::Vector<double,3> qvec = Geometry::cross(rayOrig, start);
    /* calculate V parameter and test bounds */
    Scalar v = (rayDir*qvec) * invDet;
    if (v < Scalar(0))
        return Geometry::HitResult<double>();

    /* calculate t, ray intersects triangle */
    Scalar t = (end*qvec) * invDet;
    return Geometry::HitResult<double>(t);
}
Пример #2
0
Geometry::HitResult<double> Section::
intersectPlane(const Geometry::Ray<double,3>& ray, bool cullBackFace) const
{
    Geometry::Vector<double,3> rayOrig(ray.getOrigin()[0],ray.getOrigin()[1],ray.getOrigin()[2]);
    const Geometry::Vector<double,3>& rayDir = ray.getDirection();

    /* the ray intersects the plane at poing t for which (ray(t)-PlaneOrigin) is
       orthogonal to the normal. See http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm#Line-Plane Intersection
       for nice description */
    double nDotDir = normal * rayDir;

    //exit on back-facing planes if so desired
    if (cullBackFace && nDotDir>0.0)
        return Geometry::HitResult<double>();

    //handle the parallel case
    if (nDotDir>-EPSILON && nDotDir<EPSILON)
    {
        Geometry::Vector<double,3> toOrig    = rayOrig - start;
        double nDotToOrig = normal * toOrig;
        //coincident
        if (nDotToOrig>-EPSILON && nDotToOrig<EPSILON)
            return Geometry::HitResult<double>(0.0);
        //disjoint
        else
            return Geometry::HitResult<double>();
    }

    //compute the intersection parameter
    return Geometry::HitResult<double>((normal * (start - rayOrig)) / nDotDir);
}
Пример #3
0
std::vector<vec3> Orthographic::render(std::vector<std::unique_ptr<WorldObject>> &objects,
									   std::vector<std::unique_ptr<Light>> &lights,
									   vec2 imageSize, double imageAspectRatio, int aaDepth) {
	std::vector<vec3> frameBuffer;
	for (int y = 0; y < imageSize.y; y++) {
		for (int x = 0; x < imageSize.x; x++) {
			vec3 pixel;
			std::vector<vec3> aaData;
			for (int aay = 0; aay < aaDepth; aay++) {
				for (int aax = 0; aax < aaDepth; aax++) {
					// normalize ray pos (-> NDC)
					// add 0.5 so that the final ray passes through the middle of the pixel
					pixel.x = (x + ((1.0 / (aaDepth - 1.0)) * aax)) / imageSize.x;
					pixel.y = (y + ((1.0 / (aaDepth - 1.0)) * aay)) / imageSize.y;

					// map from [0;1] to [-imageAspectRatio;imageAspectRatio]
					pixel.x = 2.0 * pixel.x - 1.0;
					pixel.x *= imageAspectRatio;
					pixel.y = 1.0 - 2.0 * pixel.y;

					double scale = tan(MyMath::degToRad(fov / 2.0));
					pixel.x *= scale;
					pixel.y *= scale;

					vec3 rayOrig(-pixel.x, -pixel.y, 0.0f);
					vec3 rayDir(0.0f, 0.0f, -1.0f);
					rayDir -= rayOrig;
					rayDir = rayDir.normalize();

					Ray ray(rayOrig, rayDir);
					aaData.push_back(ray.cast(objects, lights, 3));
				}
			}

			vec3 sum;
			for (vec3 color : aaData) {
				sum += color;
			}
			sum = sum / aaData.size();
			frameBuffer.push_back(sum);
		}
	}

	return frameBuffer;
}