source: trunk/VUT/GtpVisibilityPreprocessor/src/Vector3.cpp @ 162

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

functional raycasting version

Line 
1#include "Vector3.h"
2
3
4// Given min a vector to minimize and a candidate vector, replace
5// elements of min whose corresponding elements in Candidate are
6// smaller.  This function is used for finding objects' bounds,
7// among other things.
8void
9Minimize(Vector3 &min, const Vector3 &Candidate)
10{
11  if (Candidate.x < min.x)
12    min.x = Candidate.x;
13  if (Candidate.y < min.y)
14    min.y = Candidate.y;
15  if (Candidate.z < min.z)
16    min.z = Candidate.z;
17}
18
19// Given min a vector to minimize and a candidate vector, replace
20// elements of min whose corresponding elements in Candidate are
21// larger.  This function is used for finding objects' bounds,
22// among other things.
23void
24Maximize(Vector3 &max, const Vector3 &Candidate)
25{
26  if (Candidate.x > max.x)
27    max.x = Candidate.x;
28  if (Candidate.y > max.y)
29    max.y = Candidate.y;
30  if (Candidate.z > max.z)
31    max.z = Candidate.z;
32}
33
34// Project the vector onto the YZ, XZ, or XY plane depending on which.
35// which      Coordinate plane to project onto
36// 0          YZ
37// 1          XZ
38// 2          XY
39// This function is used by the polygon intersection code.
40
41void
42Vector3::ExtractVerts(float *px, float *py, int which) const
43{
44  switch (which) {
45    case 0:
46      *px = y;
47      *py = z;
48      break;
49    case 1:
50      *px = x;
51      *py = z;
52      break;
53    case 2:
54      *px = x;
55      *py = y;
56      break;
57  }
58}
59
60// returns the axis, where the vector has the largest value
61int
62Vector3::DrivingAxis(void) const
63{
64  int axis = 0;
65  float val = fabs(x);
66
67  if (fabs(y) > val) {
68    val = fabs(y);
69    axis = 1;
70  }
71
72  if (fabs(z) > val)
73    axis = 2;
74
75  return axis;
76}
77
78// returns the axis, where the vector has the smallest value
79int
80Vector3::TinyAxis(void) const
81{
82  int axis = 0;
83  float val = fabs(x);
84
85  if (fabs(y) < val) {
86    val = fabs(y);
87    axis = 1;
88  }
89
90  if (fabs(z) < val)
91    axis = 2;
92
93  return axis;
94}
95
96
97// Construct a view vector ViewN, and the vector ViewU perpendicular
98// to ViewN and lying in the plane given by ViewNxUpl
99// the last vector of ortogonal system is ViewV, that is
100// perpendicular to both ViewN and ViewU.
101// |ViewN| = |ViewU| = |ViewV| = 1
102// The ViewN vector pierces the center of the synthesized image
103//     ViewU vector goes from the center image rightwards
104//     ViewV vector goes from the center image upwards
105void
106ViewVectors(const Vector3 &DirAt, const Vector3 &Viewer,
107            const Vector3 &UpL, Vector3 &ViewV, Vector3 &ViewU,
108            Vector3 &ViewN)
109{
110  Vector3 U, V, N;
111  Vector3 Up = Normalize(UpL);
112
113  N = -Normalize(DirAt);
114
115  V = Normalize(Up - DirAt);
116  V -= N * DotProd(V, N);
117  V = Normalize(V);
118  U = CrossProd(V, N);
119
120  ViewU = U; // rightwards
121  ViewV = V; // upwards
122  ViewN = -N; // forwards
123#ifdef _DEBUG
124  const float eps = 1e-3;
125  if (fabs(Magnitude(ViewU) - 1.0) > eps) {
126    Debug << "ViewU magnitude error= " << Magnitude(ViewU) << "\n";
127  }
128  if (fabs(Magnitude(ViewV) - 1.0) > eps) {
129    Debug << "ViewU magnitude error= " << Magnitude(ViewV) << "\n";
130  }
131  if (fabs(Magnitude(ViewN) - 1.0) > eps) {
132    Debug << "ViewU magnitude error= " << Magnitude(ViewN) << "\n";
133  }
134#endif // _DEBUG
135
136  return;
137}
138
139// Given the intersection point `P', you have available normal `N'
140// of unit length. Let us suppose the incoming ray has direction `D'.
141// Then we can construct such two vectors `U' and `V' that
142// `U',`N', and `D' are coplanar, and `V' is perpendicular
143// to the vectors `N','D', and `V'. Then 'N', 'U', and 'V' create
144// the orthonormal base in space R3.
145void
146TangentVectors(Vector3 &U,
147               Vector3 &V, // output
148               const Vector3 &normal, // input
149               const Vector3 &dirIncoming)
150{
151#ifdef _DEBUG
152  float d = Magnitude(normal);
153  if ( (d < 0.99) ||
154       (d > 1.01) ) {
155    Debug << " The normal has not unit length = " << d << endl;
156  }
157  d = Magnitude(dirIncoming);
158  if ( (d < 0.99) ||
159       (d > 1.01) ) {
160    Debug << " The incoming dir has not unit length = " << d << endl;
161  }
162#endif
163 
164  V = CrossProd(normal, dirIncoming);
165
166  if (SqrMagnitude(V) < 1e-3) {
167    // the normal and dirIncoming are colinear
168    // we can/have to generate arbitrary perpendicular vector to normal.
169    if (fabs(normal.x) < 0.6)
170      V.SetValue(0.0, -normal.z, normal.y);
171    else {
172      if (fabs(normal.y) < 0.6)
173        V.SetValue(-normal.z, 0.0, normal.x);
174      else
175        V.SetValue(-normal.y, normal.x, 0.0);
176    }
177  }
178  V = Normalize(V);
179
180  U = CrossProd(normal, V);
181#ifdef _DEBUG
182  d = SqrMagnitude(U);
183  if ( (d < 0.99) ||
184       (d > 1.01) ) {
185    Debug << "The size of U vector incorrect\n";
186  }
187#endif
188  return; 
189}
Note: See TracBrowser for help on using the repository browser.