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