Subversion Repositories gelsvn

Rev

Rev 290 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 290 Rev 294
Line 1... Line 1...
1
#ifndef __RAY_H__
1
#ifndef __RAY_H__
2
#define __RAY_H__
2
#define __RAY_H__
3
 
3
 
-
 
4
#include "../CGLA/Vec3i.h"
4
#include "CGLA/Vec3f.h"
5
#include "../CGLA/Vec3f.h"
5
#include "Geometry/TriMesh.h"
6
#include "TriMesh.h"
6
 
7
 
7
namespace Geometry 
8
namespace Geometry 
8
{
9
{
9
  const double d_eps = 0.000001;
10
  const double d_eps = 0.000001;
10
  const float f_eps = 0.01f;
11
  const float f_eps = 0.01f;
11
 
12
 
12
  struct Ray 
13
  struct Ray 
13
  {
14
  {
14
    // Constructor
15
    // Constructor
15
    Ray() 
16
    Ray() 
16
      : origin(0), direction(0), hit_pos(0), hit_normal(0), 
17
      : origin(0.0f), direction(0.0f), hit_pos(0.0f), hit_normal(0.0f), 
17
        has_hit(false), dist(CGLA::BIG), ior(1), u(0), v(0), 
18
        has_hit(false), dist(CGLA::BIG), ior(1.0f), u(0.0f), v(0.0f), 
-
 
19
	hit_object(0)
-
 
20
    { }
-
 
21
 
-
 
22
    Ray(const CGLA::Vec3f& _origin, const CGLA::Vec3f& _direction) 
-
 
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), 
18
	hit_object(0)
25
	hit_object(0)
19
    { }
26
    { }
20
 
27
 
21
    CGLA::Vec3f origin;
28
    CGLA::Vec3f origin;
22
    CGLA::Vec3f direction;
29
    CGLA::Vec3f direction;
Line 29... Line 36...
29
    float ior;    // Current index of refraction for media
36
    float ior;    // Current index of refraction for media
30
    float u, v;   // uv-coordinates on current surface
37
    float u, v;   // uv-coordinates on current surface
31
    float ran;
38
    float ran;
32
 
39
 
33
    int trace_depth;  // Current recursion number
40
    int trace_depth;  // Current recursion number
34
    int hit_face_id;
41
    size_t hit_face_id;
35
    int id;
42
    int id;
36
 
43
 
37
    Geometry::TriMesh* hit_object;
44
    Geometry::TriMesh* hit_object;
38
 
45
 
39
    void reset()
46
    void reset()
40
    {
47
    {
41
      dist = CGLA::BIG; 
48
      dist = CGLA::BIG; 
42
      hit_object = 0;
49
      hit_object = 0;
43
      u=0;
50
      u=0.0f;
44
      v=0;
51
      v=0.0f;
45
      has_hit=false;      
52
      has_hit=false;      
46
    }
53
    }
47
 
54
 
-
 
55
    void compute_position()
-
 
56
    {
-
 
57
      hit_pos = origin + dist*direction;      
-
 
58
    }
-
 
59
    
-
 
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
    }
-
 
68
 
48
    void reflect(const CGLA::Vec3f &normal)
69
    void reflect(const CGLA::Vec3f &normal)
49
    {
70
    {
50
      assert(dot(direction, normal) < 0);
71
      assert(dot(direction, normal) < 0.0f);
51
      direction = normal*2.0f*dot(-direction,normal) + direction;      
72
      direction = normal*2.0f*dot(-direction,normal) + direction;      
52
    }
73
    }
53
 
74
 
54
    void refract(const CGLA::Vec3f& normal, float new_ior)
75
    void refract(const CGLA::Vec3f& normal, float new_ior)
55
    {
76
    {
56
      float ref_ratio = ior/new_ior;
77
      float ref_ratio = ior/new_ior;
57
      float cos_N_I = dot(normal, direction);
78
      float cos_N_I = dot(normal, direction);
58
      CGLA::Vec3f norm(normal);
79
      CGLA::Vec3f norm(normal);
59
 
80
 
60
      if(cos_N_I > 0)
81
      if(cos_N_I > 0.0f)
61
      {
82
      {
62
	norm = -norm;
83
	norm = -norm;
63
	cos_N_I = dot(norm, direction);
84
	cos_N_I = dot(norm, direction);
64
      }
85
      }
65
 
86
 
66
      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);
67
 
88
 
68
      if(selector > 0) 
89
      if(selector > 0.0f) 
69
      {
90
      {
70
	direction = norm*(ref_ratio*(-cos_N_I) - sqrt(selector)) 
91
	direction = norm*(ref_ratio*(-cos_N_I) - sqrt(selector)) 
71
	            + direction*ref_ratio;
92
	            + direction*ref_ratio;
72
	ior = new_ior;
93
	ior = new_ior;
73
      } 
94
      } 
74
      else 
95
      else 
75
	// Total internal reflection.
96
	// Total internal reflection.
76
	reflect(normal);
97
	reflect(normal);
77
    }
98
    }
-
 
99
 
-
 
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
    }
78
  };
113
  };
79
  
-
 
80
}
114
}
81
#endif
115
#endif