Subversion Repositories gelsvn

Rev

Rev 417 | Rev 422 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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