1 /****************************************************************************
2 * planes.cpp
3 *
4 * This module implements functions that manipulate planes.
5 *
6 * from Persistence of Vision(tm) Ray Tracer version 3.6.
7 * Copyright 1991-2003 Persistence of Vision Team
8 * Copyright 2003-2004 Persistence of Vision Raytracer Pty. Ltd.
9 *---------------------------------------------------------------------------
10 * NOTICE: This source code file is provided so that users may experiment
11 * with enhancements to POV-Ray and to port the software to platforms other
12 * than those supported by the POV-Ray developers. There are strict rules
13 * regarding how you are permitted to use this file. These rules are contained
14 * in the distribution and derivative versions licenses which should have been
15 * provided with this file.
16 *
17 * These licences may be found online, linked from the end-user license
18 * agreement that is located at http://www.povray.org/povlegal.html
19 *---------------------------------------------------------------------------
20 * This program is based on the popular DKB raytracer version 2.12.
21 * DKBTrace was originally written by David K. Buck.
22 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
23 *---------------------------------------------------------------------------
24 * $File: //depot/povray/3.6-release/source/planes.cpp $
25 * $Revision: #3 $
26 * $Change: 3032 $
27 * $DateTime: 2004/08/02 18:43:41 $
28 * $Author: chrisc $
29 * $Log$
30 *****************************************************************************/
31
32 #include "frame.h"
33 #include "povray.h"
34 #include "vector.h"
35 #include "matrices.h"
36 #include "objects.h"
37 #include "planes.h"
38
39 BEGIN_POV_NAMESPACE
40
41 /*****************************************************************************
42 * Local preprocessor defines
43 ******************************************************************************/
44
45 const DBL DEPTH_TOLERANCE = 1.0e-6;
46
47 /*****************************************************************************
48 * Static functions
49 ******************************************************************************/
50
51 static int Intersect_Plane (RAY *Ray, PLANE *Plane, DBL *Depth);
52 static int All_Plane_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
53 static int Inside_Plane (VECTOR point, OBJECT *Object);
54 static void Plane_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
55 static PLANE *Copy_Plane (OBJECT *Object);
56 static void Translate_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
57 static void Rotate_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
58 static void Scale_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
59 static void Transform_Plane (OBJECT *Object, TRANSFORM *Trans);
60 static void Invert_Plane (OBJECT *Object);
61 static void Destroy_Plane (OBJECT *Object);
62
63 /*****************************************************************************
64 * Local variables
65 ******************************************************************************/
66
67 METHODS Plane_Methods =
68 {
69 All_Plane_Intersections,
70 Inside_Plane, Plane_Normal, Default_UVCoord,
71 (COPY_METHOD)Copy_Plane,
72 Translate_Plane, Rotate_Plane,
73 Scale_Plane, Transform_Plane, Invert_Plane, Destroy_Plane
74 };
75
76
77 /*****************************************************************************
78 *
79 * FUNCTION
80 *
81 * All_Plane_Intersections
82 *
83 * INPUT
84 *
85 * OUTPUT
86 *
87 * RETURNS
88 *
89 * AUTHOR
90 *
91 * POV-Ray Team
92 *
93 * DESCRIPTION
94 *
95 * -
96 *
97 * CHANGES
98 *
99 * -
100 *
101 ******************************************************************************/
102
All_Plane_Intersections(OBJECT * Object,RAY * Ray,ISTACK * Depth_Stack)103 static int All_Plane_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
104 {
105 DBL Depth;
106 VECTOR IPoint;
107
108 if (Intersect_Plane(Ray, (PLANE *)Object, &Depth))
109 {
110 VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
111
112 if (Point_In_Clip(IPoint, Object->Clip))
113 {
114 push_entry(Depth,IPoint,Object,Depth_Stack);
115
116 return(true);
117 }
118 }
119
120 return(false);
121 }
122
123
124
125 /*****************************************************************************
126 *
127 * FUNCTION
128 *
129 * Intersect_Plane
130 *
131 * INPUT
132 *
133 * OUTPUT
134 *
135 * RETURNS
136 *
137 * AUTHOR
138 *
139 * POV-Ray Team
140 *
141 * DESCRIPTION
142 *
143 * -
144 *
145 * CHANGES
146 *
147 * -
148 *
149 ******************************************************************************/
150
Intersect_Plane(RAY * Ray,PLANE * Plane,DBL * Depth)151 static int Intersect_Plane (RAY *Ray, PLANE *Plane, DBL *Depth)
152 {
153 DBL NormalDotOrigin, NormalDotDirection;
154 VECTOR P, D;
155
156 Increase_Counter(stats[Ray_Plane_Tests]);
157
158 if (Plane->Trans == NULL)
159 {
160 VDot(NormalDotDirection, Plane->Normal_Vector, Ray->Direction);
161
162 if (fabs(NormalDotDirection) < EPSILON)
163 {
164 return(false);
165 }
166
167 VDot(NormalDotOrigin, Plane->Normal_Vector, Ray->Initial);
168 }
169 else
170 {
171 MInvTransPoint(P, Ray->Initial, Plane->Trans);
172 MInvTransDirection(D, Ray->Direction, Plane->Trans);
173
174 VDot(NormalDotDirection, Plane->Normal_Vector, D);
175
176 if (fabs(NormalDotDirection) < EPSILON)
177 {
178 return(false);
179 }
180
181 VDot(NormalDotOrigin, Plane->Normal_Vector, P);
182 }
183
184 *Depth = -(NormalDotOrigin + Plane->Distance) / NormalDotDirection;
185
186 if ((*Depth >= DEPTH_TOLERANCE) && (*Depth <= Max_Distance))
187 {
188 Increase_Counter(stats[Ray_Plane_Tests_Succeeded]);
189
190 return (true);
191 }
192 else
193 {
194 return (false);
195 }
196 }
197
198
199
200 /*****************************************************************************
201 *
202 * FUNCTION
203 *
204 * Inside_Plane
205 *
206 * INPUT
207 *
208 * OUTPUT
209 *
210 * RETURNS
211 *
212 * AUTHOR
213 *
214 * POV-Ray Team
215 *
216 * DESCRIPTION
217 *
218 * -
219 *
220 * CHANGES
221 *
222 * -
223 *
224 ******************************************************************************/
225
Inside_Plane(VECTOR IPoint,OBJECT * Object)226 static int Inside_Plane (VECTOR IPoint, OBJECT *Object)
227 {
228 DBL Temp;
229 VECTOR P;
230
231 if (((PLANE *)Object)->Trans == NULL)
232 {
233 VDot (Temp, IPoint, ((PLANE *)Object)->Normal_Vector);
234 }
235 else
236 {
237 MInvTransPoint(P, IPoint, ((PLANE *)Object)->Trans);
238
239 VDot (Temp, P, ((PLANE *)Object)->Normal_Vector);
240 }
241
242 return((Temp + ((PLANE *)Object)->Distance) < EPSILON);
243 }
244
245
246
247 /*****************************************************************************
248 *
249 * FUNCTION
250 *
251 * Plane_Normal
252 *
253 * INPUT
254 *
255 * OUTPUT
256 *
257 * RETURNS
258 *
259 * AUTHOR
260 *
261 * POV-Ray Team
262 *
263 * DESCRIPTION
264 *
265 * -
266 *
267 * CHANGES
268 *
269 * -
270 *
271 ******************************************************************************/
272
Plane_Normal(VECTOR Result,OBJECT * Object,INTERSECTION *)273 static void Plane_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *)
274 {
275 Assign_Vector(Result,((PLANE *)Object)->Normal_Vector);
276
277 if (((PLANE *)Object)->Trans != NULL)
278 {
279 MTransNormal(Result, Result, ((PLANE *)Object)->Trans);
280
281 VNormalize(Result, Result);
282 }
283 }
284
285
286
287 /*****************************************************************************
288 *
289 * FUNCTION
290 *
291 * Translate_Plane
292 *
293 * INPUT
294 *
295 * OUTPUT
296 *
297 * RETURNS
298 *
299 * AUTHOR
300 *
301 * POV-Ray Team
302 *
303 * DESCRIPTION
304 *
305 * -
306 *
307 * CHANGES
308 *
309 * -
310 *
311 ******************************************************************************/
312
Translate_Plane(OBJECT * Object,VECTOR Vector,TRANSFORM * Trans)313 static void Translate_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
314 {
315 VECTOR Translation;
316 PLANE *Plane = (PLANE *)Object;
317
318 if (Plane->Trans == NULL)
319 {
320 VEvaluate (Translation, ((PLANE *)Object)->Normal_Vector, Vector);
321
322 ((PLANE *)Object)->Distance -= Translation[X] + Translation[Y] + Translation[Z];
323
324 Compute_Plane_BBox((PLANE *)Object);
325 }
326 else
327 {
328 Transform_Plane(Object, Trans);
329 }
330 }
331
332
333
334 /*****************************************************************************
335 *
336 * FUNCTION
337 *
338 * Rotate_Plane
339 *
340 * INPUT
341 *
342 * OUTPUT
343 *
344 * RETURNS
345 *
346 * AUTHOR
347 *
348 * POV-Ray Team
349 *
350 * DESCRIPTION
351 *
352 * -
353 *
354 * CHANGES
355 *
356 * -
357 *
358 ******************************************************************************/
359
Rotate_Plane(OBJECT * Object,VECTOR,TRANSFORM * Trans)360 static void Rotate_Plane (OBJECT *Object, VECTOR, TRANSFORM *Trans)
361 {
362 if (((PLANE *)Object)->Trans == NULL)
363 {
364 MTransDirection(((PLANE *)Object)->Normal_Vector, ((PLANE *)Object)->Normal_Vector, Trans);
365
366 Compute_Plane_BBox(((PLANE *)Object));
367 }
368 else
369 {
370 Transform_Plane (Object, Trans);
371 }
372 }
373
374
375
376 /*****************************************************************************
377 *
378 * FUNCTION
379 *
380 * Scale_Plane
381 *
382 * INPUT
383 *
384 * OUTPUT
385 *
386 * RETURNS
387 *
388 * AUTHOR
389 *
390 * POV-Ray Team
391 *
392 * DESCRIPTION
393 *
394 * -
395 *
396 * CHANGES
397 *
398 * -
399 *
400 ******************************************************************************/
401
Scale_Plane(OBJECT * Object,VECTOR Vector,TRANSFORM * Trans)402 static void Scale_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
403 {
404 DBL Length;
405 PLANE *Plane = (PLANE *) Object;
406
407 if (Plane->Trans == NULL)
408 {
409 VDivEq(Plane->Normal_Vector, Vector);
410
411 VLength(Length, ((PLANE *)Object)->Normal_Vector);
412
413 VInverseScaleEq (((PLANE *)Object)->Normal_Vector, Length);
414
415 ((PLANE *)Object)->Distance /= Length;
416
417 Compute_Plane_BBox(Plane);
418 }
419 else
420 {
421 Transform_Plane (Object, Trans);
422 }
423 }
424
425
426
427 /*****************************************************************************
428 *
429 * FUNCTION
430 *
431 * Invert_Plane
432 *
433 * INPUT
434 *
435 * OUTPUT
436 *
437 * RETURNS
438 *
439 * AUTHOR
440 *
441 * POV-Ray Team
442 *
443 * DESCRIPTION
444 *
445 * -
446 *
447 * CHANGES
448 *
449 * -
450 *
451 ******************************************************************************/
452
Invert_Plane(OBJECT * Object)453 static void Invert_Plane (OBJECT *Object)
454 {
455 VScaleEq(((PLANE *)Object)->Normal_Vector, -1.0);
456
457 ((PLANE *)Object)->Distance *= -1.0;
458 }
459
460
461
462 /*****************************************************************************
463 *
464 * FUNCTION
465 *
466 * Transform_Plane
467 *
468 * INPUT
469 *
470 * OUTPUT
471 *
472 * RETURNS
473 *
474 * AUTHOR
475 *
476 * POV-Ray Team
477 *
478 * DESCRIPTION
479 *
480 * -
481 *
482 * CHANGES
483 *
484 * -
485 *
486 ******************************************************************************/
487
Transform_Plane(OBJECT * Object,TRANSFORM * Trans)488 static void Transform_Plane(OBJECT *Object, TRANSFORM *Trans)
489 {
490 PLANE *Plane = (PLANE *) Object;
491
492 if (Plane->Trans == NULL)
493 {
494 Plane->Trans = Create_Transform();
495 }
496
497 Compose_Transforms(Plane->Trans, Trans);
498
499 Compute_Plane_BBox(Plane);
500 }
501
502
503
504 /*****************************************************************************
505 *
506 * FUNCTION
507 *
508 * Create_Plane
509 *
510 * INPUT
511 *
512 * OUTPUT
513 *
514 * RETURNS
515 *
516 * AUTHOR
517 *
518 * POV-Ray Team
519 *
520 * DESCRIPTION
521 *
522 * -
523 *
524 * CHANGES
525 *
526 * -
527 *
528 ******************************************************************************/
529
Create_Plane()530 PLANE *Create_Plane()
531 {
532 PLANE *New;
533
534 New = (PLANE *)POV_MALLOC(sizeof (PLANE), "plane");
535
536 INIT_OBJECT_FIELDS(New,PLANE_OBJECT,&Plane_Methods)
537
538 Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
539
540 New ->Distance = 0.0;
541
542 New->Trans = NULL;
543
544 return(New);
545 }
546
547
548
549 /*****************************************************************************
550 *
551 * FUNCTION
552 *
553 * Copy_Plane
554 *
555 * INPUT
556 *
557 * OUTPUT
558 *
559 * RETURNS
560 *
561 * AUTHOR
562 *
563 * POV-Ray Team
564 *
565 * DESCRIPTION
566 *
567 * -
568 *
569 * CHANGES
570 *
571 * -
572 *
573 ******************************************************************************/
574
Copy_Plane(OBJECT * Object)575 static PLANE *Copy_Plane (OBJECT *Object)
576 {
577 PLANE *New;
578
579 New = Create_Plane();
580
581 Destroy_Transform(New->Trans);
582
583 *New = *((PLANE *)Object);
584
585 New->Trans = Copy_Transform(((PLANE *)Object)->Trans);
586
587 return(New);
588 }
589
590
591
592 /*****************************************************************************
593 *
594 * FUNCTION
595 *
596 * Destroy_Plane
597 *
598 * INPUT
599 *
600 * OUTPUT
601 *
602 * RETURNS
603 *
604 * AUTHOR
605 *
606 * POV-Ray Team
607 *
608 * DESCRIPTION
609 *
610 * -
611 *
612 * CHANGES
613 *
614 * -
615 *
616 ******************************************************************************/
617
Destroy_Plane(OBJECT * Object)618 static void Destroy_Plane(OBJECT *Object)
619 {
620 #if(DUMP_OBJECT_DATA == 1)
621 Debug_Info("{ // PLANE \n");
622 DUMP_OBJECT_FIELDS(Object);
623 Debug_Info("\t{ %f, %f, %f }, // Normal_Vector\n", \
624 (DBL)((PLANE *)Object)->Normal_Vector[X], \
625 (DBL)((PLANE *)Object)->Normal_Vector[Y], \
626 (DBL)((PLANE *)Object)->Normal_Vector[Z]); \
627 Debug_Info("\t%f // Distance\n", (DBL)((PLANE *)Object)->Distance);
628 Debug_Info("}\n");
629 #endif
630
631 Destroy_Transform(((PLANE *)Object)->Trans);
632
633 POV_FREE(Object);
634 }
635
636
637
638 /*****************************************************************************
639 *
640 * FUNCTION
641 *
642 * Compute_Plane_BBox
643 *
644 * INPUT
645 *
646 * Plane - Plane
647 *
648 * OUTPUT
649 *
650 * Plane
651 *
652 * RETURNS
653 *
654 * AUTHOR
655 *
656 * Dieter Bayer
657 *
658 * DESCRIPTION
659 *
660 * Calculate the bounding box of a plane (it's always infinite).
661 *
662 * CHANGES
663 *
664 * Aug 1994 : Creation.
665 *
666 ******************************************************************************/
667
Compute_Plane_BBox(PLANE * Plane)668 void Compute_Plane_BBox(PLANE *Plane)
669 {
670 Make_BBox(Plane->BBox, -BOUND_HUGE/2, -BOUND_HUGE/2, -BOUND_HUGE/2,
671 BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
672
673 if (Plane->Clip != NULL)
674 {
675 Plane->BBox = Plane->Clip->BBox;
676 }
677 }
678
679 END_POV_NAMESPACE
680