include/raytracer.h
author Radek Brich <radek.brich@devl.cz>
Mon, 19 May 2008 22:59:04 +0200
branchpyrit
changeset 98 64638385798a
parent 95 ca7d4c665531
permissions -rw-r--r--
add sections about demos to README update doxygen comments

/**
 * @file  raytracer.h
 * @brief The base class of the ray tracer
 *
 * This file is part of Pyrit Ray Tracer.
 *
 * Copyright 2006, 2007, 2008  Radek Brich
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef RAYTRACER_H
#define RAYTRACER_H

#include <vector>
#include <queue>

#include "common.h"
#include "container.h"
#include "scene.h"

class Raytracer;

/**
 * main ray tracer class
 */
class Raytracer
{
	Container *top;    /**< container with shapes */
	Sampler *sampler;  /**< active sampler */
	Camera *camera;    /**< active camera */
	vector<Light*> lights; /**< array of lights in the scene */
	Colour bg_colour;  /**< background colour */

	/* ambient occlussion parameters */
	Float ao_distance, ao_angle;
	int ao_samples;

	int num_threads;  /**< number of threads to use for rendering */
	int max_depth;    /**< maximum depth of recursion */
	bool use_packets; /**< allow ray packet tracing */

	/* private helper variables */
	Sample *sample_queue;
	int sample_queue_pos, sample_queue_size, sample_queue_count;
	bool end_of_samples;
	pthread_mutex_t sample_queue_mutex, sampler_mutex;
	pthread_cond_t sample_queue_cond, worker_ready_cond;

	/**
	 * Hammersley spherical point distribution function
	 * http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
	 * @param[in] i   sample index
	 * @param[in] n   number of samples
	 * @param[in] extent   angle of dispersion
	 * @param[in] normal   central direction vector
	 */
	Vector SphereDistribute(int i, int n, Float extent, const Vector &normal);

	/**
	 * shader implementing Phong lighting model
	 * @param[in] P    point of intersection
	 * @param[in] N    normal in intersect. point
	 * @param[in] R    direction of reflected ray
	 * @param[in] V    direction to the viewer
	 * @return colour of the surface
	 */
	Colour PhongShader(const Shape *shape,
		const Vector &P, const Vector &N, const Vector &V);

	/** light scattering function */
	void lightScatter(const Ray &ray, const Shape *shape, int depth,
		const Vector &P, const Vector &normal, bool from_inside, Colour &col);

#ifndef NO_SIMD
	VectorPacket PhongShader_packet(const Shape* const* shapes,
		const VectorPacket &P, const VectorPacket &N, const VectorPacket &V);
	void raytracePacket(RayPacket &rays, Colour *results);
#endif

	/** main function of the ray tracing worker */
	NORETURN static void *raytrace_worker(void *d);

public:
	Raytracer(): top(NULL), camera(NULL), lights(), bg_colour(0., 0., 0.),
		ao_samples(0), num_threads(4), max_depth(3), use_packets(true)
	{
		pthread_mutex_init(&sample_queue_mutex, NULL);
		pthread_mutex_init(&sampler_mutex, NULL);
		pthread_cond_init (&sample_queue_cond, NULL);
		pthread_cond_init (&worker_ready_cond, NULL);
	};
	~Raytracer()
	{
		pthread_mutex_destroy(&sample_queue_mutex);
		pthread_mutex_destroy(&sampler_mutex);
		pthread_cond_destroy (&sample_queue_cond);
		pthread_cond_destroy (&worker_ready_cond);
	}

	/** start the rendering process */
	void render();

	/** ray trace one ray */
	Colour raytrace(Ray &ray, int depth, const Shape *origin_shape);

	/** add shape to container */
	void addShape(Shape *shape) { top->addShape(shape); };

	/** add light to scene */
	void addLight(Light *light) { lights.push_back(light); };

	/** set active sampler */
	void setSampler(Sampler *sampl) { sampler = sampl; };
	Sampler *&getSampler() { return sampler; };

	/** set active camera */
	void setCamera(Camera *cam) { camera = cam; };
	Camera *&getCamera() { return camera; };

	/** set active container */
	void setTop(Container *atop) { top = atop; };
	Container *&getTop() { return top; };

	/** set background colour */
	void setBgColour(const Colour &bg) { bg_colour = bg; };

	/** set maximum depth of recursion */
	void setMaxDepth(int newdepth) { max_depth = newdepth; };

	/** set ambient occlusion parameters */
	void ambientOcclusion(int samples, Float distance, Float angle);

	/** set number of threads to use for rendering */
	void setThreads(int num) { num_threads = num; };
};

#endif