src/scene.cc
branchpyrit
changeset 0 3547b885df7e
child 7 bf17f9f84c91
equal deleted inserted replaced
-1:000000000000 0:3547b885df7e
       
     1 /*
       
     2  * C++ RayTracer
       
     3  * file: scene.cc
       
     4  *
       
     5  * Radek Brich, 2006
       
     6  */
       
     7 
       
     8 #include <math.h>
       
     9 #include "scene.h"
       
    10 
       
    11 bool Sphere::intersect(const Ray &ray, float &dist)
       
    12 {
       
    13 	Vector3 V = ((Ray)ray).a - center;
       
    14 
       
    15 	float Vd = - dot(V, ray.dir);
       
    16 	float Det = Vd * Vd - (dot(V,V) - sqr_radius);
       
    17 
       
    18 	if (Det > 0) {
       
    19 		Det = sqrtf(Det);
       
    20 		float t1 = Vd - Det;
       
    21 		if (t1 > 0)
       
    22 		{
       
    23 			if (t1 < dist) {
       
    24 				dist = t1;
       
    25 				return true;
       
    26 			}
       
    27 		} else {
       
    28 			float t2 = Vd + Det;
       
    29 			if (t2 > 0)
       
    30 			{
       
    31 				// ray from inside of the sphere
       
    32 				dist = t2;
       
    33 				return true;
       
    34 			}
       
    35 		}
       
    36 	}
       
    37 	return false;
       
    38 }
       
    39 
       
    40 bool Sphere::intersect_all(const Ray &ray, float dist, vector<float> &allts)
       
    41 {
       
    42 	//allts = new vector<float>();
       
    43 
       
    44 	Vector3 V = ((Ray)ray).a - center;
       
    45 	float Vd = - dot(V, ray.dir);
       
    46 	float Det = Vd * Vd - (dot(V,V) - sqr_radius);
       
    47 
       
    48 	if (Det > 0) {
       
    49 		Det = sqrtf(Det);
       
    50 		float t1 = Vd - Det;
       
    51 		float t2 = Vd + Det;
       
    52 		if (t1 < 0)
       
    53 		{
       
    54 			if (t2 > 0)
       
    55 			{
       
    56 				// ray from inside of the sphere
       
    57 				allts.push_back(0.0);
       
    58 				allts.push_back(t2);
       
    59 				return true;
       
    60 			}
       
    61 			else
       
    62 				return false;
       
    63 		}
       
    64 		else
       
    65 		{
       
    66 			allts.push_back(t1);
       
    67 			allts.push_back(t2);
       
    68 			return true;
       
    69 		}
       
    70 	}
       
    71 	return false;
       
    72 }
       
    73 
       
    74 bool Plane::intersect(const Ray &ray, float &dist)
       
    75 {
       
    76 	float dir = dot(N, ray.dir);
       
    77 	if (dir != 0)
       
    78 	{
       
    79 		float newdist = -(dot(N, ray.a) + d) / dir;
       
    80 		if (newdist > 0 && newdist < dist) {
       
    81 			dist = newdist;
       
    82 			return true;
       
    83 		}
       
    84 	}
       
    85 	return false;
       
    86 }
       
    87 
       
    88 // this initialization and following intersection methods implements
       
    89 // Fast Triangle Intersection algorithm from
       
    90 // http://www.mpi-inf.mpg.de/~wald/PhD/
       
    91 Triangle::Triangle(const Vector3 &aA, const Vector3 &aB, const Vector3 &aC, Material *amaterial)
       
    92 	: A(aA), B(aB), C(aC)
       
    93 {
       
    94 	material = amaterial;
       
    95 	Vector3 c = B - A;
       
    96 	Vector3 b = C - A;
       
    97 
       
    98 	N = cross(c, b);
       
    99 
       
   100 	if (fabsf(N.x) > fabsf(N.y))
       
   101 	{
       
   102 		if (fabsf(N.x) > fabsf(N.z))
       
   103 			k = 0;
       
   104 		else
       
   105 			k = 2;
       
   106 	}
       
   107 	else
       
   108 	{
       
   109 		if (fabsf(N.y) > fabsf(N.z))
       
   110 			k = 1;
       
   111 		else
       
   112 			k = 2;
       
   113 	}
       
   114 
       
   115 	int u = (k + 1) % 3;
       
   116 	int v = (k + 2) % 3;
       
   117 
       
   118 	float krec = 1.0f / N[k];
       
   119 	nu = N[u] * krec;
       
   120 	nv = N[v] * krec;
       
   121 	nd = dot(N, A) * krec;
       
   122 
       
   123 	// first line equation
       
   124 	float reci = 1.0f / (b[u] * c[v] - b[v] * c[u]);
       
   125 	bnu = b[u] * reci;
       
   126 	bnv = -b[v] * reci;
       
   127 
       
   128 	// second line equation
       
   129 	cnu = c[v] * reci;
       
   130 	cnv = -c[u] * reci;
       
   131 
       
   132 	// finalize normal
       
   133 	N.normalize();
       
   134 }
       
   135 
       
   136 // see comment for previous method
       
   137 bool Triangle::intersect(const Ray &ray, float &dist)
       
   138 {
       
   139 	Vector3 O = ray.a;
       
   140 	Vector3 D = ray.dir;
       
   141 
       
   142 	const int modulo3[5] = {0,1,2,0,1};
       
   143 	const int ku = modulo3[k+1];
       
   144 	const int kv = modulo3[k+2];
       
   145 	const float lnd = 1.0f / (D[k] + nu * D[ku] + nv * D[kv]);
       
   146 	const float t = (nd - O[k] - nu * O[ku] - nv * O[kv]) * lnd;
       
   147 
       
   148 	if (!(t < dist && t > 0))
       
   149 		return false;
       
   150 
       
   151 	float hu = O[ku] + t * D[ku] - A[ku];
       
   152 	float hv = O[kv] + t * D[kv] - A[kv];
       
   153 	float beta = hv * bnu + hu * bnv;
       
   154 
       
   155 	if (beta < 0)
       
   156 		return false;
       
   157 
       
   158 	float gamma = hu * cnu + hv * cnv;
       
   159 	if (gamma < 0)
       
   160 		return false;
       
   161 
       
   162 	if ((beta + gamma) > 1)
       
   163 		return false;
       
   164 
       
   165 	dist = t;
       
   166 	return true;
       
   167 }