1 /*******************************************************************************
2 * frame.h
3 *
4 * This header file is included by all C modules in POV-Ray. It defines all
5 * globally-accessible types and constants.
6 *
7 * ---------------------------------------------------------------------------
8 * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
9 * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
10 *
11 * POV-Ray is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Affero General Public License as
13 * published by the Free Software Foundation, either version 3 of the
14 * License, or (at your option) any later version.
15 *
16 * POV-Ray is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Affero General Public License for more details.
20 *
21 * You should have received a copy of the GNU Affero General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * ---------------------------------------------------------------------------
24 * POV-Ray is based on the popular DKB raytracer version 2.12.
25 * DKBTrace was originally written by David K. Buck.
26 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
27 * ---------------------------------------------------------------------------
28 * $File: //depot/public/povray/3.x/source/backend/frame.h $
29 * $Revision: #1 $
30 * $Change: 6069 $
31 * $DateTime: 2013/11/06 11:59:40 $
32 * $Author: chrisc $
33 *******************************************************************************/
34
35 #ifndef FRAME_H
36 #define FRAME_H
37
38 // Generic header for all modules
39
40 #include <new>
41
42 #include <stdio.h>
43 #include <string.h>
44 #include <limits.h>
45
46 #include <vector>
47 #include <stack>
48
49 #ifndef MATH_H_INCLUDED
50 #include <math.h>
51 #endif
52
53 #include "base/configbase.h"
54 #include "base/types.h"
55
56 #include "backend/configbackend.h"
57 #include "backend/support/simplevector.h"
58 #include "backend/control/messagefactory.h"
59 #include "backend/colour/spectral.h"
60
61 #include "pov_mem.h"
62
63 namespace pov
64 {
65
66 using namespace pov_base;
67
68 // these defines affect the maximum size of some types based on FixedSimpleVector
69
70 #ifndef MEDIA_VECTOR_SIZE
71 #define MEDIA_VECTOR_SIZE 256
72 #endif
73
74 #ifndef MEDIA_INTERVAL_VECTOR_SIZE
75 #define MEDIA_INTERVAL_VECTOR_SIZE 256
76 #endif
77
78 #ifndef LIT_INTERVAL_VECTOR_SIZE
79 #define LIT_INTERVAL_VECTOR_SIZE 512
80 #endif
81
82 #ifndef LIGHT_INTERSECTION_VECTOR_SIZE
83 #define LIGHT_INTERSECTION_VECTOR_SIZE 512
84 #endif
85
86 #ifndef LIGHTSOURCE_VECTOR_SIZE
87 #define LIGHTSOURCE_VECTOR_SIZE 1024
88 #endif
89
90 #ifndef WEIGHTEDTEXTURE_VECTOR_SIZE
91 #define WEIGHTEDTEXTURE_VECTOR_SIZE 512
92 #endif
93
94 #ifndef RAYINTERIOR_VECTOR_SIZE
95 #define RAYINTERIOR_VECTOR_SIZE 512
96 #endif
97
98 /*****************************************************************************
99 *
100 * Typedefs that need to be known here.
101 *
102 *****************************************************************************/
103
104 class ObjectBase;
105 typedef ObjectBase * ObjectPtr;
106 typedef const ObjectBase * ConstObjectPtr;
107
108 class CompoundObject;
109
110
111 /*****************************************************************************
112 *
113 * Scalar, color and vector stuff.
114 *
115 *****************************************************************************/
116
117 typedef DBL UV_VECT[2];
118 typedef DBL VECTOR[3];
119 typedef DBL VECTOR_4D[4];
120 typedef DBL MATRIX[4][4];
121 typedef DBL EXPRESS[5];
122 typedef COLC COLOUR[5];
123 typedef COLC RGB[3];
124 typedef SNGL SNGL_VECT[3];
125
126 // Vector array elements.
127 enum
128 {
129 U = 0,
130 V = 1
131 };
132
133 enum
134 {
135 X = 0,
136 Y = 1,
137 Z = 2,
138 T = 3,
139 W = 3
140 };
141
142 // Color array elements.
143 enum
144 {
145 pRED = 0,
146 pGREEN = 1,
147 pBLUE = 2,
148 pFILTER = 3,
149 pTRANSM = 4
150 };
151
152 // Macros to manipulate scalars, vectors, and colors.
153
Assign_Vector(VECTOR d,const VECTOR s)154 inline void Assign_Vector(VECTOR d, const VECTOR s)
155 {
156 d[X] = s[X];
157 d[Y] = s[Y];
158 d[Z] = s[Z];
159 }
160
Assign_Vector(VECTOR d,const SNGL_VECT s)161 inline void Assign_Vector(VECTOR d, const SNGL_VECT s)
162 {
163 d[X] = s[X];
164 d[Y] = s[Y];
165 d[Z] = s[Z];
166 }
167
Assign_Vector(SNGL_VECT d,const VECTOR s)168 inline void Assign_Vector(SNGL_VECT d, const VECTOR s)
169 {
170 d[X] = s[X];
171 d[Y] = s[Y];
172 d[Z] = s[Z];
173 }
174
Assign_Vector(SNGL_VECT d,const SNGL_VECT s)175 inline void Assign_Vector(SNGL_VECT d, const SNGL_VECT s)
176 {
177 d[X] = s[X];
178 d[Y] = s[Y];
179 d[Z] = s[Z];
180 }
181
Assign_UV_Vect(UV_VECT d,const UV_VECT s)182 inline void Assign_UV_Vect(UV_VECT d, const UV_VECT s)
183 {
184 d[X] = s[X];
185 d[Y] = s[Y];
186 }
187
Assign_Vector_4D(VECTOR_4D d,const VECTOR_4D s)188 inline void Assign_Vector_4D(VECTOR_4D d, const VECTOR_4D s)
189 {
190 d[X] = s[X];
191 d[Y] = s[Y];
192 d[Z] = s[Z];
193 d[T] = s[T];
194 }
195
Assign_Colour(COLOUR d,const COLOUR s)196 inline void Assign_Colour(COLOUR d, const COLOUR s)
197 {
198 d[pRED] = s[pRED];
199 d[pGREEN] = s[pGREEN];
200 d[pBLUE] = s[pBLUE];
201 d[pFILTER] = s[pFILTER];
202 d[pTRANSM] = s[pTRANSM];
203 }
204
Assign_Colour_Express(COLOUR d,const EXPRESS s)205 inline void Assign_Colour_Express(COLOUR d, const EXPRESS s)
206 {
207 d[pRED] = s[pRED];
208 d[pGREEN] = s[pGREEN];
209 d[pBLUE] = s[pBLUE];
210 d[pFILTER] = s[pFILTER];
211 d[pTRANSM] = s[pTRANSM];
212 }
213
Assign_Express(EXPRESS d,const EXPRESS s)214 inline void Assign_Express(EXPRESS d, const EXPRESS s)
215 {
216 d[pRED] = s[pRED];
217 d[pGREEN] = s[pGREEN];
218 d[pBLUE] = s[pBLUE];
219 d[pFILTER] = s[pFILTER];
220 d[pTRANSM] = s[pTRANSM];
221 }
222
Make_ColourA(COLOUR c,COLC r,COLC g,COLC b,COLC a,COLC t)223 inline void Make_ColourA(COLOUR c, COLC r, COLC g, COLC b, COLC a, COLC t)
224 {
225 c[pRED] = r;
226 c[pGREEN] = g;
227 c[pBLUE] = b;
228 c[pFILTER] = a;
229 c[pTRANSM] = t;
230 }
231
Make_Vector(VECTOR v,DBL a,DBL b,DBL c)232 inline void Make_Vector(VECTOR v, DBL a, DBL b, DBL c)
233 {
234 v[X] = a;
235 v[Y] = b;
236 v[Z] = c;
237 }
238
Make_Vector(SNGL_VECT v,SNGL a,SNGL b,SNGL c)239 inline void Make_Vector(SNGL_VECT v, SNGL a, SNGL b, SNGL c)
240 {
241 v[X] = a;
242 v[Y] = b;
243 v[Z] = c;
244 }
245
Make_UV_Vector(UV_VECT v,DBL a,DBL b)246 inline void Make_UV_Vector(UV_VECT v, DBL a, DBL b)
247 {
248 v[U] = a;
249 v[V] = b;
250 }
251
Destroy_Float(DBL * x)252 inline void Destroy_Float(DBL *x)
253 {
254 if(x != NULL)
255 POV_FREE(x);
256 }
257
Destroy_Vector(VECTOR * x)258 inline void Destroy_Vector(VECTOR *x)
259 {
260 if(x != NULL)
261 POV_FREE(x);
262 }
263
Destroy_UV_Vect(UV_VECT * x)264 inline void Destroy_UV_Vect(UV_VECT *x)
265 {
266 if(x != NULL)
267 POV_FREE(x);
268 }
269
Destroy_Vector_4D(VECTOR_4D * x)270 inline void Destroy_Vector_4D(VECTOR_4D *x)
271 {
272 if(x != NULL)
273 POV_FREE(x);
274 }
275
Destroy_Colour(COLOUR * x)276 inline void Destroy_Colour(COLOUR *x)
277 {
278 if(x != NULL)
279 POV_FREE(x);
280 }
281
282 #if 0
283 #pragma mark * Vector2d
284 #endif
285
286 class Vector2d
287 {
288 public:
Vector2d()289 Vector2d()
290 {
291 vect[X] = 0.0;
292 vect[Y] = 0.0;
293 }
294
Vector2d(DBL d)295 explicit Vector2d(DBL d)
296 {
297 vect[X] = d;
298 vect[Y] = d;
299 }
300
Vector2d(DBL x,DBL y)301 Vector2d(DBL x, DBL y)
302 {
303 vect[X] = x;
304 vect[Y] = y;
305 }
306
Vector2d(const UV_VECT vi)307 explicit Vector2d(const UV_VECT vi)
308 {
309 vect[X] = vi[X];
310 vect[Y] = vi[Y];
311 }
312
Vector2d(const SNGL_VECT vi)313 explicit Vector2d(const SNGL_VECT vi)
314 {
315 vect[X] = DBL(vi[X]);
316 vect[Y] = DBL(vi[Y]);
317 }
318
Vector2d(const Vector2d & b)319 Vector2d(const Vector2d& b)
320 {
321 vect[X] = b[X];
322 vect[Y] = b[Y];
323 }
324
325 Vector2d& operator=(const Vector2d& b)
326 {
327 vect[X] = b[X];
328 vect[Y] = b[Y];
329 return *this;
330 }
331
332 DBL operator[](int idx) const { return vect[idx]; }
333 DBL& operator[](int idx) { return vect[idx]; }
334
335 Vector2d operator+(const Vector2d& b) const
336 {
337 return Vector2d(vect[X] + b[X], vect[Y] + b[Y]);
338 }
339
340 Vector2d operator-(const Vector2d& b) const
341 {
342 return Vector2d(vect[X] - b[X], vect[Y] - b[Y]);
343 }
344
345 Vector2d operator*(const Vector2d& b) const
346 {
347 return Vector2d(vect[X] * b[X], vect[Y] * b[Y]);
348 }
349
350 Vector2d operator/(const Vector2d& b) const
351 {
352 return Vector2d(vect[X] / b[X], vect[Y] / b[Y]);
353 }
354
355 Vector2d& operator+=(const Vector2d& b)
356 {
357 vect[X] += b[X];
358 vect[Y] += b[Y];
359 return *this;
360 }
361
362 Vector2d& operator-=(const Vector2d& b)
363 {
364 vect[X] -= b[X];
365 vect[Y] -= b[Y];
366 return *this;
367 }
368
369 Vector2d& operator*=(const Vector2d& b)
370 {
371 vect[X] *= b[X];
372 vect[Y] *= b[Y];
373 return *this;
374 }
375
376 Vector2d& operator/=(const Vector2d& b)
377 {
378 vect[X] /= b[X];
379 vect[Y] /= b[Y];
380 return *this;
381 }
382
383 Vector2d operator-() const
384 {
385 return Vector2d(-vect[X], -vect[Y]);
386 }
387
388 Vector2d operator+(DBL b) const
389 {
390 return Vector2d(vect[X] + b, vect[Y] + b);
391 }
392
393 Vector2d operator-(DBL b) const
394 {
395 return Vector2d(vect[X] - b, vect[Y] - b);
396 }
397
398 Vector2d operator*(DBL b) const
399 {
400 return Vector2d(vect[X] * b, vect[Y] * b);
401 }
402
403 Vector2d operator/(DBL b) const
404 {
405 return Vector2d(vect[X] / b, vect[Y] / b);
406 }
407
408 Vector2d& operator+=(DBL b)
409 {
410 vect[X] += b;
411 vect[Y] += b;
412 return *this;
413 }
414
415 Vector2d& operator-=(DBL b)
416 {
417 vect[X] -= b;
418 vect[Y] -= b;
419 return *this;
420 }
421
422 Vector2d& operator*=(DBL b)
423 {
424 vect[X] *= b;
425 vect[Y] *= b;
426 return *this;
427 }
428
429 Vector2d& operator/=(DBL b)
430 {
431 vect[X] /= b;
432 vect[Y] /= b;
433 return *this;
434 }
435
436 const UV_VECT& operator*() const { return vect; }
437 UV_VECT& operator*() { return vect; }
438
x()439 DBL x() const { return vect[X]; }
x()440 DBL& x() { return vect[X]; }
441
y()442 DBL y() const { return vect[Y]; }
y()443 DBL& y() { return vect[Y]; }
444
u()445 DBL u() const { return vect[X]; }
u()446 DBL& u() { return vect[X]; }
447
v()448 DBL v() const { return vect[Y]; }
v()449 DBL& v() { return vect[Y]; }
450
length()451 DBL length() const
452 {
453 return sqrt(vect[X] * vect[X] + vect[Y] * vect[Y]);
454 }
lengthSqr()455 DBL lengthSqr() const
456 {
457 return vect[X] * vect[X] + vect[Y] * vect[Y];
458 }
normalized()459 Vector2d normalized() const
460 {
461 DBL l = length();
462 if (l != 0)
463 return *this / l;
464 else
465 return *this;
466 }
normalize()467 void normalize()
468 {
469 DBL l = length();
470 if (l != 0)
471 *this /= l;
472 // no else
473 }
474
475 private:
476 DBL vect[2];
477 };
478
479 #if 0
480 #pragma mark * Vector3d
481 #endif
482
483 class Vector3d
484 {
485 public:
486
Vector3d()487 Vector3d()
488 {
489 vect[X] = 0.0;
490 vect[Y] = 0.0;
491 vect[Z] = 0.0;
492 }
493
Vector3d(DBL d)494 explicit Vector3d(DBL d)
495 {
496 vect[X] = d;
497 vect[Y] = d;
498 vect[Z] = d;
499 }
500
Vector3d(DBL x,DBL y,DBL z)501 Vector3d(DBL x, DBL y, DBL z)
502 {
503 vect[X] = x;
504 vect[Y] = y;
505 vect[Z] = z;
506 }
507
Vector3d(const VECTOR vi)508 explicit Vector3d(const VECTOR vi)
509 {
510 vect[X] = vi[X];
511 vect[Y] = vi[Y];
512 vect[Z] = vi[Z];
513 }
514
Vector3d(const SNGL_VECT vi)515 explicit Vector3d(const SNGL_VECT vi)
516 {
517 vect[X] = DBL(vi[X]);
518 vect[Y] = DBL(vi[Y]);
519 vect[Z] = DBL(vi[Z]);
520 }
521
Vector3d(const Vector3d & b)522 Vector3d(const Vector3d& b)
523 {
524 vect[X] = b[X];
525 vect[Y] = b[Y];
526 vect[Z] = b[Z];
527 }
528
529 Vector3d& operator=(const Vector3d& b)
530 {
531 vect[X] = b[X];
532 vect[Y] = b[Y];
533 vect[Z] = b[Z];
534 return *this;
535 }
536
537 DBL operator[](int idx) const { return vect[idx]; }
538 DBL& operator[](int idx) { return vect[idx]; }
539
540 Vector3d operator+(const Vector3d& b) const
541 {
542 return Vector3d(vect[X] + b[X], vect[Y] + b[Y], vect[Z] + b[Z]);
543 }
544
545 Vector3d operator-(const Vector3d& b) const
546 {
547 return Vector3d(vect[X] - b[X], vect[Y] - b[Y], vect[Z] - b[Z]);
548 }
549
550 Vector3d operator*(const Vector3d& b) const
551 {
552 return Vector3d(vect[X] * b[X], vect[Y] * b[Y], vect[Z] * b[Z]);
553 }
554
555 Vector3d operator/(const Vector3d& b) const
556 {
557 return Vector3d(vect[X] / b[X], vect[Y] / b[Y], vect[Z] / b[Z]);
558 }
559
560 Vector3d& operator+=(const Vector3d& b)
561 {
562 vect[X] += b[X];
563 vect[Y] += b[Y];
564 vect[Z] += b[Z];
565 return *this;
566 }
567
568 Vector3d& operator-=(const Vector3d& b)
569 {
570 vect[X] -= b[X];
571 vect[Y] -= b[Y];
572 vect[Z] -= b[Z];
573 return *this;
574 }
575
576 Vector3d& operator*=(const Vector3d& b)
577 {
578 vect[X] *= b[X];
579 vect[Y] *= b[Y];
580 vect[Z] *= b[Z];
581 return *this;
582 }
583
584 Vector3d& operator/=(const Vector3d& b)
585 {
586 vect[X] /= b[X];
587 vect[Y] /= b[Y];
588 vect[Z] /= b[Z];
589 return *this;
590 }
591
592 Vector3d operator-() const
593 {
594 return Vector3d(-vect[X], -vect[Y], -vect[Z]);
595 }
596
597 Vector3d operator+(DBL b) const
598 {
599 return Vector3d(vect[X] + b, vect[Y] + b, vect[Z] + b);
600 }
601
602 Vector3d operator-(DBL b) const
603 {
604 return Vector3d(vect[X] - b, vect[Y] - b, vect[Z] - b);
605 }
606
607 Vector3d operator*(DBL b) const
608 {
609 return Vector3d(vect[X] * b, vect[Y] * b, vect[Z] * b);
610 }
611
612 Vector3d operator/(DBL b) const
613 {
614 return Vector3d(vect[X] / b, vect[Y] / b, vect[Z] / b);
615 }
616
617 Vector3d& operator+=(DBL b)
618 {
619 vect[X] += b;
620 vect[Y] += b;
621 vect[Z] += b;
622 return *this;
623 }
624
625 Vector3d& operator-=(DBL b)
626 {
627 vect[X] -= b;
628 vect[Y] -= b;
629 vect[Z] -= b;
630 return *this;
631 }
632
633 Vector3d& operator*=(DBL b)
634 {
635 vect[X] *= b;
636 vect[Y] *= b;
637 vect[Z] *= b;
638 return *this;
639 }
640
641 Vector3d& operator/=(DBL b)
642 {
643 vect[X] /= b;
644 vect[Y] /= b;
645 vect[Z] /= b;
646 return *this;
647 }
648
649 const VECTOR& operator*() const { return vect; }
650 VECTOR& operator*() { return vect; }
651
x()652 DBL x() const { return vect[X]; }
x()653 DBL& x() { return vect[X]; }
654
y()655 DBL y() const { return vect[Y]; }
y()656 DBL& y() { return vect[Y]; }
657
z()658 DBL z() const { return vect[Z]; }
z()659 DBL& z() { return vect[Z]; }
660
length()661 DBL length() const
662 {
663 return sqrt(vect[X] * vect[X] + vect[Y] * vect[Y] + vect[Z] * vect[Z]);
664 }
lengthSqr()665 DBL lengthSqr() const
666 {
667 return vect[X] * vect[X] + vect[Y] * vect[Y] + vect[Z] * vect[Z];
668 }
normalized()669 Vector3d normalized() const
670 {
671 DBL l = length();
672 if (l != 0)
673 return *this / l;
674 else
675 return *this;
676 }
normalize()677 void normalize()
678 {
679 DBL l = length();
680 if (l != 0)
681 *this /= l;
682 // no else
683 }
684
685 private:
686 DBL vect[3];
687 };
688
dot(const Vector2d & a,const Vector2d & b)689 inline DBL dot(const Vector2d& a, const Vector2d& b)
690 {
691 return (a.x() * b.x()) + (a.y() * b.y());
692 }
693
dot(const Vector3d & a,const Vector3d & b)694 inline DBL dot(const Vector3d& a, const Vector3d& b)
695 {
696 return ((a.x() * b.x()) + (a.y() * b.y()) + (a.z() * b.z()));
697 }
698
cross(const Vector3d & a,const Vector3d & b)699 inline Vector3d cross(const Vector3d& a, const Vector3d& b)
700 {
701 return Vector3d( ((a.y() * b.z()) - (a.z() * b.y())),
702 ((a.z() * b.x()) - (a.x() * b.z())),
703 ((a.x() * b.y()) - (a.y() * b.x())) );
704 }
705
similar(const Vector3d & a,const Vector3d & b)706 inline bool similar(const Vector3d& a, const Vector3d& b)
707 {
708 return ( fabs(a.x()-b.x()) + fabs(a.y()-b.y()) + fabs(a.z()-b.z()) < EPSILON );
709 }
710
711 inline Vector3d operator* (double a, const Vector3d& b) { return b * a; }
712
713 typedef pov_base::Colour Colour;
714
715 /*****************************************************************************
716 *
717 * Bounding box stuff (see also BOUND.H).
718 *
719 *****************************************************************************/
720
721 #if 0
722 #pragma mark * Bounding
723 #endif
724
725 typedef SNGL BBOX_VAL;
726
727 typedef BBOX_VAL BBOX_VECT[3];
728
729 typedef struct Bounding_Box_Struct BBOX;
730
731 struct Bounding_Box_Struct
732 {
733 union
734 {
735 BBOX_VECT Lower_Left;
736 BBOX_VECT pmin;
737 BBOX_VECT lowerleft;
738 };
739 union
740 {
741 BBOX_VECT Lengths;
742 BBOX_VECT pmax;
743 BBOX_VECT length;
744 };
745
GetMinXBounding_Box_Struct746 SNGL GetMinX() const { return Lower_Left[X]; }
GetMinYBounding_Box_Struct747 SNGL GetMinY() const { return Lower_Left[Y]; }
GetMinZBounding_Box_Struct748 SNGL GetMinZ() const { return Lower_Left[Z]; }
749
GetMaxXBounding_Box_Struct750 SNGL GetMaxX() const { return Lower_Left[X] + Lengths[X]; }
GetMaxYBounding_Box_Struct751 SNGL GetMaxY() const { return Lower_Left[Y] + Lengths[Y]; }
GetMaxZBounding_Box_Struct752 SNGL GetMaxZ() const { return Lower_Left[Z] + Lengths[Z]; }
753 };
754
Assign_BBox_Vect(BBOX_VECT & d,const BBOX_VECT s)755 inline void Assign_BBox_Vect(BBOX_VECT& d, const BBOX_VECT s)
756 {
757 d[X] = s[X];
758 d[Y] = s[Y];
759 d[Z] = s[Z];
760 }
761
Assign_BBox_Vect(BBOX_VECT & d,const VECTOR s)762 inline void Assign_BBox_Vect(BBOX_VECT& d, const VECTOR s)
763 {
764 d[X] = s[X];
765 d[Y] = s[Y];
766 d[Z] = s[Z];
767 }
768
Assign_BBox_Vect(VECTOR & d,const BBOX_VECT s)769 inline void Assign_BBox_Vect(VECTOR& d, const BBOX_VECT s)
770 {
771 d[X] = s[X];
772 d[Y] = s[Y];
773 d[Z] = s[Z];
774 }
775
Make_BBox(BBOX & BBox,const BBOX_VAL llx,const BBOX_VAL lly,const BBOX_VAL llz,const BBOX_VAL lex,const BBOX_VAL ley,const BBOX_VAL lez)776 inline void Make_BBox(BBOX& BBox, const BBOX_VAL llx, const BBOX_VAL lly, const BBOX_VAL llz, const BBOX_VAL lex, const BBOX_VAL ley, const BBOX_VAL lez)
777 {
778 BBox.Lower_Left[X] = (BBOX_VAL)(llx);
779 BBox.Lower_Left[Y] = (BBOX_VAL)(lly);
780 BBox.Lower_Left[Z] = (BBOX_VAL)(llz);
781 BBox.Lengths[X] = (BBOX_VAL)(lex);
782 BBox.Lengths[Y] = (BBOX_VAL)(ley);
783 BBox.Lengths[Z] = (BBOX_VAL)(lez);
784 }
785
Make_BBox_from_min_max(BBOX & BBox,const BBOX_VECT mins,const BBOX_VECT maxs)786 inline void Make_BBox_from_min_max(BBOX& BBox, const BBOX_VECT mins, const BBOX_VECT maxs)
787 {
788 BBox.Lower_Left[X] = (BBOX_VAL)(mins[X]);
789 BBox.Lower_Left[Y] = (BBOX_VAL)(mins[Y]);
790 BBox.Lower_Left[Z] = (BBOX_VAL)(mins[Z]);
791 BBox.Lengths[X] = (BBOX_VAL)(maxs[X]-mins[X]);
792 BBox.Lengths[Y] = (BBOX_VAL)(maxs[Y]-mins[Y]);
793 BBox.Lengths[Z] = (BBOX_VAL)(maxs[Z]-mins[Z]);
794 }
795
Make_BBox_from_min_max(BBOX & BBox,const VECTOR mins,const VECTOR maxs)796 inline void Make_BBox_from_min_max(BBOX& BBox, const VECTOR mins, const VECTOR maxs)
797 {
798 BBox.Lower_Left[X] = (BBOX_VAL)(mins[X]);
799 BBox.Lower_Left[Y] = (BBOX_VAL)(mins[Y]);
800 BBox.Lower_Left[Z] = (BBOX_VAL)(mins[Z]);
801 BBox.Lengths[X] = (BBOX_VAL)(maxs[X]-mins[X]);
802 BBox.Lengths[Y] = (BBOX_VAL)(maxs[Y]-mins[Y]);
803 BBox.Lengths[Z] = (BBOX_VAL)(maxs[Z]-mins[Z]);
804 }
805
Make_min_max_from_BBox(BBOX_VECT & mins,BBOX_VECT & maxs,const BBOX & BBox)806 inline void Make_min_max_from_BBox(BBOX_VECT& mins, BBOX_VECT& maxs, const BBOX& BBox)
807 {
808 mins[X] = BBox.Lower_Left[X];
809 mins[Y] = BBox.Lower_Left[Y];
810 mins[Z] = BBox.Lower_Left[Z];
811 maxs[X] = mins[X] + BBox.Lengths[X];
812 maxs[Y] = mins[Y] + BBox.Lengths[Y];
813 maxs[Z] = mins[Z] + BBox.Lengths[Z];
814 }
815
Make_min_max_from_BBox(VECTOR & mins,VECTOR & maxs,const BBOX & BBox)816 inline void Make_min_max_from_BBox(VECTOR& mins, VECTOR& maxs, const BBOX& BBox)
817 {
818 mins[X] = BBox.Lower_Left[X];
819 mins[Y] = BBox.Lower_Left[Y];
820 mins[Z] = BBox.Lower_Left[Z];
821 maxs[X] = mins[X] + BBox.Lengths[X];
822 maxs[Y] = mins[Y] + BBox.Lengths[Y];
823 maxs[Z] = mins[Z] + BBox.Lengths[Z];
824 }
825
Inside_BBox(const VECTOR point,const BBOX & bbox)826 inline bool Inside_BBox(const VECTOR point, const BBOX& bbox)
827 {
828 if (point[X] < (DBL)bbox.Lower_Left[X])
829 return(false);
830 if (point[Y] < (DBL)bbox.Lower_Left[Y])
831 return(false);
832 if (point[Z] < (DBL)bbox.Lower_Left[Z])
833 return(false);
834 if (point[X] > (DBL)bbox.Lower_Left[X] + (DBL)bbox.Lengths[X])
835 return(false);
836 if (point[Y] > (DBL)bbox.Lower_Left[Y] + (DBL)bbox.Lengths[Y])
837 return(false);
838 if (point[Z] > (DBL)bbox.Lower_Left[Z] + (DBL)bbox.Lengths[Z])
839 return(false);
840
841 return(true);
842 }
843
844 /*****************************************************************************
845 *
846 * Transformation stuff.
847 *
848 *****************************************************************************/
849
850 #if 0
851 #pragma mark * Transform
852 #endif
853
854 typedef struct Transform_Struct TRANSFORM;
855
856 struct Transform_Struct
857 {
858 MATRIX matrix;
859 MATRIX inverse;
860 };
861
862
863
864 /*****************************************************************************
865 *
866 * Color map stuff.
867 *
868 *****************************************************************************/
869
870 #if 0
871 #pragma mark * Blend Map
872 #endif
873
874 const int MAX_BLEND_MAP_ENTRIES = 256;
875
876 typedef struct Blend_Map_Entry BLEND_MAP_ENTRY;
877 typedef struct Blend_Map_Struct BLEND_MAP;
878 typedef struct Pattern_Struct TPATTERN;
879 typedef struct Texture_Struct TEXTURE;
880 typedef struct Pigment_Struct PIGMENT;
881 typedef struct Tnormal_Struct TNORMAL;
882 typedef struct Finish_Struct FINISH;
883 typedef struct Turb_Struct TURB;
884 typedef struct Warps_Struct WARP;
885 typedef struct Spline_Entry SPLINE_ENTRY;
886 typedef struct Spline_Struct SPLINE;
887
888 struct Blend_Map_Entry
889 {
890 SNGL value;
891 unsigned char Same;
892 union
893 {
894 COLOUR colour;
895 PIGMENT *Pigment;
896 TNORMAL *Tnormal;
897 TEXTURE *Texture;
898 UV_VECT Point_Slope;
899 } Vals;
900 };
901
902 struct Blend_Map_Struct
903 {
904 int Users;
905 short Number_Of_Entries;
906 char Transparency_Flag, Type;
907 BLEND_MAP_ENTRY *Blend_Map_Entries;
908 };
909
Make_Blend_Map_Entry(BLEND_MAP_ENTRY & entry,SNGL v,unsigned char s,COLC r,COLC g,COLC b,COLC a,COLC t)910 inline void Make_Blend_Map_Entry(BLEND_MAP_ENTRY& entry, SNGL v, unsigned char s, COLC r, COLC g, COLC b, COLC a, COLC t)
911 {
912 entry.value = v;
913 entry.Same = s;
914 Make_ColourA(entry.Vals.colour, r, g, b, a, t);
915 }
916
917
918 /*****************************************************************************
919 *
920 * Media and Interior stuff.
921 *
922 *****************************************************************************/
923
924 #if 0
925 #pragma mark * Media, Interior
926 #endif
927
928 class Media
929 {
930 public:
931 int Type;
932 int Intervals;
933 int Min_Samples;
934 int Max_Samples;
935 unsigned Sample_Method : 8;
936 bool is_constant : 1;
937 bool use_absorption : 1;
938 bool use_emission : 1;
939 bool use_extinction : 1;
940 bool use_scattering : 1;
941 bool ignore_photons : 1;
942 DBL Jitter;
943 DBL Eccentricity;
944 DBL sc_ext;
945 RGBColour Absorption;
946 RGBColour Emission;
947 RGBColour Extinction;
948 RGBColour Scattering;
949
950 DBL Ratio;
951 DBL Confidence;
952 DBL Variance;
953 DBL *Sample_Threshold;
954
955 DBL AA_Threshold;
956 int AA_Level;
957
958 PIGMENT *Density;
959
960 Media();
961 Media(const Media&);
962 ~Media();
963
964 Media& operator=(const Media&);
965
966 void Transform(const TRANSFORM *trans);
967
968 void PostProcess();
969 };
970
971 class SubsurfaceInterior;
972 class Interior
973 {
974 public:
975 int References;
976 int hollow, Disp_NElems;
977 SNGL IOR, Dispersion;
978 SNGL Caustics, Old_Refract;
979 SNGL Fade_Distance, Fade_Power;
980 RGBColour Fade_Colour;
981 vector<Media> media;
982 shared_ptr<SubsurfaceInterior> subsurface;
983
984 Interior();
985 Interior(const Interior&);
986 ~Interior();
987
988 void Transform(const TRANSFORM *trans);
989
990 void PostProcess();
991 private:
992 Interior& operator=(const Interior&);
993 };
994
995
996
997 /*****************************************************************************
998 *
999 * Spline stuff.
1000 *
1001 *****************************************************************************/
1002
1003 #if 0
1004 #pragma mark * Spline
1005 #endif
1006
1007 struct Spline_Entry
1008 {
1009 DBL par; // Parameter
1010 DBL vec[5]; // Value at the parameter
1011 DBL coeff[5]; // Interpolating coefficients at the parameter
1012 };
1013
1014 struct Spline_Struct
1015 {
1016 int Number_Of_Entries, Type;
1017 int Max_Entries;
1018 SPLINE_ENTRY *SplineEntries;
1019 int Coeffs_Computed;
1020 int Terms;
1021 /* [JG] flyspray #294 : cache is not thread-safe
1022 * (and seems useless, as slower than without it)
1023 bool Cache_Valid;
1024 int Cache_Type;
1025 DBL Cache_Point;
1026 EXPRESS Cache_Data;
1027 */
1028 int ref_count;
1029 };
1030
1031 typedef struct Spline_Entry SPLINE_ENTRY;
1032
1033
1034 /*****************************************************************************
1035 *
1036 * Image stuff.
1037 *
1038 *****************************************************************************/
1039
1040 #if 0
1041 #pragma mark * Image
1042 #endif
1043
1044 // Legal image attributes.
1045
1046 #define NO_FILE 0x00000000
1047 #define GIF_FILE 0x00000001
1048 #define POT_FILE 0x00000002
1049 #define SYS_FILE 0x00000004
1050 #define IFF_FILE 0x00000008
1051 #define TGA_FILE 0x00000010
1052 #define GRAD_FILE 0x00000020
1053 #define PGM_FILE 0x00000040
1054 #define PPM_FILE 0x00000080
1055 #define PNG_FILE 0x00000100
1056 #define JPEG_FILE 0x00000200
1057 #define TIFF_FILE 0x00000400
1058 #define BMP_FILE 0x00000800
1059 #define EXR_FILE 0x00001000
1060 #define HDR_FILE 0x00002000
1061
1062 // Image types.
1063
1064 #define IMAGE_FILE GIF_FILE+SYS_FILE+TGA_FILE+PGM_FILE+PPM_FILE+PNG_FILE+JPEG_FILE+TIFF_FILE+BMP_FILE+EXR_FILE+HDR_FILE+IFF_FILE+GRAD_FILE
1065 #define NORMAL_FILE GIF_FILE+SYS_FILE+TGA_FILE+PGM_FILE+PPM_FILE+PNG_FILE+JPEG_FILE+TIFF_FILE+BMP_FILE+EXR_FILE+HDR_FILE+IFF_FILE+GRAD_FILE
1066 #define MATERIAL_FILE GIF_FILE+SYS_FILE+TGA_FILE+PGM_FILE+PPM_FILE+PNG_FILE+JPEG_FILE+TIFF_FILE+BMP_FILE+EXR_FILE+HDR_FILE+IFF_FILE+GRAD_FILE
1067 #define HF_FILE GIF_FILE+SYS_FILE+TGA_FILE+PGM_FILE+PPM_FILE+PNG_FILE+JPEG_FILE+TIFF_FILE+BMP_FILE+EXR_FILE+HDR_FILE+POT_FILE
1068
1069 #define PIGMENT_TYPE 0
1070 #define NORMAL_TYPE 1
1071 #define PATTERN_TYPE 2
1072 #define TEXTURE_TYPE 4
1073 #define COLOUR_TYPE 5
1074 #define SLOPE_TYPE 6
1075 #define DENSITY_TYPE 7
1076
1077 #define DEFAULT_FRACTAL_EXTERIOR_TYPE 1
1078 #define DEFAULT_FRACTAL_INTERIOR_TYPE 0
1079 #define DEFAULT_FRACTAL_EXTERIOR_FACTOR 1
1080 #define DEFAULT_FRACTAL_INTERIOR_FACTOR 1
1081
1082
1083 /*****************************************************************************
1084 *
1085 * Pigment, Tnormal, Finish, Texture & Warps stuff.
1086 *
1087 *****************************************************************************/
1088
1089 #if 0
1090 #pragma mark * Pigment, Normal, Finish, Texture, Warp
1091 #endif
1092
1093 typedef struct Density_file_Struct DENSITY_FILE;
1094 typedef struct Density_file_Data_Struct DENSITY_FILE_DATA;
1095
1096 struct Density_file_Struct
1097 {
1098 int Interpolation;
1099 DENSITY_FILE_DATA *Data;
1100 };
1101
1102 struct Density_file_Data_Struct
1103 {
1104 int References;
1105 char *Name;
1106 size_t Sx, Sy, Sz;
1107 int Type;
1108 union
1109 {
1110 unsigned char *Density8;
1111 unsigned short *Density16;
1112 unsigned int *Density32;
1113 };
1114 };
1115
1116 class ImageData;
1117 class FunctionVM;
1118
1119 struct Crackle_Cache_Struct
1120 {
1121 VECTOR data [125];
1122 bool valid [125];
1123 int lastSeed;
1124 };
1125
1126 struct Pattern_Struct
1127 {
1128 unsigned short Type, Wave_Type, Flags;
1129 int References;
1130 SNGL Frequency, Phase;
1131 SNGL Exponent;
1132 WARP *Warps;
1133 TPATTERN *Next;
1134 BLEND_MAP *Blend_Map;
1135 union {
1136 DENSITY_FILE *Density_File;
1137 ImageData *image;
1138 VECTOR Gradient;
1139 SNGL Agate_Turb_Scale;
1140 short Num_of_Waves;
1141 short Iterations;
1142 short Arms;
1143 struct { SNGL Mortar; VECTOR Size; } Brick;
1144 struct { SNGL Control0, Control1; } Quilted;
1145 struct { DBL Size, UseCoords, Metric; } Facets;
1146 struct { VECTOR Form; DBL Metric; DBL Offset; DBL Dim;
1147 short IsSolid; } Crackle;
1148 struct { VECTOR Slope_Vector, Altit_Vector;
1149 short Slope_Base, Altit_Base; DBL Slope_Len,
1150 Altit_Len; UV_VECT Slope_Mod, Altit_Mod;
1151 bool Point_At; } Slope;
1152 struct { UV_VECT Coord; DBL efactor, ifactor;
1153 unsigned int Iterations; int Exponent;
1154 unsigned char interior_type, exterior_type; } Fractal;
1155 struct { void *Fn; unsigned int Data; FunctionVM *vm; } Function;
1156 struct { unsigned char Side,Tile,Number,Exterior,Interior,Form;} Pavement;
1157 struct { unsigned char Pattern; } Tiling;
1158 PIGMENT *Pigment;
1159 ObjectBase *Object;
1160 } Vals;
1161 };
1162
1163 struct Pigment_Struct : public Pattern_Struct
1164 {
1165 Colour colour; // may have a filter/transmit component
1166 Colour Quick_Colour; // may have a filter/transmit component
1167 };
1168
1169 struct Tnormal_Struct : public Pattern_Struct
1170 {
1171 SNGL Amount;
1172 SNGL Delta; // NK delta
1173 };
1174
1175 struct Texture_Struct : public Pattern_Struct
1176 {
1177 TEXTURE *Next_Material;
1178 PIGMENT *Pigment;
1179 TNORMAL *Tnormal;
1180 FINISH *Finish;
1181 TEXTURE *Materials;
1182 int Num_Of_Mats;
1183
1184 };
1185
1186 struct Finish_Struct
1187 {
1188 SNGL Diffuse, DiffuseBack, RawDiffuse, RawDiffuseBack, Brilliance;
1189 SNGL Specular, Roughness;
1190 SNGL Phong, Phong_Size;
1191 SNGL Irid, Irid_Film_Thickness, Irid_Turb;
1192 SNGL Temp_Caustics, Temp_IOR, Temp_Dispersion, Temp_Refract, Reflect_Exp;
1193 SNGL Crand, Metallic;
1194 RGBColour Ambient, Emission, Reflection_Max, Reflection_Min;
1195 RGBColour SubsurfaceTranslucency, SubsurfaceAnisotropy;
1196 //RGBColour SigmaPrimeS, SigmaA;
1197 SNGL Reflection_Falloff; // Added by MBP 8/27/98
1198 int Reflection_Type; // Added by MBP 9/5/98
1199 SNGL Reflect_Metallic; // MBP
1200 int Conserve_Energy; // added by NK Dec 19 1999
1201 bool UseSubsurface; // whether to use subsurface light transport
1202 };
1203
1204 struct Warps_Struct
1205 {
1206 unsigned short Warp_Type;
1207 WARP *Prev_Warp;
1208 WARP *Next_Warp;
1209 };
1210
1211 struct Turb_Struct : public Warps_Struct
1212 {
1213 VECTOR Turbulence;
1214 int Octaves;
1215 SNGL Lambda, Omega;
1216 };
1217
1218 #define Destroy_Finish(x) if ((x)!=NULL) POV_FREE(x)
1219
1220 typedef struct Material_Struct MATERIAL;
1221
1222 struct Material_Struct
1223 {
1224 TEXTURE *Texture;
1225 TEXTURE * Interior_Texture;
1226 Interior *interior;
1227 };
1228
1229 /*****************************************************************************
1230 *
1231 * Object stuff (see also OBJECTS.H and primitive include files).
1232 *
1233 *****************************************************************************/
1234
1235 #if 0
1236 #pragma mark * Object
1237 #endif
1238
1239 #ifndef DUMP_OBJECT_DATA
1240 #define DUMP_OBJECT_DATA 0
1241 #endif
1242
1243 // TODO FIXME
1244 class SceneThreadData;
1245 #define TraceThreadData SceneThreadData
1246
1247 // These fields are common to all objects.
1248 class LightSource;
1249 class Ray;
1250 class Intersection;
1251
1252 template<typename T>
1253 class RefPool
1254 {
1255 public:
RefPool()1256 RefPool() { }
~RefPool()1257 ~RefPool() { for(typename vector<T*>::iterator i(pool.begin()); i != pool.end(); i++) delete *i; pool.clear(); }
1258
alloc()1259 T *alloc() { if(pool.empty()) return new T(); T *ptr(pool.back()); pool.pop_back(); return ptr; }
release(T * ptr)1260 void release(T *ptr) { pool.push_back(ptr); }
1261 private:
1262 vector<T*> pool;
1263
1264 RefPool(const RefPool&);
1265 RefPool& operator=(RefPool&);
1266 };
1267
1268 template<typename T>
1269 struct RefClearDefault
1270 {
operatorRefClearDefault1271 void operator()(T&) { }
1272 };
1273
1274 template<typename T>
1275 struct RefClearContainer
1276 {
operatorRefClearContainer1277 void operator()(T& p) { p.clear(); }
1278 };
1279
1280 template<typename T, class C = RefClearDefault<T> >
1281 class Ref
1282 {
1283 public:
Ref(RefPool<T> & p)1284 Ref(RefPool<T>& p) : pool(p), ptr(p.alloc()) { }
~Ref()1285 ~Ref() { C c; c(*ptr); pool.release(ptr); }
1286
1287 T& operator*() { return *ptr; }
1288 const T& operator*() const { return *ptr; }
1289
1290 T *operator->() { return ptr; }
1291 const T *operator->() const { return ptr; }
1292 private:
1293 RefPool<T>& pool;
1294 T *ptr;
1295
1296 Ref();
1297 Ref(const Ref&);
1298 Ref& operator=(Ref&);
1299 };
1300
1301 typedef std::stack<Intersection, vector<Intersection> > IStackData;
1302 typedef RefPool<IStackData> IStackPool;
1303 typedef Ref<IStackData> IStack;
1304
1305 struct WeightedTexture
1306 {
1307 COLC weight;
1308 TEXTURE *texture;
1309
WeightedTextureWeightedTexture1310 WeightedTexture(COLC w, TEXTURE *t) :
1311 weight(w), texture(t) { }
1312 };
1313
1314 // TODO: these sizes will need tweaking.
1315 typedef FixedSimpleVector<WeightedTexture, WEIGHTEDTEXTURE_VECTOR_SIZE> WeightedTextureVector;
1316 typedef FixedSimpleVector<Interior *, RAYINTERIOR_VECTOR_SIZE> RayInteriorVector;
1317
1318 class ObjectDebugHelper
1319 {
1320 public:
1321 int Index;
1322 bool IsCopy;
1323 std::string Tag;
1324
ObjectDebugHelper()1325 ObjectDebugHelper() { Index = ObjectIndex++; IsCopy = false; }
1326 ObjectDebugHelper& operator=(const ObjectDebugHelper& src) { Index = ObjectIndex++; IsCopy = true; Tag = src.Tag; return *this; }
1327
1328 std::string& SimpleDesc (std::string& result);
1329 private:
1330 static int ObjectIndex;
ObjectDebugHelper(const ObjectDebugHelper & src)1331 ObjectDebugHelper(const ObjectDebugHelper& src) { Index = ObjectIndex++; IsCopy = true; Tag = src.Tag; }
1332 };
1333
1334 class ObjectBase
1335 {
1336 public:
1337 int Type;
1338 TEXTURE *Texture;
1339 TEXTURE *Interior_Texture;
1340 Interior *interior;
1341 vector<ObjectPtr> Bound;
1342 vector<ObjectPtr> Clip;
1343 vector<LightSource *> LLights;
1344 BBOX BBox;
1345 TRANSFORM *Trans;
1346 TRANSFORM *UV_Trans;
1347 SNGL Ph_Density;
1348 FloatSetting RadiosityImportance;
1349 unsigned int Flags;
1350
1351 #ifdef OBJECT_DEBUG_HELPER
1352 ObjectDebugHelper Debug;
1353 #endif
1354 enum BBoxDirection
1355 {
1356 BBOX_DIR_X0Y0Z0 = 0,
1357 BBOX_DIR_X0Y0Z1 = 1,
1358 BBOX_DIR_X0Y1Z0 = 2,
1359 BBOX_DIR_X0Y1Z1 = 3,
1360 BBOX_DIR_X1Y0Z0 = 4,
1361 BBOX_DIR_X1Y0Z1 = 5,
1362 BBOX_DIR_X1Y1Z0 = 6,
1363 BBOX_DIR_X1Y1Z1 = 7
1364 };
1365
ObjectBase(int t)1366 ObjectBase(int t) :
1367 Type(t),
1368 Texture(NULL), Interior_Texture(NULL), interior(NULL), Trans(NULL), UV_Trans(NULL),
1369 Ph_Density(0), RadiosityImportance(0.0), Flags(0)
1370 {
1371 Make_BBox(BBox, -BOUND_HUGE/2.0, -BOUND_HUGE/2.0, -BOUND_HUGE/2.0, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
1372 }
1373
ObjectBase(int t,ObjectBase & o,bool transplant)1374 ObjectBase(int t, ObjectBase& o, bool transplant) :
1375 Type(t),
1376 Texture(o.Texture), Interior_Texture(o.Interior_Texture), interior(o.interior), Trans(o.Trans), UV_Trans(o.UV_Trans),
1377 Ph_Density(o.Ph_Density), RadiosityImportance(o.RadiosityImportance), Flags(o.Flags),
1378 Bound(o.Bound), Clip(o.Clip), LLights(o.LLights), BBox(o.BBox)
1379 {
1380 if (transplant)
1381 {
1382 o.Texture = NULL;
1383 o.Interior_Texture = NULL;
1384 o.interior = NULL;
1385 o.Trans = NULL;
1386 o.UV_Trans = NULL;
1387 o.Bound.clear();
1388 o.Clip.clear();
1389 o.LLights.clear();
1390 }
1391 }
~ObjectBase()1392 virtual ~ObjectBase() { }
1393
1394 virtual ObjectPtr Copy() = 0;
1395
1396 virtual bool All_Intersections(const Ray&, IStack&, TraceThreadData *) = 0; // could be "const", if it wasn't for isosurface max_gradient estimation stuff
1397 virtual bool Inside(const VECTOR, TraceThreadData *) const = 0;
1398 virtual void Normal(VECTOR, Intersection *, TraceThreadData *) const = 0;
1399 virtual void UVCoord(UV_VECT, const Intersection *, TraceThreadData *) const;
1400 virtual void Translate(const VECTOR, const TRANSFORM *) = 0;
1401 virtual void Rotate(const VECTOR, const TRANSFORM *) = 0;
1402 virtual void Scale(const VECTOR, const TRANSFORM *) = 0;
1403 virtual void Transform(const TRANSFORM *) = 0;
1404 virtual void Invert() = 0;
1405 virtual void Compute_BBox() = 0;
1406 virtual void Determine_Textures(Intersection *, bool, WeightedTextureVector&, TraceThreadData *Thread); // could be "(const Intersection*...) const" if it wasn't for blob specials
1407 virtual bool Intersect_BBox(BBoxDirection, const BBOX_VECT&, const BBOX_VECT&, BBOX_VAL = HUGE_VAL) const;
1408
1409 // optional post-render message dispatcher; will be called upon completion
1410 // of rendering a view. this is the appropriate place to send messages that
1411 // would traditionally have been sent at the end of a render or at object
1412 // destruction - e.g. IsoSurface max_gradient warnings. (object destruction
1413 // isn't the place to do that anymore since a scene may persist between views).
DispatchShutdownMessages(MessageFactory & messageFactory)1414 virtual void DispatchShutdownMessages(MessageFactory& messageFactory) {};
1415
1416 protected:
ObjectBase(const ObjectBase &)1417 explicit ObjectBase(const ObjectBase&) { }
1418 };
1419
1420 /* This is an abstract structure that is never actually used.
1421 All other objects are descendents of this primitive type */
1422
1423 class CompoundObject : public ObjectBase
1424 {
1425 public:
CompoundObject(int t)1426 CompoundObject(int t) : ObjectBase(t) {}
CompoundObject(int t,CompoundObject & o,bool transplant)1427 CompoundObject(int t, CompoundObject& o, bool transplant) : ObjectBase(t, o, transplant), children(o.children) { if (transplant) o.children.clear(); }
1428 vector<ObjectPtr> children;
1429 };
1430
1431 typedef struct BBox_Tree_Struct BBOX_TREE;
1432
1433 struct BBox_Tree_Struct
1434 {
1435 short Infinite; // Flag if node is infinite
1436 short Entries; // Number of sub-nodes in this node
1437 BBOX BBox; // Bounding box of this node
1438 BBOX_TREE **Node; // If node: children; if leaf: element
1439 };
1440
1441 typedef struct Project_Struct PROJECT;
1442 typedef struct Project_Tree_Node_Struct PROJECT_TREE_NODE;
1443
1444 struct Project_Struct
1445 {
1446 int x1, y1, x2, y2;
1447 };
1448
1449 /*
1450 * The following structure represent the bounding box hierarchy in 2d space.
1451 * Because is_leaf, Object and Project are the first elements in both
1452 * structures they can be accessed without knowing at which structure
1453 * a pointer is pointing.
1454 */
1455
1456 struct Project_Tree_Node_Struct
1457 {
1458 unsigned short is_leaf;
1459 BBOX_TREE *Node;
1460 PROJECT Project;
1461 unsigned short Entries;
1462 PROJECT_TREE_NODE **Entry;
1463 };
1464
1465 #if 0
1466 #pragma mark * Light Source
1467 #endif
1468
1469 class LightSource : public CompoundObject
1470 {
1471 public:
1472 size_t index;
1473 RGBColour colour;
1474 VECTOR Direction, Center, Points_At, Axis1, Axis2;
1475 DBL Coeff, Radius, Falloff;
1476 DBL Fade_Distance, Fade_Power;
1477 int Area_Size1, Area_Size2;
1478 int Adaptive_Level;
1479 // ObjectBase *Shadow_Cached_Object;
1480 ObjectBase *Projected_Through_Object;
1481 BLEND_MAP *blend_map;// NK for dispersion
1482 // PROJECT_TREE_NODE *Light_Buffer[6]; // Light buffers for the six general directions in space. [DB 9/94]
1483
1484 unsigned Light_Type : 8;
1485 bool Area_Light : 1;
1486 bool Use_Full_Area_Lighting : 1; // JN2007: Full area lighting
1487 bool Jitter : 1;
1488 bool Orient : 1;
1489 bool Circular : 1;
1490 // bool Track : 1;
1491 bool Parallel : 1;
1492 bool Photon_Area_Light : 1;
1493 bool Media_Attenuation : 1;
1494 bool Media_Interaction : 1;
1495 bool lightGroupLight : 1;
1496
1497 LightSource();
1498 virtual ~LightSource();
1499
1500 virtual ObjectPtr Copy();
1501
1502 virtual bool All_Intersections(const Ray&, IStack&, TraceThreadData *);
1503 virtual bool Inside(const VECTOR, TraceThreadData *) const;
1504 virtual void Normal(VECTOR, Intersection *, TraceThreadData *) const;
1505 virtual void UVCoord(UV_VECT, const Intersection *, TraceThreadData *) const;
1506 virtual void Translate(const VECTOR, const TRANSFORM *);
1507 virtual void Rotate(const VECTOR, const TRANSFORM *);
1508 virtual void Scale(const VECTOR, const TRANSFORM *);
1509 virtual void Transform(const TRANSFORM *);
1510 virtual void Invert();
Compute_BBox()1511 virtual void Compute_BBox() { }
1512 };
1513
1514 typedef unsigned short HF_VAL;
1515
1516
1517 /*****************************************************************************
1518 *
1519 * Intersection stack stuff.
1520 *
1521 *****************************************************************************/
1522
1523 #if 0
1524 #pragma mark * Intersection
1525 #endif
1526
1527 /**
1528 * Ray-object intersection data.
1529 * This class holds various information on a ray-object intersection.
1530 */
1531 class Intersection
1532 {
1533 public:
1534 /// Distance from the intersecting ray's origin.
1535 DBL Depth;
1536 /// Point of the intersection in global coordinate space.
1537 VECTOR IPoint;
1538 /// Unpertubed surface normal at the intersection point.
1539 /// @note This is not necessarily the true geometric surface normal, as it may include fake smoothing.
1540 /// @note This value is invalid if haveNormal is false.
1541 /// @todo We should have two distinct vectors: A true geometric one, and a separate one for faked smoothing.
1542 VECTOR INormal;
1543 /// Perturbed normal vector (set during texture evaluation).
1544 VECTOR PNormal;
1545 /// UV texture coordinate.
1546 UV_VECT Iuv;
1547 /// Intersected object.
1548 ObjectBase *Object;
1549
1550 /// @name Object-Specific Auxiliary Data
1551 /// These members hold information specific to particular object types, typically generated during
1552 /// intersection testing, to be re-used later for normal and/or UV coordinate computation.
1553 /// @note These values may be invalid or meaningless depending on the type of object intersected.
1554 //@{
1555 /// Point of the intersection in local coordinate space (used by Blob)
1556 /// @note This value is invalid if haveLocalIPoint is false.
1557 VECTOR LocalIPoint;
1558 /// Flag to indicate whether INormal was computed during intersection testing (used by HField)
1559 /// @note Objects either always or never computing INormal during intersection testing don't use this flag.
1560 bool haveNormal;
1561 /// Flag to indicate whether LocalIPoint has already been computed.
1562 bool haveLocalIPoint;
1563 /// Generic auxiliary integer data #1 (used by Sor, Prism, Lathe, Cones, Boxes)
1564 int i1;
1565 /// Generic auxiliary integer data #2 (used by Sor, Prism)
1566 int i2;
1567 /// Generic auxiliary float data #1 (used by Prism, Lathe)
1568 DBL d1;
1569 /// Generic auxiliary pointer data (used by Mesh)
1570 const void *Pointer;
1571 //@}
1572
1573 /// Root-level parent CSG object for cutaway textures.
1574 ObjectBase *Csg;
1575
Intersection()1576 Intersection() { Depth = BOUND_HUGE; Object = NULL; Csg = NULL; }
1577
Intersection(DBL d,const VECTOR & v,ObjectBase * o)1578 Intersection(DBL d, const VECTOR& v, ObjectBase *o)
1579 {
1580 Depth = d;
1581 Object = o;
1582 Assign_Vector(IPoint, v);
1583 Assign_UV_Vect(Iuv, v);
1584 haveNormal = false;
1585 haveLocalIPoint = false;
1586 Csg = NULL;
1587 }
1588
Intersection(DBL d,const VECTOR & v,const VECTOR & n,ObjectBase * o)1589 Intersection(DBL d, const VECTOR& v, const VECTOR& n, ObjectBase *o)
1590 {
1591 Depth = d;
1592 Object = o;
1593 Assign_Vector(IPoint, v);
1594 Assign_UV_Vect(Iuv, v);
1595 Assign_Vector(INormal, n);
1596 haveNormal = true;
1597 haveLocalIPoint = false;
1598 Csg = NULL;
1599 }
1600
Intersection(DBL d,const VECTOR & v,const UV_VECT & uv,ObjectBase * o)1601 Intersection(DBL d, const VECTOR& v, const UV_VECT& uv, ObjectBase *o)
1602 {
1603 Depth = d;
1604 Object = o;
1605 Assign_Vector(IPoint, v);
1606 Assign_UV_Vect(Iuv, uv);
1607 haveNormal = false;
1608 haveLocalIPoint = false;
1609 Csg = NULL;
1610 }
1611
Intersection(DBL d,const VECTOR & v,const VECTOR & n,const UV_VECT & uv,ObjectBase * o)1612 Intersection(DBL d, const VECTOR& v, const VECTOR& n, const UV_VECT& uv, ObjectBase *o)
1613 {
1614 Depth = d;
1615 Object = o;
1616 Assign_Vector(IPoint, v);
1617 Assign_Vector(INormal, n);
1618 Assign_UV_Vect(Iuv, uv);
1619 haveNormal = true;
1620 haveLocalIPoint = false;
1621 Csg = NULL;
1622 }
1623
Intersection(DBL d,const VECTOR & v,ObjectBase * o,const void * a)1624 Intersection(DBL d, const VECTOR& v, ObjectBase *o, const void *a)
1625 {
1626 Depth = d;
1627 Object = o;
1628 Pointer = a;
1629 Assign_Vector(IPoint, v);
1630 Assign_UV_Vect(Iuv, v);
1631 haveNormal = false;
1632 haveLocalIPoint = false;
1633 Csg = NULL;
1634 }
1635
Intersection(DBL d,const VECTOR & v,const UV_VECT & uv,ObjectBase * o,const void * a)1636 Intersection(DBL d, const VECTOR& v, const UV_VECT& uv, ObjectBase *o, const void *a)
1637 {
1638 Depth = d;
1639 Object = o;
1640 Pointer = a;
1641 Assign_Vector(IPoint, v);
1642 Assign_UV_Vect(Iuv, uv);
1643 haveNormal = false;
1644 haveLocalIPoint = false;
1645 Csg = NULL;
1646 }
1647
Intersection(DBL d,const VECTOR & v,ObjectBase * o,int a)1648 Intersection(DBL d, const VECTOR& v, ObjectBase *o, int a)
1649 {
1650 Depth = d;
1651 Object = o;
1652 i1 = a;
1653 Assign_Vector(IPoint, v);
1654 haveNormal = false;
1655 haveLocalIPoint = false;
1656 Csg = NULL;
1657 }
1658
Intersection(DBL d,const VECTOR & v,ObjectBase * o,DBL a)1659 Intersection(DBL d, const VECTOR& v, ObjectBase *o, DBL a)
1660 {
1661 Depth = d;
1662 Object = o;
1663 d1 = a;
1664 Assign_Vector(IPoint, v);
1665 haveNormal = false;
1666 haveLocalIPoint = false;
1667 Csg = NULL;
1668 }
1669
Intersection(DBL d,const VECTOR & v,ObjectBase * o,int a,int b)1670 Intersection(DBL d, const VECTOR& v, ObjectBase *o, int a, int b)
1671 {
1672 Depth = d;
1673 Object = o;
1674 i1 = a;
1675 i2 = b;
1676 Assign_Vector(IPoint, v);
1677 haveNormal = false;
1678 haveLocalIPoint = false;
1679 Csg = NULL;
1680 }
1681
Intersection(DBL d,const VECTOR & v,ObjectBase * o,int a,DBL b)1682 Intersection(DBL d, const VECTOR& v, ObjectBase *o, int a, DBL b)
1683 {
1684 Depth = d;
1685 Object = o;
1686 i1 = a;
1687 d1 = b;
1688 Assign_Vector(IPoint, v);
1689 haveNormal = false;
1690 haveLocalIPoint = false;
1691 Csg = NULL;
1692 }
1693
Intersection(DBL d,const VECTOR & v,ObjectBase * o,int a,int b,DBL c)1694 Intersection(DBL d, const VECTOR& v, ObjectBase *o, int a, int b, DBL c)
1695 {
1696 Depth = d;
1697 Object = o;
1698 i1 = a;
1699 i2 = b;
1700 d1 = c;
1701 Assign_Vector(IPoint, v);
1702 haveNormal = false;
1703 haveLocalIPoint = false;
1704 Csg = NULL;
1705 }
1706
~Intersection()1707 ~Intersection() { }
1708 };
1709
1710 /*****************************************************************************
1711 *
1712 * Ray stuff (see also RAY.H).
1713 *
1714 *****************************************************************************/
1715
1716 #if 0
1717 #pragma mark * Ray
1718 #endif
1719
1720 class Ray
1721 {
1722 public:
1723 enum RayType
1724 {
1725 OtherRay = 0,
1726 PrimaryRay = 1,
1727 ReflectionRay = 2,
1728 RefractionRay = 3,
1729 SubsurfaceRay = 4, ///< Ray is shot from just below a surface; very close intersections shall not be suppressed.
1730 };
1731
1732 VECTOR Origin;
1733 VECTOR Direction;
1734
1735 Ray(RayType rt = PrimaryRay, bool shadowTest = false, bool photon = false, bool radiosity = false, bool monochromatic = false, bool pretrace = false);
1736 Ray(const VECTOR ov, const VECTOR dv, RayType rt = PrimaryRay, bool shadowTest = false, bool photon = false, bool radiosity = false, bool monochromatic = false, bool pretrace = false);
1737 ~Ray();
1738
GetOrigin()1739 const VECTOR& GetOrigin() const { return Origin; }
GetDirection()1740 const VECTOR& GetDirection() const { return Direction; }
1741
1742 void AppendInterior(Interior *i);
1743 void AppendInteriors(RayInteriorVector&);
1744 bool RemoveInterior(const Interior *i);
ClearInteriors()1745 void ClearInteriors() { interiors.clear(); }
1746
1747 bool IsInterior(const Interior *i) const;
GetInteriors()1748 const RayInteriorVector& GetInteriors() const { return interiors; }
GetInteriors()1749 RayInteriorVector& GetInteriors() { return interiors; }
1750
1751 void SetSpectralBand(const SpectralBand&);
1752 const SpectralBand& GetSpectralBand() const;
1753
1754 void SetFlags(RayType rt, bool shadowTest = false, bool photon = false, bool radiosity = false, bool monochromatic = false, bool pretrace = false);
1755 void SetFlags(RayType rt, const Ray& other);
1756
IsPrimaryRay()1757 bool IsPrimaryRay() const { return primaryRay; }
IsImageRay()1758 bool IsImageRay() const { return primaryRay || (refractionRay && !reflectionRay); }
IsReflectionRay()1759 bool IsReflectionRay() const { return reflectionRay; }
IsRefractionRay()1760 bool IsRefractionRay() const { return refractionRay; }
IsSubsurfaceRay()1761 bool IsSubsurfaceRay() const { return subsurfaceRay; }
IsShadowTestRay()1762 bool IsShadowTestRay() const { return shadowTestRay; }
IsPhotonRay()1763 bool IsPhotonRay() const { return photonRay; }
IsRadiosityRay()1764 bool IsRadiosityRay() const { return radiosityRay; }
IsMonochromaticRay()1765 bool IsMonochromaticRay() const { return monochromaticRay; }
IsHollowRay()1766 bool IsHollowRay() const { return hollowRay; }
IsPretraceRay()1767 bool IsPretraceRay() const { return pretraceRay; }
1768
Inside(const BBOX & bbox)1769 bool Inside(const BBOX& bbox) const { return Inside_BBox(Origin, bbox); }
1770 private:
1771 RayInteriorVector interiors;
1772 SpectralBand spectralBand;
1773
1774 bool primaryRay : 1;
1775 bool reflectionRay : 1;
1776 bool refractionRay : 1;
1777 bool subsurfaceRay : 1;
1778 bool shadowTestRay : 1;
1779 bool photonRay : 1;
1780 bool radiosityRay : 1;
1781 bool monochromaticRay : 1;
1782 bool hollowRay : 1;
1783 bool pretraceRay : 1;
1784 };
1785
1786 struct RayObjectCondition
1787 {
1788 virtual bool operator()(const Ray& ray, const ObjectBase* object, DBL data) const = 0;
1789 };
1790
1791 struct TrueRayObjectCondition : public RayObjectCondition
1792 {
operatorTrueRayObjectCondition1793 virtual bool operator()(const Ray&, const ObjectBase*, DBL) const { return true; }
1794 };
1795
1796 struct PointObjectCondition
1797 {
1798 virtual bool operator()(const Vector3d& point, const ObjectBase* object) const = 0;
1799 };
1800
1801 struct TruePointObjectCondition : public PointObjectCondition
1802 {
operatorTruePointObjectCondition1803 virtual bool operator()(const Vector3d&, const ObjectBase*) const { return true; }
1804 };
1805
1806
1807 /*****************************************************************************
1808 *
1809 * Frame tracking information
1810 *
1811 *****************************************************************************/
1812
1813 enum FRAMETYPE
1814 {
1815 FT_SINGLE_FRAME,
1816 FT_MULTIPLE_FRAME
1817 };
1818
1819 #define INT_VALUE_UNSET (-1)
1820 #define DBL_VALUE_UNSET (-1.0)
1821
1822 struct FrameSettings
1823 {
1824 FRAMETYPE FrameType;
1825 DBL Clock_Value; // May change between frames of an animation
1826 int FrameNumber; // May change between frames of an animation
1827
1828 int InitialFrame;
1829 DBL InitialClock;
1830
1831 int FinalFrame;
1832 int FrameNumWidth;
1833 DBL FinalClock;
1834
1835 int SubsetStartFrame;
1836 DBL SubsetStartPercent;
1837 int SubsetEndFrame;
1838 DBL SubsetEndPercent;
1839
1840 bool Field_Render_Flag;
1841 bool Odd_Field_Flag;
1842 };
1843
1844
1845 /*****************************************************************************
1846 *
1847 * Miscellaneous stuff.
1848 *
1849 *****************************************************************************/
1850
1851 typedef struct complex_block complex;
1852
1853 struct Chunk_Header_Struct
1854 {
1855 int name;
1856 int size;
1857 };
1858
1859 struct complex_block
1860 {
1861 DBL r, c;
1862 };
1863
1864 struct BYTE_XYZ
1865 {
1866 unsigned char x, y, z;
1867 };
1868
VUnpack(Vector3d & dest_vec,const BYTE_XYZ * pack_vec)1869 inline void VUnpack(Vector3d& dest_vec, const BYTE_XYZ * pack_vec)
1870 {
1871 dest_vec[X] = ((double)pack_vec->x * (1.0 / 255.0)) * 2.0 - 1.0;
1872 dest_vec[Y] = ((double)pack_vec->y * (1.0 / 255.0));
1873 dest_vec[Z] = ((double)pack_vec->z * (1.0 / 255.0)) * 2.0 - 1.0;
1874
1875 dest_vec.normalize(); // already good to about 1%, but we can do better
1876 }
1877
1878 // platform-specific headers should have provided DECLARE_THREAD_LOCAL_PTR.
1879 // if not, we default to using the boost thread_specific_ptr class.
1880 #ifndef DECLARE_THREAD_LOCAL_PTR
1881 #define DECLARE_THREAD_LOCAL_PTR(ptrType, ptrName) boost::thread_specific_ptr<ptrType> ptrName
1882 #define IMPLEMENT_THREAD_LOCAL_PTR(ptrType, ptrName, ptrCleanup) boost::thread_specific_ptr<ptrType> ptrName(ptrCleanup)
1883 #define GET_THREAD_LOCAL_PTR(ptrName) (ptrName.get())
1884 #define SET_THREAD_LOCAL_PTR(ptrName, ptrValue) (ptrName.reset(ptrValue))
1885 #endif
1886
1887 }
1888
1889 #endif
1890