Subversion Repositories gelsvn

Rev

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

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