Subversion Repositories gelsvn

Rev

Rev 304 | Rev 310 | 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
{
309 jab 10
		const double d_eps = 0.000001;
11
		const float f_eps = 0.01f;
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
304 jab 34
 
309 jab 35
				double dist;  // Distance from origin to current intersection
36
				float ior;    // Current index of refraction for media
37
				float u, v;   // uv-coordinates on current surface
38
				float ran;
304 jab 39
 
309 jab 40
				int trace_depth;  // Current recursion number
41
				size_t hit_face_id;
42
				int id;
304 jab 43
 
309 jab 44
				Geometry::TriMesh* hit_object;
304 jab 45
 
309 jab 46
				void reset()
47
						{
48
								dist = CGLA::BIG; 
49
								hit_object = 0;
50
								u=0.0f;
51
								v=0.0f;
52
								has_hit=false;      
53
						}
304 jab 54
 
309 jab 55
				void compute_position()
56
						{
57
								hit_pos = origin + dist*direction;      
58
						}
304 jab 59
 
309 jab 60
				void compute_normal()
61
						{
62
								CGLA::Vec3i face = hit_object->normals.face(hit_face_id);
63
								CGLA::Vec3f normal0 = hit_object->normals.vertex(face[0]);
64
								CGLA::Vec3f normal1 = hit_object->normals.vertex(face[1]);
65
								CGLA::Vec3f normal2 = hit_object->normals.vertex(face[2]);
66
								hit_normal = normalize(normal0*(1 - u - v) + normal1*u + normal2*v);      
67
						}
304 jab 68
 
309 jab 69
				void reflect(const CGLA::Vec3f &normal)
70
						{
71
								assert(dot(direction, normal) < 0.0f);
72
								direction = normal*2.0f*dot(-direction,normal) + direction;      
73
						}
304 jab 74
 
309 jab 75
				void refract(const CGLA::Vec3f& normal, float new_ior)
76
						{
77
								float ref_ratio = ior/new_ior;
78
								float cos_N_I = dot(normal, direction);
79
								CGLA::Vec3f norm(normal);
304 jab 80
 
309 jab 81
								if(cos_N_I > 0.0f)
82
								{
83
										norm = -norm;
84
										cos_N_I = dot(norm, direction);
85
								}
304 jab 86
 
309 jab 87
								float selector = 1+(ref_ratio*ref_ratio)*(cos_N_I*cos_N_I - 1);
304 jab 88
 
309 jab 89
								if(selector > 0.0f) 
90
								{
91
										direction = norm*(ref_ratio*(-cos_N_I) - sqrt(selector)) 
92
												+ direction*ref_ratio;
93
										ior = new_ior;
94
								} 
95
								else 
96
										// Total internal reflection.
97
										reflect(normal);
98
						}
304 jab 99
 
309 jab 100
				bool cond_set_parameter(float t, float _u, float _v, 
101
																Geometry::TriMesh* mesh, size_t idx)
102
						{
103
								if(t < dist)
104
								{
105
										dist = t;
106
										u = _u;
107
										v = _v;
108
										hit_object = mesh;
109
										hit_face_id = idx;
110
										has_hit = true;
111
								}
112
						}
113
		};
304 jab 114
}
115
#endif
116