From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_projector_8cpp_source.html | 587 +++++++++++++++++++++++++++ 1 file changed, 587 insertions(+) create mode 100644 Doc/doxygen/html/_projector_8cpp_source.html (limited to 'Doc/doxygen/html/_projector_8cpp_source.html') diff --git a/Doc/doxygen/html/_projector_8cpp_source.html b/Doc/doxygen/html/_projector_8cpp_source.html new file mode 100644 index 0000000..2af13e3 --- /dev/null +++ b/Doc/doxygen/html/_projector_8cpp_source.html @@ -0,0 +1,587 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/nGenEx/Projector.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Projector.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: nGenEx.lib
+
6  FILE: Projector.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  3D Projection Camera class
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "Projector.h"
+
17 
+
18 // +--------------------------------------------------------------------+
+
19 
+
20 static const float CLIP_PLANE_EPSILON = 0.0001f;
+
21 static const double Z_NEAR = 1.0;
+
22 
+
23 void Print(const char* fmt, ...);
+
24 
+
25 // +--------------------------------------------------------------------+
+
26 
+
27 static Camera emergency_cam;
+
28 
+
29 // +--------------------------------------------------------------------+
+
30 
+ +
32 : camera(cam), infinite(0), depth_scale(1.0f), orthogonal(false), field_of_view(2)
+
33 {
+
34  if (!camera)
+
35  camera = &emergency_cam;
+
36 
+
37  UseWindow(window);
+
38 }
+
39 
+ +
41 { }
+
42 
+
43 // +--------------------------------------------------------------------+
+
44 
+
45 void
+ +
47 {
+
48  if (cam)
+
49  camera = cam;
+
50  else
+
51  camera = &emergency_cam;
+
52 }
+
53 
+
54 void
+ +
56 {
+
57  Rect r = win->GetRect();
+
58  width = r.w;
+
59  height = r.h;
+
60 
+
61  xcenter = (width / 2.0);
+
62  ycenter = (height / 2.0);
+
63 
+
64  xclip0 = 0.0f;
+
65  xclip1 = (float) width-0.5f;
+
66  yclip0 = 0.0f;
+
67  yclip1 = (float) height-0.5f;
+
68 
+ +
70 }
+
71 
+
72 void
+ +
74 {
+
75  field_of_view = fov;
+
76 
+
77  xscreenscale = width / fov;
+
78  yscreenscale = height / fov;
+
79 
+ +
81 
+
82  xangle = atan(2.0/fov * maxscale/xscreenscale);
+
83  yangle = atan(2.0/fov * maxscale/yscreenscale);
+
84 }
+
85 
+
86 double
+ +
88 {
+
89  return field_of_view;
+
90 }
+
91 
+
92 void
+ +
94 {
+
95  depth_scale = scale;
+
96 }
+
97 
+
98 double
+ +
100 {
+
101  return depth_scale;
+
102 }
+
103 
+
104 int
+ +
106 {
+
107  int old = infinite;
+
108  infinite = i;
+
109  return old;
+
110 }
+
111 
+
112 // +--------------------------------------------------------------------+
+
113 
+
114 void
+ +
116 {
+
117  SetUpFrustum();
+
118  SetWorldSpace();
+
119 }
+
120 
+
121 // +--------------------------------------------------------------------+
+
122 // Transform a point from worldspace to viewspace.
+
123 // +--------------------------------------------------------------------+
+
124 
+
125 void
+ +
127 {
+
128  Vec3 tvert = vec;
+
129 
+
130  // Translate into a viewpoint-relative coordinate
+
131  if (!infinite)
+
132  tvert -= camera->Pos();
+
133 
+
134  // old method:
+
135  vec.x = (tvert * camera->vrt());
+
136  vec.y = (tvert * camera->vup());
+
137  vec.z = (tvert * camera->vpn());
+
138 
+
139  // Rotate into the view orientation
+
140  // vec = tvert * camera->Orientation();
+
141 }
+
142 
+
143 // +--------------------------------------------------------------------+
+
144 // Transform a point from worldspace to viewspace.
+
145 // +--------------------------------------------------------------------+
+
146 
+
147 void
+ +
149 {
+
150  Point tvert = point;
+
151 
+
152  // Translate into a viewpoint-relative coordinate
+
153  if (!infinite)
+
154  tvert -= camera->Pos();
+
155 
+
156  // old method:
+
157  point.x = (tvert * camera->vrt());
+
158  point.y = (tvert * camera->vup());
+
159  point.z = (tvert * camera->vpn());
+
160 
+
161  // Rotate into the view orientation
+
162  // point = tvert * camera->Orientation();
+
163 }
+
164 
+
165 // +--------------------------------------------------------------------+
+
166 // APPARENT RADIUS OF PROJECTED OBJECT
+
167 // Project a viewspace point into screen coordinates.
+
168 // Use projected Z to determine apparent radius of object.
+
169 // +--------------------------------------------------------------------+
+
170 
+
171 float
+
172 Projector::ProjectRadius(const Vec3& v, float radius) const
+
173 {
+
174  return (float) fabs((radius * maxscale) / v.z);
+
175 }
+
176 
+
177 // +--------------------------------------------------------------------+
+
178 // IN PLACE PROJECTION OF POINT
+
179 // Project a viewspace point into screen coordinates.
+
180 // Note that the y axis goes up in worldspace and viewspace, but
+
181 // goes down in screenspace.
+
182 // +--------------------------------------------------------------------+
+
183 
+
184 void
+ +
186 {
+
187  double zrecip;
+
188 
+
189  if (orthogonal) {
+
190  double scale = field_of_view/2;
+
191  v.x = (float) (xcenter + scale * v.x);
+
192  v.y = (float) (height - (ycenter + scale * v.y));
+
193  v.z = (float) (0.0f);
+
194  }
+
195 
+
196  else {
+
197  //zrecip = 2 * (1.0e5 / (1.0e5-1)) / v.z;
+
198  //zrecip = 2 * 0.97 / v.z; -- what the heck was this version used for?
+
199 
+
200  zrecip = 2 / v.z;
+
201  v.x = (float) (xcenter + maxscale * v.x * zrecip);
+
202  v.y = (float) (height - (ycenter + maxscale * v.y * zrecip));
+
203  v.z = (float) (1 - zrecip);
+
204  }
+
205 
+
206  // clamp the point to the viewport:
+
207  if (clamp) {
+
208  if (v.x < xclip0) v.x = xclip0;
+
209  if (v.x > xclip1) v.x = xclip1;
+
210  if (v.y < yclip0) v.y = yclip0;
+
211  if (v.y > yclip1) v.y = yclip1;
+
212  }
+
213 }
+
214 
+
215 // +--------------------------------------------------------------------+
+
216 // IN PLACE PROJECTION OF POINT
+
217 // Project a viewspace point into screen coordinates.
+
218 // Note that the y axis goes up in worldspace and viewspace, but
+
219 // goes down in screenspace.
+
220 // +--------------------------------------------------------------------+
+
221 
+
222 void
+ +
224 {
+
225  double zrecip;
+
226 
+
227  if (orthogonal) {
+
228  double scale = field_of_view/2;
+
229  v.x = (xcenter + scale * v.x);
+
230  v.y = (height - (ycenter + scale * v.y));
+
231  v.z = 0;
+
232  }
+
233 
+
234  else {
+
235  zrecip = 1 / v.z;
+
236  v.x = (xcenter + 2 * maxscale * v.x * zrecip);
+
237  v.y = (height - (ycenter + 2 * maxscale * v.y * zrecip));
+
238  v.z = (1 - zrecip);
+
239  }
+
240 
+
241  // clamp the point to the viewport:
+
242  if (clamp) {
+
243  if (v.x < xclip0) v.x = xclip0;
+
244  if (v.x > xclip1) v.x = xclip1;
+
245  if (v.y < yclip0) v.y = yclip0;
+
246  if (v.y > yclip1) v.y = yclip1;
+
247  }
+
248 }
+
249 
+
250 // +--------------------------------------------------------------------+
+
251 // IN PLACE UN-PROJECTION OF POINT
+
252 // Convert a point in screen coordinates back to viewspace.
+
253 // Note that the y axis goes up in worldspace and viewspace, but
+
254 // goes down in screenspace.
+
255 // +--------------------------------------------------------------------+
+
256 
+
257 void
+ +
259 {
+
260  double zrecip = 1 / v.z;
+
261 
+
262  /***
+
263  * forward projection:
+
264 v.x = (xcenter + maxscale * v.x * zrecip);
+
265 v.y = (height - (ycenter + maxscale * v.y * zrecip));
+
266 v.z = (1 - zrecip);
+
267 ***/
+
268 
+
269  v.x = ( v.x - xcenter) / (maxscale * zrecip);
+
270  v.y = (height - v.y - ycenter) / (maxscale * zrecip);
+
271 }
+
272 
+
273 // +--------------------------------------------------------------------+
+
274 // IN PLACE PROJECTION OF RECTANGLE (FOR SPRITES)
+
275 // Project a viewspace point into screen coordinates.
+
276 // Note that the y axis goes up in worldspace and viewspace, but
+
277 // goes down in screenspace.
+
278 // +--------------------------------------------------------------------+
+
279 
+
280 void
+
281 Projector::ProjectRect(Point& v, double& w, double& h) const
+
282 {
+
283  double zrecip;
+
284 
+
285  if (orthogonal) {
+
286  double scale = field_of_view/2;
+
287  v.x = (xcenter + scale * v.x);
+
288  v.y = (height - (ycenter + scale * v.y));
+
289  v.z = 0;
+
290  }
+
291 
+
292  else {
+
293  zrecip = 1 / v.z;
+
294  v.x = (xcenter + 2 * maxscale * v.x * zrecip);
+
295  v.y = (height - (ycenter + 2 * maxscale * v.y * zrecip));
+
296  v.z = (1 - Z_NEAR*zrecip);
+
297 
+
298  w *= maxscale * zrecip;
+
299  h *= maxscale * zrecip;
+
300  }
+
301 }
+
302 
+
303 // +--------------------------------------------------------------------+
+
304 // Set up a clip plane with the specified normal.
+
305 // +--------------------------------------------------------------------+
+
306 
+
307 void
+ +
309 {
+
310  // Rotate the plane normal into worldspace
+
311  ViewToWorld(normal, plane.normal);
+
312  plane.distance = (float) (camera->Pos() * plane.normal + CLIP_PLANE_EPSILON);
+
313 }
+
314 
+
315 // +--------------------------------------------------------------------+
+
316 // Set up the planes of the frustum, in worldspace coordinates.
+
317 // +--------------------------------------------------------------------+
+
318 
+
319 void
+ +
321 {
+
322  double angle, s, c;
+
323  Vec3 normal;
+
324 
+
325  angle = XAngle();
+
326  s = sin(angle);
+
327  c = cos(angle);
+
328 
+
329  // Left clip plane
+
330  normal.x = (float) s;
+
331  normal.y = (float) 0;
+
332  normal.z = (float) c;
+
333  view_planes[0].normal = normal;
+
334  view_planes[0].distance = CLIP_PLANE_EPSILON;
+ +
336 
+
337  // Right clip plane
+
338  normal.x = (float) -s;
+
339  view_planes[1].normal = normal;
+
340  view_planes[1].distance = CLIP_PLANE_EPSILON;
+ +
342 
+
343  angle = YAngle();
+
344  s = sin(angle);
+
345  c = cos(angle);
+
346 
+
347  // Bottom clip plane
+
348  normal.x = (float) 0;
+
349  normal.y = (float) s;
+
350  normal.z = (float) c;
+
351  view_planes[2].normal = normal;
+
352  view_planes[2].distance = CLIP_PLANE_EPSILON;
+ +
354 
+
355  // Top clip plane
+
356  normal.y = (float) -s;
+
357  view_planes[3].normal = normal;
+
358  view_planes[3].distance = CLIP_PLANE_EPSILON;
+ +
360 }
+
361 
+
362 // +--------------------------------------------------------------------+
+
363 // Clip the point against the frustum and return 1 if partially inside
+
364 // Return 2 if completely inside
+
365 // +--------------------------------------------------------------------+
+
366 
+
367 int
+
368 Projector::IsVisible(const Vec3& v, float radius) const
+
369 {
+
370  int visible = 1;
+
371  int complete = 1;
+
372 
+
373  Plane* plane = (Plane*) frustum_planes;
+
374  if (infinite) {
+
375  complete = 0;
+
376 
+
377  for (int i = 0; visible && (i < NUM_FRUSTUM_PLANES); i++) {
+
378  visible = ((v * plane->normal) >= CLIP_PLANE_EPSILON);
+
379  plane++;
+
380  }
+
381  }
+
382  else {
+
383  for (int i = 0; visible && (i < NUM_FRUSTUM_PLANES); i++) {
+
384  float dot = v * plane->normal;
+
385  visible = ((dot + radius) >= plane->distance);
+
386  complete = complete && ((dot - radius) >= plane->distance);
+
387  plane++;
+
388  }
+
389  }
+
390 
+
391  return visible + complete;
+
392 }
+
393 
+
394 // +--------------------------------------------------------------------+
+
395 // Clip the bouding point against the frustum and return non zero
+
396 // if at least partially inside. This version is not terribly
+
397 // efficient as it checks all eight box corners rather than just
+
398 // the minimum two.
+
399 // +--------------------------------------------------------------------+
+
400 
+
401 int
+ +
403 {
+
404  int i, j, outside = 0;
+
405 
+
406  // if all eight corners are outside of the same
+
407  // frustrum plane, then the box is not visible
+
408  Plane* plane = (Plane*) frustum_planes;
+
409 
+
410  if (infinite) {
+
411  for (i = 0; !outside && (i < NUM_FRUSTUM_PLANES); i++) {
+
412  for (j = 0; j < 8; j++)
+
413  outside += (p[j] * plane->normal) < CLIP_PLANE_EPSILON;
+
414 
+
415  if (outside < 8)
+
416  outside = 0;
+
417 
+
418  plane++;
+
419  }
+
420  }
+
421  else {
+
422  for (i = 0; !outside && (i < NUM_FRUSTUM_PLANES); i++) {
+
423  for (j = 0; j < 8; j++)
+
424  outside += (p[j] * plane->normal) < plane->distance;
+
425 
+
426  if (outside < 8)
+
427  outside = 0;
+
428 
+
429  plane++;
+
430  }
+
431  }
+
432 
+
433  // if not outside, then the box is visible
+
434  return !outside;
+
435 }
+
436 
+
437 // +--------------------------------------------------------------------+
+
438 
+
439 float
+
440 Projector::ApparentRadius(const Vec3& v, float radius) const
+
441 {
+
442  Vec3 vloc = v;
+
443 
+
444  Transform(vloc); // transform in place
+
445  return ProjectRadius(vloc, radius);
+
446 }
+
447 
+
448 
+
449 // +--------------------------------------------------------------------+
+
450 // Rotate a vector from viewspace to worldspace.
+
451 // +--------------------------------------------------------------------+
+
452 
+
453 void
+ +
455 {
+
456  // Rotate into the world orientation
+
457  pout.x = pin.x * camera->vrt().x + pin.y * camera->vup().x + pin.z * camera->vpn().x;
+
458  pout.y = pin.x * camera->vrt().y + pin.y * camera->vup().y + pin.z * camera->vpn().y;
+
459  pout.z = pin.x * camera->vrt().z + pin.y * camera->vup().z + pin.z * camera->vpn().z;
+
460 }
+
461 
+
462 void
+ +
464 {
+
465  // Rotate into the world orientation
+
466  vout.x = (float) (vin.x * camera->vrt().x + vin.y * camera->vup().x + vin.z * camera->vpn().x);
+
467  vout.y = (float) (vin.x * camera->vrt().y + vin.y * camera->vup().y + vin.z * camera->vpn().y);
+
468  vout.z = (float) (vin.x * camera->vrt().z + vin.y * camera->vup().z + vin.z * camera->vpn().z);
+
469 }
+
470 
+
+
+ + + + -- cgit v1.1