-
Notifications
You must be signed in to change notification settings - Fork 1
/
Plane.cpp
307 lines (233 loc) · 8.82 KB
/
Plane.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
// Plane.cpp: implementation of the CPlane class.
//
//////////////////////////////////////////////////////////////////////
# include "Plane.h"
# include "IntersectionInfo.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPlane::CPlane()
{
}
CPlane::~CPlane()
{
}
/*********************************************************************
NAME : CPlane
DESCRIPTION: Parameterized constructor
PARAMETER : pos : the position of the plane in space.
col : the color of the plane.
width : the width of hte plane
height : the height of the plane.
normal : the spatial orientation of the plane normal.
RETURN : NONE
EXCEPTION : NONE.
*********************************************************************/
CPlane::CPlane(CPoint3D pos, CColor col, float width, float length, CVector normal, CVector orientation) : CShape (pos, col)
{
/************************************************************************
NOTE:
I have decided to define the plane in the following manner so that it is
intuitive for the user to specify.
a. The centre of the plane.
b. The normal of the plane.
c. The height and the width of the plane.
d. The tricky one - The orientation of the plane.
Now, one might ask....isn't the normal the orientation? The answer is: if
the plane is infinite, then yes, the normal is all the orientation you need.
But if the plane is NOT infinite (which is the case here), we will have a
plane-segment (or a rectangle), whose dimensions are length x width.
This rectangle can be rotated ABOUT THE NORMAL to face different directions.
but we have to pin one direction down, thus we specify an 'orientation'.
The orientation, technically, is perfectly orthogonal to the normal, but
we cannot expect such a level of precision from the user. So, the user just
gives us a vector that roughly defines the direction and we compute the
'perfect' orientation.
We also need an 'ortho' vector which is orthogonal to both of these. This
vector helps simplify calculations later on when points on the plane have
to be tested if they lie inside the rectangle.
************************************************************************/
/***********************************************************************
STRATEGY:
1. Copy width, length and Normal as they are.Normalize the normal vector.
2. Get vector orthogonal to Normal along the orientation.
3. Get the orthogonal vector.
4. Compute 'F'.
***********************************************************************/
// 1.
m_fWidth = width;
m_fLength = length;
m_vecNormal = normal;
m_vecNormal.Normalize();
// 2.
m_vecOrientation = m_vecNormal.GetOrthoAlong (orientation);
m_vecOrientation.Normalize();
// 3.
m_vecOrtho = m_vecOrientation.CrossProduct(m_vecNormal);
m_vecOrtho.Normalize();
// 4.
m_fF = -1.0f * (m_vecNormal.XComponent() * m_ptPosition.GetX() +
m_vecNormal.YComponent() * m_ptPosition.GetY() +
m_vecNormal.ZComponent() * m_ptPosition.GetZ());
}
/*********************************************************************
NAME : CPlane
DESCRIPTION: Copy constructor
PARAMETER : plane1 : the object to copy
RETURN : NONE
EXCEPTION : NONE.
*********************************************************************/
CPlane::CPlane(CPlane &plane1)
{
this->m_fF = plane1.m_fF;
this->m_fLength = plane1.m_fLength;
this->m_fWidth = plane1.m_fWidth;
this->m_pShader = plane1.m_pShader;
this->m_ptPosition = plane1.m_ptPosition;
this->m_vecNormal = plane1.m_vecNormal;
this->m_vecOrientation = plane1.m_vecOrientation;
this->m_vecOrtho = plane1.m_vecOrtho;
this->objColor = plane1.objColor;
}
/*********************************************************************
NAME : SetDimensions
DESCRIPTION: Sets teh length and width of the plane.
PARAMETER : width, length
RETURN : void
EXCEPTION : NONE.
*********************************************************************/
void CPlane::SetDimensions (float width, float length)
{
this->m_fWidth = width;
this->m_fLength = length;
}
/*********************************************************************
NAME : SetNormal
DESCRIPTION: Set the normal
PARAMETER : normal : the value to use
RETURN : void
EXCEPTION : NONE.
*********************************************************************/
void CPlane::SetNormal (CVector normal)
{
this->m_vecNormal = normal;
m_vecNormal.Normalize();
}
/*********************************************************************
NAME : GetNormalAt
DESCRIPTION: returns the plane normal
PARAMETER : pt : ignored
RETURN : vector denoting the normal
EXCEPTION : NONE.
*********************************************************************/
CVector CPlane::GetNormalAt (CPoint3D pt)
{
return this->m_vecNormal;
}
/*********************************************************************
NAME : GetIntersection
DESCRIPTION: Calculates the intersection of the given ray with the plane.
If an intersection occurs the return value contains the
homogenous coordinates of the point of intersection. If not,
then the 'w' of the homogenous coordinates returned is zero
PARAMETER : ray : the ray to test for.
RETURN : 3D homogenous point
EXCEPTION : NONE.
*********************************************************************/
CIntersectionInfo CPlane::GetIntersection (CRay ray)
{
CPoint3D ptNoIntersection (0.0f, 0.0f, 0.0f, 0.0f); // no intersection by default
CPoint3D ptOfIntersection;
CIntersectionInfo hitInfo;
float fX, fY, fZ;
CVector vecPn, vecD;
float omega, fPndotD;
/****************************************************************************
STRATEGY:
The equation we use is:
omega = - ( Pn.P0 + F) / (Pn.D)
1. First find the point of intersection of ray with INFINITE PLANE containing
this plane so that it lies in front of the ray origin.
2. Now see if the point of intersection lies inside OUR PLANE.
3. Ready the hitInfo object so that we can return it.
****************************************************************************/
// 1.
/*********************************************************************
STRATEGY:
1.1. Compute Pn.D
1.2. If the ray is parallel to the plane, return.
1.3. Compute F
1.4. Compute Omega
1.5. If the pt is behind us, return.
1.6. Compute the coordinates of the point.
*********************************************************************/
// 1.1.
fPndotD = m_vecNormal.DotProduct(ray.Direction());
// 1.2.
if (!fPndotD)
{
return hitInfo;
}
// 1.3.
// 1.4.
omega = - (m_vecNormal.DotProduct(ray.Origin()) + m_fF) / fPndotD;
// 1.5.
if (omega < 0)
{
return hitInfo;
}
// 1.6.
fX = ray.Origin().GetX() + ray.Direction().XComponent() * omega;
fY = ray.Origin().GetY() + ray.Direction().YComponent() * omega;
fZ = ray.Origin().GetZ() + ray.Direction().ZComponent() * omega;
// 2.
float localX, localY;
CVector vecLocalPos = CVector(fX, fY, fZ) - CVector (m_ptPosition);
localX = m_vecOrtho.DotProduct(vecLocalPos);
localY = m_vecOrientation.DotProduct (vecLocalPos);
if (localY < (-1.0f * 0.5 * m_fLength) || localY > 0.5 * m_fLength ||
localX < (-1.0f * 0.5 * m_fWidth) || localX > 0.5 * m_fWidth)
{
return hitInfo;
}
ptOfIntersection.SetPoint(fX,fY,fZ);
// 3.
hitInfo.SetPointOfIntersection(ptOfIntersection);
hitInfo.SetNormal(m_vecNormal);
hitInfo.SetColor (objColor);
hitInfo.SetTexCoords(GetTexCoords (ptOfIntersection));
return hitInfo;
}
/*********************************************************************
NAME : ShadePoint
DESCRIPTION: This functin returns the color that should be displayed
for this object given the hit details.
PARAMETER : objHitInfo : detailed information about the hit.
RETURN : NONE
EXCEPTION : NONE.
*********************************************************************/
CColor CPlane::ShadePoint(CIntersectionInfo objHitInfo)
{
if (m_pShader == 0)
return this->objColor;
return m_pShader->ShadePoint(objHitInfo);
}
/*********************************************************************
NAME : GetTexCoords
DESCRIPTION: This method returns the texture coordinates for the given
point on the surface of the object.
PARAMETER : ptOfIntersection : The point at which tex coords have to
be computed.
RETURN : CTexCoords.
EXCEPTION : NONE.
*********************************************************************/
CTexCoords CPlane::GetTexCoords (CPoint3D ptOfIntersection)
{
CVector vecCorner, a;
float u,v;
vecCorner = CVector(m_ptPosition) - (m_vecOrtho * 0.5f * m_fWidth) - (m_vecOrientation * 0.5f * m_fLength);
a = CVector(ptOfIntersection) - vecCorner;
u = (m_vecOrtho.DotProduct (a)) / m_fWidth;
v = (m_vecOrientation.DotProduct(a)) / m_fLength;
return CTexCoords (u,v);
}