source: trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h @ 162

Revision 162, 6.7 KB checked in by bittner, 19 years ago (diff)

functional raycasting version

Line 
1#ifndef __RAY_H__
2#define __RAY_H__
3
4#include <vector>
5#include "Matrix4x4.h"
6#include "Vector3.h"
7
8// forward declarations
9class Plane3;
10class Intersectable;
11class KdLeaf;
12class MeshInstance;
13
14
15// -------------------------------------------------------------------
16// CRay class.  A ray is defined by a location and a direction.
17// The direction is always normalized (length == 1).
18// -------------------------------------------------------------------
19
20class Ray
21{
22public:
23  enum RayType { LOCAL_RAY, GLOBAL_RAY };
24
25  enum { NO_INTERSECTION=0, INTERSECTION_OUT_OF_LIMITS, INTERSECTION };
26
27  struct RayIntersection {
28    // the point of intersection
29    float mT;
30    // can be either mesh or a viewcell
31    Intersectable *mObject;
32    // the face of the intersectable
33    int mFace;
34    RayIntersection(const float t,
35                    Intersectable *object,
36                    const int face):mT(t), mObject(object), mFace(face) {}
37    RayIntersection() {}
38
39    bool operator<(
40                   const RayIntersection &b) const {
41      return
42        mT
43        <
44        b.mT;
45    }
46
47
48   
49  };
50 
51  vector<RayIntersection> intersections;
52  vector<KdLeaf *> leaves;
53  vector<MeshInstance *> meshes;
54
55  // constructors
56  Ray(const Vector3 &wherefrom,
57      const Vector3 &whichdir,
58      const int _type,
59      const void *_originCell = NULL) {
60    loc = wherefrom;
61    dir = Normalize(whichdir);
62    mType = _type;
63    origin = _originCell;
64    termination = NULL;
65    depth = 0;
66    Init();
67  }
68  // dummy constructor
69  Ray() {}
70
71 
72  // Inititalize the ray again when already constructed
73  void Init(const Vector3 &wherefrom, const Vector3 &whichdir,
74            const int _type, const void *_originCell = NULL,
75            bool dirNormalized = false) {
76    loc = wherefrom;
77    dir = (dirNormalized) ? whichdir: Normalize(whichdir) ;
78    mType = _type;
79    origin = _originCell;
80    termination = NULL;
81    depth = 0;
82    Init();
83  }
84
85  // --------------------------------------------------------
86  // Extrapolate ray given a signed distance, returns a point
87  // --------------------------------------------------------
88  Vector3 Extrap(float t) const {
89    return loc + dir * t;
90  }
91
92  // -----------------------------------
93  // Return parameter given point on ray
94  // -----------------------------------
95  float Interp(Vector3 &x) const {
96    for (int i = 0; i < 3; i++)
97      if (Abs(dir[i]) > Limits::Small)
98        return (x[i] - loc[i]) / dir[i];
99    return 0;
100  }
101
102  // -----------------------------------
103  // Reflects direction of reflection for the ray,
104  // given the normal to the surface.
105  // -----------------------------------
106  Vector3 ReflectRay(const Vector3 &N) const {
107    return N * 2.0 * DotProd(N, -dir) + dir;
108  }
109  void ReflectRay(Vector3 &result, const Vector3 &N) const {
110    result =  N * 2.0 * DotProd(N, -dir) + dir;
111  }
112
113  // Computes the inverted direction of the ray, used optionally by
114  // a ray traversal algorithm.
115  void ComputeInvertedDir() const;
116
117  // Given the matrix 4x4, transforms the ray to another space
118  void ApplyTransform(const Matrix4x4 &tform) {
119    loc = tform * loc;
120    dir = RotateOnly(tform, dir);
121    // note that normalization to the unit size of the direction
122    // is NOT computed -- this is what we want.
123    Precompute();
124  }
125
126  // returns ID of this ray (use for mailboxes)
127  int GetID() const { return ID; }
128
129  // returns the transfrom ID of the ray (use for ray transformations)
130  int GetTransformID() const { return transfID; }
131
132  // copy the transform ID from an input ray
133  void CopyTransformID(const Ray &ray) { transfID = ray.transfID; }
134 
135  // set unique ID for a given ray - always avoid setting to zero
136  void SetID() {
137    if ((ID = ++genID) == 0)
138      ID = ++genID;
139    transfID = ID;
140  }
141  // set ID to explicit value - it can be even 0 for rays transformed
142  // to the canonical object space to supress the mailbox failure.
143  void SetID(int newID) {
144    ID = newID;
145    // note that transfID is not changed!
146  }
147
148  // the cell in the ASDS, where ray starts from
149  void SetOrigin(const void *c) {origin = c;}
150  const void *GetOrigin() const  { return origin; }
151
152  // the cell in the ASDS, where ray finishes the walk
153  void SetTermination(const void *c) {termination = c; }
154  const void* GetTermination() const { return termination;}
155
156  // the object on which the ray starts at
157  const RayIntersection* GetStartObject() const { return &intersections[0]; }
158  const RayIntersection* GetStopObject() const { return &intersections[intersections.size()-1]; }
159 
160 
161  void SetLoc(const Vector3 &l);
162  Vector3& GetLoc() { return loc; }
163  Vector3  GetLoc() const { return loc; }
164
165  float  GetLoc(const int axis) const { return loc[axis]; }
166
167  void SetDir(const Vector3 &ndir) { dir = ndir;}
168  Vector3& GetDir() { return dir; }
169  Vector3  GetDir() const { return dir; }
170  float  GetDir(const int axis) const { return dir[axis]; }
171
172  int GetType() const { return mType; }
173 
174  // make such operation to slightly change the ray direction
175  // in case any component of ray direction is zero.
176  void CorrectZeroComponents();
177
178  // the depth of the ray - primary rays are in the depth 0
179  int GetDepth() const { return depth;}
180  void SetDepth(int newDepth) { depth = newDepth;}
181 
182private:
183  Vector3 loc, dir;             // Describes ray origin and vector
184 
185 
186  // The inverted direction of the ray components. It is computed optionally
187  // by the ray traversal algorithm using function ComputeInvertedDir();
188  mutable Vector3 invDir;
189
190  // Type of the ray: primary, shadow, dummy etc., see ERayType above
191  int mType;
192 
193  // I should have some abstract cell data type !!! here
194  // corresponds to the spatial elementary cell
195  const void *origin;
196  const void *termination;
197 
198  // unique ID of a ray for the use in the mailboxes
199  int ID;
200  // unique ID of a ray for the use with a transformations - this one
201  // never can be changed that allows the nesting of transformations
202  // and caching the transformed rays correctly
203  int transfID;
204 
205  // the ID generator fo each ray instantiated
206  static int genID; 
207
208  // When ray shot from the source(camera/light), this number is equal
209  // to the number of bounces of the ray, also called the depth of the
210  // ray (primary ray has its depth zero)
211  int      depth;
212 
213 
214  void Init();
215
216  // precompute some values that are necessary
217  void Precompute();
218
219  friend class AxisAlignedBox3;
220  friend class Plane;
221
222  // for CKDR GEMS
223  friend float DistanceToXPlane(const Vector3 &vec, const Ray &ray);
224  friend float DistanceToYPlane(const Vector3 &vec, const Ray &ray);
225  friend float DistanceToZPlane(const Vector3 &vec, const Ray &ray);
226  friend int MakeIntersectLine(const Plane3 &p, const Plane3 &q, Ray &ray);
227};
228
229
230
231
232#endif
233
Note: See TracBrowser for help on using the repository browser.