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

Revision 369, 7.6 KB checked in by bittner, 19 years ago (diff)

sampling contribution changes

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