Subversion Repositories gelsvn

Rev

Rev 324 | Rev 422 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
304 jab 1
#ifndef __RAY_H__
2
#define __RAY_H__
3
 
4
#include "../CGLA/Vec3i.h"
5
#include "../CGLA/Vec3f.h"
6
#include "TriMesh.h"
7
 
8
namespace Geometry 
9
{
313 jrf 10
		const double d_eps = 1.0e-12;
11
		const float f_eps = 1.0e-6f;
304 jab 12
 
309 jab 13
		struct Ray 
14
		{
15
				// Constructor
16
				Ray() 
17
						: origin(0.0f), direction(0.0f), hit_pos(0.0f), hit_normal(0.0f), 
304 jab 18
        has_hit(false), dist(CGLA::BIG), ior(1.0f), u(0.0f), v(0.0f), 
309 jab 19
				hit_object(0)
20
						{ }
304 jab 21
 
309 jab 22
				Ray(const CGLA::Vec3f& _origin, const CGLA::Vec3f& _direction) 
23
						: origin(_origin), direction(_direction), hit_pos(0.0f), hit_normal(0.0f), 
304 jab 24
        has_hit(false), dist(CGLA::BIG), ior(1.0f), u(0.0f), v(0.0f), 
309 jab 25
				hit_object(0)
26
						{ }
304 jab 27
 
309 jab 28
				CGLA::Vec3f origin;
29
				CGLA::Vec3f direction;
30
				CGLA::Vec3f hit_pos;
31
				CGLA::Vec3f hit_normal;
304 jab 32
 
309 jab 33
				bool has_hit; // Did the ray hit an object
417 jrf 34
        bool inside;  // Is the ray inside an object
304 jab 35
 
309 jab 36
				double dist;  // Distance from origin to current intersection
37
				float ior;    // Current index of refraction for media
38
				float u, v;   // uv-coordinates on current surface
39
				float ran;
304 jab 40
 
309 jab 41
				int trace_depth;  // Current recursion number
42
				size_t hit_face_id;
43
				int id;
304 jab 44
 
318 awk 45
				const Geometry::TriMesh* hit_object;
304 jab 46
 
309 jab 47
				void reset()
48
						{
49
								dist = CGLA::BIG; 
50
								hit_object = 0;
51
								u=0.0f;
52
								v=0.0f;
53
								has_hit=false;      
54
						}
304 jab 55
 
309 jab 56
				void compute_position()
57
						{
58
								hit_pos = origin + dist*direction;      
59
						}
304 jab 60
 
309 jab 61
				void compute_normal()
62
						{
63
								CGLA::Vec3i face = hit_object->normals.face(hit_face_id);
64
								CGLA::Vec3f normal0 = hit_object->normals.vertex(face[0]);
65
								CGLA::Vec3f normal1 = hit_object->normals.vertex(face[1]);
66
								CGLA::Vec3f normal2 = hit_object->normals.vertex(face[2]);
67
								hit_normal = normalize(normal0*(1 - u - v) + normal1*u + normal2*v);      
68
						}
304 jab 69
 
309 jab 70
				void reflect(const CGLA::Vec3f &normal)
71
						{
72
								assert(dot(direction, normal) < 0.0f);
73
								direction = normal*2.0f*dot(-direction,normal) + direction;      
74
						}
304 jab 75
 
309 jab 76
				void refract(const CGLA::Vec3f& normal, float new_ior)
77
						{
78
								float ref_ratio = ior/new_ior;
79
								float cos_N_I = dot(normal, direction);
80
								CGLA::Vec3f norm(normal);
304 jab 81
 
309 jab 82
								if(cos_N_I > 0.0f)
83
								{
84
										norm = -norm;
85
										cos_N_I = dot(norm, direction);
86
								}
304 jab 87
 
309 jab 88
								float selector = 1+(ref_ratio*ref_ratio)*(cos_N_I*cos_N_I - 1);
304 jab 89
 
309 jab 90
								if(selector > 0.0f) 
91
								{
92
										direction = norm*(ref_ratio*(-cos_N_I) - sqrt(selector)) 
93
												+ direction*ref_ratio;
94
										ior = new_ior;
95
								} 
96
								else 
97
										// Total internal reflection.
98
										reflect(normal);
99
						}
304 jab 100
 
309 jab 101
				bool cond_set_parameter(float t, float _u, float _v, 
102
																Geometry::TriMesh* mesh, size_t idx)
103
						{
104
								if(t < dist)
105
								{
106
										dist = t;
107
										u = _u;
108
										v = _v;
109
										hit_object = mesh;
110
										hit_face_id = idx;
111
										has_hit = true;
324 jab 112
										return true;
309 jab 113
								}
324 jab 114
								return false;
309 jab 115
						}
116
		};
304 jab 117
}
118
#endif
119