1 /*******************************************************************************
2 * planes.cpp
3 *
4 * This module implements functions that manipulate planes.
5 *
6 * ---------------------------------------------------------------------------
7 * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
8 * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
9 *
10 * POV-Ray is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as
12 * published by the Free Software Foundation, either version 3 of the
13 * License, or (at your option) any later version.
14 *
15 * POV-Ray is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
19 *
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * ---------------------------------------------------------------------------
23 * POV-Ray is based on the popular DKB raytracer version 2.12.
24 * DKBTrace was originally written by David K. Buck.
25 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
26 * ---------------------------------------------------------------------------
27 * $File: //depot/public/povray/3.x/source/backend/shape/planes.cpp $
28 * $Revision: #1 $
29 * $Change: 6069 $
30 * $DateTime: 2013/11/06 11:59:40 $
31 * $Author: chrisc $
32 *******************************************************************************/
33
34 // frame.h must always be the first POV file included (pulls in platform config)
35 #include "backend/frame.h"
36 #include "backend/math/vector.h"
37 #include "backend/math/matrices.h"
38 #include "backend/scene/objects.h"
39 #include "backend/scene/threaddata.h"
40 #include "backend/shape/planes.h"
41
42 // this must be the last file included
43 #include "base/povdebug.h"
44
45 namespace pov
46 {
47
48 /*****************************************************************************
49 * Local preprocessor defines
50 ******************************************************************************/
51
52 const DBL DEPTH_TOLERANCE = 1.0e-6;
53
54
55
56 /*****************************************************************************
57 *
58 * FUNCTION
59 *
60 * All_Plane_Intersections
61 *
62 * INPUT
63 *
64 * OUTPUT
65 *
66 * RETURNS
67 *
68 * AUTHOR
69 *
70 * POV-Ray Team
71 *
72 * DESCRIPTION
73 *
74 * -
75 *
76 * CHANGES
77 *
78 * -
79 *
80 ******************************************************************************/
81
All_Intersections(const Ray & ray,IStack & Depth_Stack,TraceThreadData * Thread)82 bool Plane::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread)
83 {
84 DBL Depth;
85 VECTOR IPoint;
86
87 if (Intersect(ray, &Depth, Thread))
88 {
89 VEvaluateRay(IPoint, ray.Origin, Depth, ray.Direction);
90
91 if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread))
92 {
93 Depth_Stack->push(Intersection(Depth,IPoint,this));
94 return(true);
95 }
96 }
97
98 return(false);
99 }
100
101
102
103 /*****************************************************************************
104 *
105 * FUNCTION
106 *
107 * Intersect_Plane
108 *
109 * INPUT
110 *
111 * OUTPUT
112 *
113 * RETURNS
114 *
115 * AUTHOR
116 *
117 * POV-Ray Team
118 *
119 * DESCRIPTION
120 *
121 * -
122 *
123 * CHANGES
124 *
125 * -
126 *
127 ******************************************************************************/
128
Intersect(const Ray & ray,DBL * Depth,TraceThreadData * Thread) const129 bool Plane::Intersect(const Ray& ray, DBL *Depth, TraceThreadData *Thread) const
130 {
131 DBL NormalDotOrigin, NormalDotDirection;
132 VECTOR P, D;
133
134 Thread->Stats()[Ray_Plane_Tests]++;
135
136 if (Trans == NULL)
137 {
138 VDot(NormalDotDirection, Normal_Vector, ray.Direction);
139
140 if (fabs(NormalDotDirection) < EPSILON)
141 {
142 return(false);
143 }
144
145 VDot(NormalDotOrigin, Normal_Vector, ray.Origin);
146 }
147 else
148 {
149 MInvTransPoint(P, ray.Origin, Trans);
150 MInvTransDirection(D, ray.Direction, Trans);
151
152 VDot(NormalDotDirection, Normal_Vector, D);
153
154 if (fabs(NormalDotDirection) < EPSILON)
155 {
156 return(false);
157 }
158
159 VDot(NormalDotOrigin, Normal_Vector, P);
160 }
161
162 *Depth = -(NormalDotOrigin + Distance) / NormalDotDirection;
163
164 if ((*Depth >= DEPTH_TOLERANCE) && (*Depth <= MAX_DISTANCE))
165 {
166 Thread->Stats()[Ray_Plane_Tests_Succeeded]++;
167 return (true);
168 }
169 else
170 {
171 return (false);
172 }
173 }
174
175
176
177 /*****************************************************************************
178 *
179 * FUNCTION
180 *
181 * Inside_Plane
182 *
183 * INPUT
184 *
185 * OUTPUT
186 *
187 * RETURNS
188 *
189 * AUTHOR
190 *
191 * POV-Ray Team
192 *
193 * DESCRIPTION
194 *
195 * -
196 *
197 * CHANGES
198 *
199 * -
200 *
201 ******************************************************************************/
202
Inside(const VECTOR IPoint,TraceThreadData * Thread) const203 bool Plane::Inside(const VECTOR IPoint, TraceThreadData *Thread) const
204 {
205 DBL Temp;
206 VECTOR P;
207
208 if(Trans == NULL)
209 {
210 VDot(Temp, IPoint, Normal_Vector);
211 }
212 else
213 {
214 MInvTransPoint(P, IPoint, Trans);
215
216 VDot(Temp, P, Normal_Vector);
217 }
218
219 return((Temp + Distance) < EPSILON);
220 }
221
222
223
224 /*****************************************************************************
225 *
226 * FUNCTION
227 *
228 * Plane_Normal
229 *
230 * INPUT
231 *
232 * OUTPUT
233 *
234 * RETURNS
235 *
236 * AUTHOR
237 *
238 * POV-Ray Team
239 *
240 * DESCRIPTION
241 *
242 * -
243 *
244 * CHANGES
245 *
246 * -
247 *
248 ******************************************************************************/
249
Normal(VECTOR Result,Intersection *,TraceThreadData *) const250 void Plane::Normal(VECTOR Result, Intersection *, TraceThreadData *) const
251 {
252 Assign_Vector(Result, Normal_Vector);
253
254 if(Trans != NULL)
255 {
256 MTransNormal(Result, Result, Trans);
257
258 VNormalize(Result, Result);
259 }
260 }
261
262
263
264 /*****************************************************************************
265 *
266 * FUNCTION
267 *
268 * Translate_Plane
269 *
270 * INPUT
271 *
272 * OUTPUT
273 *
274 * RETURNS
275 *
276 * AUTHOR
277 *
278 * POV-Ray Team
279 *
280 * DESCRIPTION
281 *
282 * -
283 *
284 * CHANGES
285 *
286 * -
287 *
288 ******************************************************************************/
289
Translate(const VECTOR Vector,const TRANSFORM * tr)290 void Plane::Translate(const VECTOR Vector, const TRANSFORM *tr)
291 {
292 VECTOR Translation;
293
294 if(Trans == NULL)
295 {
296 VEvaluate (Translation, Normal_Vector, Vector);
297
298 Distance -= Translation[X] + Translation[Y] + Translation[Z];
299
300 Compute_BBox();
301 }
302 else
303 {
304 Transform(tr);
305 }
306 }
307
308
309
310 /*****************************************************************************
311 *
312 * FUNCTION
313 *
314 * Rotate_Plane
315 *
316 * INPUT
317 *
318 * OUTPUT
319 *
320 * RETURNS
321 *
322 * AUTHOR
323 *
324 * POV-Ray Team
325 *
326 * DESCRIPTION
327 *
328 * -
329 *
330 * CHANGES
331 *
332 * -
333 *
334 ******************************************************************************/
335
Rotate(const VECTOR,const TRANSFORM * tr)336 void Plane::Rotate(const VECTOR, const TRANSFORM *tr)
337 {
338 if(Trans == NULL)
339 {
340 MTransDirection(Normal_Vector, Normal_Vector, tr);
341
342 Compute_BBox();
343 }
344 else
345 {
346 Transform(tr);
347 }
348 }
349
350
351
352 /*****************************************************************************
353 *
354 * FUNCTION
355 *
356 * Scale_Plane
357 *
358 * INPUT
359 *
360 * OUTPUT
361 *
362 * RETURNS
363 *
364 * AUTHOR
365 *
366 * POV-Ray Team
367 *
368 * DESCRIPTION
369 *
370 * -
371 *
372 * CHANGES
373 *
374 * -
375 *
376 ******************************************************************************/
377
Scale(const VECTOR Vector,const TRANSFORM * tr)378 void Plane::Scale(const VECTOR Vector, const TRANSFORM *tr)
379 {
380 DBL Length;
381
382 if(Trans == NULL)
383 {
384 VDivEq(Normal_Vector, Vector);
385
386 VLength(Length, Normal_Vector);
387
388 VInverseScaleEq(Normal_Vector, Length);
389
390 Distance /= Length;
391
392 Compute_BBox();
393 }
394 else
395 {
396 Transform(tr);
397 }
398 }
399
400
401
402 /*****************************************************************************
403 *
404 * FUNCTION
405 *
406 * Invert_Plane
407 *
408 * INPUT
409 *
410 * OUTPUT
411 *
412 * RETURNS
413 *
414 * AUTHOR
415 *
416 * POV-Ray Team
417 *
418 * DESCRIPTION
419 *
420 * -
421 *
422 * CHANGES
423 *
424 * -
425 *
426 ******************************************************************************/
427
Invert()428 void Plane::Invert()
429 {
430 VScaleEq(Normal_Vector, -1.0);
431
432 Distance *= -1.0;
433 }
434
435
436
437 /*****************************************************************************
438 *
439 * FUNCTION
440 *
441 * Transform_Plane
442 *
443 * INPUT
444 *
445 * OUTPUT
446 *
447 * RETURNS
448 *
449 * AUTHOR
450 *
451 * POV-Ray Team
452 *
453 * DESCRIPTION
454 *
455 * -
456 *
457 * CHANGES
458 *
459 * -
460 *
461 ******************************************************************************/
462
Transform(const TRANSFORM * tr)463 void Plane::Transform(const TRANSFORM *tr)
464 {
465 if(Trans == NULL)
466 Trans = Create_Transform();
467
468 Compose_Transforms(Trans, tr);
469
470 Compute_BBox();
471 }
472
473
474
475 /*****************************************************************************
476 *
477 * FUNCTION
478 *
479 * Create_Plane
480 *
481 * INPUT
482 *
483 * OUTPUT
484 *
485 * RETURNS
486 *
487 * AUTHOR
488 *
489 * POV-Ray Team
490 *
491 * DESCRIPTION
492 *
493 * -
494 *
495 * CHANGES
496 *
497 * -
498 *
499 ******************************************************************************/
500
Plane()501 Plane::Plane() : ObjectBase(PLANE_OBJECT)
502 {
503 Make_Vector(Normal_Vector, 0.0, 1.0, 0.0);
504
505 Distance = 0.0;
506
507 Trans = NULL;
508 }
509
510
511
512 /*****************************************************************************
513 *
514 * FUNCTION
515 *
516 * Copy_Plane
517 *
518 * INPUT
519 *
520 * OUTPUT
521 *
522 * RETURNS
523 *
524 * AUTHOR
525 *
526 * POV-Ray Team
527 *
528 * DESCRIPTION
529 *
530 * -
531 *
532 * CHANGES
533 *
534 * -
535 *
536 ******************************************************************************/
537
Copy()538 ObjectPtr Plane::Copy()
539 {
540 Plane *New = new Plane();
541 Destroy_Transform(New->Trans);
542 *New = *this;
543 New->Trans = Copy_Transform(Trans);
544
545 return(New);
546 }
547
548
549
550 /*****************************************************************************
551 *
552 * FUNCTION
553 *
554 * Destroy_Plane
555 *
556 * INPUT
557 *
558 * OUTPUT
559 *
560 * RETURNS
561 *
562 * AUTHOR
563 *
564 * POV-Ray Team
565 *
566 * DESCRIPTION
567 *
568 * -
569 *
570 * CHANGES
571 *
572 * -
573 *
574 ******************************************************************************/
575
~Plane()576 Plane::~Plane()
577 {
578 Destroy_Transform(Trans);
579 }
580
581
582
583 /*****************************************************************************
584 *
585 * FUNCTION
586 *
587 * Compute_Plane_BBox
588 *
589 * INPUT
590 *
591 * Plane - Plane
592 *
593 * OUTPUT
594 *
595 * Plane
596 *
597 * RETURNS
598 *
599 * AUTHOR
600 *
601 * Dieter Bayer
602 *
603 * DESCRIPTION
604 *
605 * Calculate the bounding box of a plane (it's always infinite).
606 *
607 * CHANGES
608 *
609 * Aug 1994 : Creation.
610 *
611 ******************************************************************************/
612
Compute_BBox()613 void Plane::Compute_BBox()
614 {
615 Make_BBox(BBox, -BOUND_HUGE/2, -BOUND_HUGE/2, -BOUND_HUGE/2,
616 BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
617
618 if (!Clip.empty())
619 {
620 BBox = Clip[0]->BBox; // FIXME - only supports one clip object? [trf]
621 }
622 }
623
Intersect_BBox(BBoxDirection,const BBOX_VECT &,const BBOX_VECT &,BBOX_VAL) const624 bool Plane::Intersect_BBox(BBoxDirection, const BBOX_VECT&, const BBOX_VECT&, BBOX_VAL) const
625 {
626 return true;
627 }
628
629 }
630