1 /*******************************************************************************
2 * types.h
3 *
4 * ---------------------------------------------------------------------------
5 * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
6 * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
7 *
8 * POV-Ray is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * POV-Ray is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * ---------------------------------------------------------------------------
21 * POV-Ray is based on the popular DKB raytracer version 2.12.
22 * DKBTrace was originally written by David K. Buck.
23 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
24 * ---------------------------------------------------------------------------
25 * $File: //depot/public/povray/3.x/source/base/types.h $
26 * $Revision: #1 $
27 * $Change: 6069 $
28 * $DateTime: 2013/11/06 11:59:40 $
29 * $Author: chrisc $
30 *******************************************************************************/
31
32 #ifndef POVRAY_BASE_TYPES_H
33 #define POVRAY_BASE_TYPES_H
34
35 #include <algorithm>
36 #include <vector>
37
38 #include "base/configbase.h"
39
40 namespace pov_base
41 {
42
43 // Get minimum/maximum of three values.
44 template<typename T>
max3(T x,T y,T z)45 inline T max3(T x, T y, T z) { return max(x, max(y, z)); }
46 template<typename T>
min3(T x,T y,T z)47 inline T min3(T x, T y, T z) { return min(x, min(y, z)); }
48
49 template<typename T>
50 inline T clip(T val, T minv, T maxv);
51
52 template<typename T>
clip(T val,T minv,T maxv)53 inline T clip(T val, T minv, T maxv)
54 {
55 if(val < minv)
56 return minv;
57 else if(val > maxv)
58 return maxv;
59 else
60 return val;
61 }
62
63 // force a value's precision to a given type, even if computations are normally done with extended precision
64 // (such as GNU Linux on 32-bit CPU, which uses 80-bit extended double precision)
65 // TODO - we might make this code platform-specific
66 template<typename T>
forcePrecision(T val)67 inline T forcePrecision(T val)
68 {
69 volatile T tempVal;
70 tempVal = val;
71 return tempVal;
72 }
73
74 // wrap value into the range [0..upperLimit);
75 // (this is equivalent to fmod() for positive values, but not for negative ones)
76 template<typename T>
wrap(T val,T upperLimit)77 inline T wrap(T val, T upperLimit)
78 {
79 T tempVal = fmod(val, upperLimit);
80 // NB: The range of the value computed by fmod() should be in the range [0..upperLimit) already,
81 // but on some architectures may actually be in the range [0..upperLimit].
82
83 if (tempVal < T(0.0))
84 {
85 // For negative values, fmod() returns a value in the range [-upperLimit..0];
86 // transpose it into the range [0..upperLimit].
87 tempVal += upperLimit;
88 }
89
90 // for negative values (and also for positive values on systems that internally use higher precision
91 // than double for computations) we may end up with value equal to upperLimit (in double precision);
92 // make sure to wrap these special cases to the range [0..upperLimit) as well.
93 if (forcePrecision<double>(tempVal) >= upperLimit)
94 tempVal = T(0.0);
95
96 return tempVal;
97 }
98
99 // round up/down to a multiple of some value
100 template<typename T1, typename T2>
RoundDownToMultiple(T1 x,T2 base)101 inline T1 RoundDownToMultiple(T1 x, T2 base) { return x - (x % base); }
102 template<typename T1, typename T2>
RoundUpToMultiple(T1 x,T2 base)103 inline T1 RoundUpToMultiple(T1 x, T2 base) { return RoundDownToMultiple (x + base - 1, base); }
104
105
106 template<typename T>
107 class GenericRGBColour;
108
109 #define RED_INTENSITY 0.297
110 #define GREEN_INTENSITY 0.589
111 #define BLUE_INTENSITY 0.114
112
113 template<typename T>
114 class GenericColour
115 {
116 public:
117 typedef DBL EXPRESS[5];
118 typedef COLC COLOUR[5];
119 typedef T DATA[5];
120
121 enum
122 {
123 RED = 0,
124 GREEN = 1,
125 BLUE = 2,
126 FILTER = 3,
127 TRANSM = 4
128 };
129
GenericColour()130 GenericColour()
131 {
132 colour[RED] = 0.0;
133 colour[GREEN] = 0.0;
134 colour[BLUE] = 0.0;
135 colour[FILTER] = 0.0;
136 colour[TRANSM] = 0.0;
137 }
138
GenericColour(T grey)139 explicit GenericColour(T grey)
140 {
141 colour[RED] = grey;
142 colour[GREEN] = grey;
143 colour[BLUE] = grey;
144 colour[FILTER] = 0.0;
145 colour[TRANSM] = 0.0;
146 }
147
148 explicit inline GenericColour(const GenericRGBColour<T>& col);
149
150 explicit inline GenericColour(const GenericRGBColour<T>& col, T nfilter, T ntransm);
151
GenericColour(T nred,T ngreen,T nblue)152 GenericColour(T nred, T ngreen, T nblue)
153 {
154 colour[RED] = nred;
155 colour[GREEN] = ngreen;
156 colour[BLUE] = nblue;
157 colour[FILTER] = 0.0;
158 colour[TRANSM] = 0.0;
159 }
160
GenericColour(T nred,T ngreen,T nblue,T nfilter,T ntransm)161 GenericColour(T nred, T ngreen, T nblue, T nfilter, T ntransm)
162 {
163 colour[RED] = nred;
164 colour[GREEN] = ngreen;
165 colour[BLUE] = nblue;
166 colour[FILTER] = nfilter;
167 colour[TRANSM] = ntransm;
168 }
169
GenericColour(const COLOUR col)170 explicit GenericColour(const COLOUR col)
171 {
172 colour[RED] = col[RED];
173 colour[GREEN] = col[GREEN];
174 colour[BLUE] = col[BLUE];
175 colour[FILTER] = col[FILTER];
176 colour[TRANSM] = col[TRANSM];
177 }
178
GenericColour(const EXPRESS col)179 explicit GenericColour(const EXPRESS col)
180 {
181 colour[RED] = col[RED];
182 colour[GREEN] = col[GREEN];
183 colour[BLUE] = col[BLUE];
184 colour[FILTER] = col[FILTER];
185 colour[TRANSM] = col[TRANSM];
186 }
187
GenericColour(const GenericColour & col)188 GenericColour(const GenericColour& col)
189 {
190 colour[RED] = col[RED];
191 colour[GREEN] = col[GREEN];
192 colour[BLUE] = col[BLUE];
193 colour[FILTER] = col[FILTER];
194 colour[TRANSM] = col[TRANSM];
195 }
196
197 template<typename T2>
GenericColour(const GenericColour<T2> & col)198 explicit GenericColour(const GenericColour<T2>& col)
199 {
200 colour[RED] = col[RED];
201 colour[GREEN] = col[GREEN];
202 colour[BLUE] = col[BLUE];
203 colour[FILTER] = col[FILTER];
204 colour[TRANSM] = col[TRANSM];
205 }
206
207 GenericColour(vector<POVMSFloat>::const_iterator& it, bool filter = true, bool transmit = true)
208 {
209 colour[RED] = *it++;
210 colour[GREEN] = *it++;
211 colour[BLUE] = *it++;
212 if (filter)
213 colour[FILTER] = *it++;
214 if (transmit)
215 colour[TRANSM] = *it++;
216 }
217
218 GenericColour& operator=(const GenericColour& col)
219 {
220 colour[RED] = col[RED];
221 colour[GREEN] = col[GREEN];
222 colour[BLUE] = col[BLUE];
223 colour[FILTER] = col[FILTER];
224 colour[TRANSM] = col[TRANSM];
225 return *this;
226 }
227
228 GenericColour& operator=(const T& col)
229 {
230 colour[RED] = col;
231 colour[GREEN] = col;
232 colour[BLUE] = col;
233 colour[FILTER] = 0.0f;
234 colour[TRANSM] = 0.0f;
235 return *this;
236 }
237
238 T operator[](int idx) const { return colour[idx]; }
239 T& operator[](int idx) { return colour[idx]; }
240
241 const DATA& operator*() const { return colour; }
242 DATA& operator*() { return colour; }
243
red()244 T red() const { return colour[RED]; }
red()245 T& red() { return colour[RED]; }
246
green()247 T green() const { return colour[GREEN]; }
green()248 T& green() { return colour[GREEN]; }
249
blue()250 T blue() const { return colour[BLUE]; }
blue()251 T& blue() { return colour[BLUE]; }
252
filter()253 T filter() const { return colour[FILTER]; }
filter()254 T& filter() { return colour[FILTER]; }
255
transm()256 T transm() const { return colour[TRANSM]; }
transm()257 T& transm() { return colour[TRANSM]; }
258
opacity()259 T opacity() const { return 1.0 - colour[FILTER] - colour[TRANSM]; }
260
greyscale()261 T greyscale() const { return RED_INTENSITY * colour[RED] + GREEN_INTENSITY * colour[GREEN] + BLUE_INTENSITY * colour[BLUE]; }
262
263 // TODO: find a more correct way of handling alpha <-> filter/transmit
AtoFT(T alpha,T & f,T & t)264 static void AtoFT(T alpha, T& f, T& t) { f = 0.0f; t = 1.0f - alpha; }
AtoFT(T alpha)265 void AtoFT(T alpha) { colour[FILTER] = 0.0f; colour[TRANSM] = 1.0f - alpha; }
FTtoA(T,T t)266 static T FTtoA(T /*f*/, T t) { return 1.0f - t; }
FTtoA()267 T FTtoA() const { return 1.0f - colour[TRANSM]; }
268
clear()269 void clear()
270 {
271 colour[RED] = 0.0;
272 colour[GREEN] = 0.0;
273 colour[BLUE] = 0.0;
274 colour[FILTER] = 0.0;
275 colour[TRANSM] = 0.0;
276 }
277
set(T grey)278 void set(T grey)
279 {
280 colour[RED] = grey;
281 colour[GREEN] = grey;
282 colour[BLUE] = grey;
283 colour[FILTER] = 0.0;
284 colour[TRANSM] = 0.0;
285 }
286
set(T nred,T ngreen,T nblue)287 void set(T nred, T ngreen, T nblue)
288 {
289 colour[RED] = nred;
290 colour[GREEN] = ngreen;
291 colour[BLUE] = nblue;
292 colour[FILTER] = 0.0;
293 colour[TRANSM] = 0.0;
294 }
295
set(T nred,T ngreen,T nblue,T nfilter,T ntransm)296 void set(T nred, T ngreen, T nblue, T nfilter, T ntransm)
297 {
298 colour[RED] = nred;
299 colour[GREEN] = ngreen;
300 colour[BLUE] = nblue;
301 colour[FILTER] = nfilter;
302 colour[TRANSM] = ntransm;
303 }
304
clip(T minc,T maxc)305 GenericColour clip(T minc, T maxc)
306 {
307 return GenericColour(pov_base::clip<T>(colour[RED], minc, maxc),
308 pov_base::clip<T>(colour[GREEN], minc, maxc),
309 pov_base::clip<T>(colour[BLUE], minc, maxc),
310 pov_base::clip<T>(colour[FILTER], minc, maxc),
311 pov_base::clip<T>(colour[TRANSM], minc, maxc));
312 }
313
314 inline GenericRGBColour<T> rgbTransm() const;
315
316 GenericColour operator+(const GenericColour& b) const
317 {
318 return GenericColour(colour[RED] + b[RED], colour[GREEN] + b[GREEN], colour[BLUE] + b[BLUE], colour[FILTER] + b[FILTER], colour[TRANSM] + b[TRANSM]);
319 }
320
321 GenericColour operator-(const GenericColour& b) const
322 {
323 return GenericColour(colour[RED] - b[RED], colour[GREEN] - b[GREEN], colour[BLUE] - b[BLUE], colour[FILTER] - b[FILTER], colour[TRANSM] - b[TRANSM]);
324 }
325
326 GenericColour operator*(const GenericColour& b) const
327 {
328 return GenericColour(colour[RED] * b[RED], colour[GREEN] * b[GREEN], colour[BLUE] * b[BLUE], colour[FILTER] * b[FILTER], colour[TRANSM] * b[TRANSM]);
329 }
330
331 GenericColour operator/(const GenericColour& b) const
332 {
333 return GenericColour(colour[RED] / b[RED], colour[GREEN] / b[GREEN], colour[BLUE] / b[BLUE], colour[FILTER] / b[FILTER], colour[TRANSM] / b[TRANSM]);
334 }
335
336 GenericColour& operator+=(const GenericColour& b)
337 {
338 colour[RED] += b[RED];
339 colour[GREEN] += b[GREEN];
340 colour[BLUE] += b[BLUE];
341 colour[FILTER] += b[FILTER];
342 colour[TRANSM] += b[TRANSM];
343 return *this;
344 }
345
346 GenericColour& operator-=(const GenericColour& b)
347 {
348 colour[RED] -= b[RED];
349 colour[GREEN] -= b[GREEN];
350 colour[BLUE] -= b[BLUE];
351 colour[FILTER] -= b[FILTER];
352 colour[TRANSM] -= b[TRANSM];
353 return *this;
354 }
355
356 GenericColour& operator*=(const GenericColour& b)
357 {
358 colour[RED] *= b[RED];
359 colour[GREEN] *= b[GREEN];
360 colour[BLUE] *= b[BLUE];
361 colour[FILTER] *= b[FILTER];
362 colour[TRANSM] *= b[TRANSM];
363 return *this;
364 }
365
366 GenericColour& operator/=(const GenericColour& b)
367 {
368 colour[RED] /= b[RED];
369 colour[GREEN] /= b[GREEN];
370 colour[BLUE] /= b[BLUE];
371 colour[FILTER] /= b[FILTER];
372 colour[TRANSM] /= b[TRANSM];
373 return *this;
374 }
375
376 GenericColour operator-() const
377 {
378 return GenericColour(-colour[RED], -colour[GREEN], -colour[BLUE], -colour[FILTER], -colour[TRANSM]);
379 }
380
381 GenericColour operator+(DBL b) const
382 {
383 return GenericColour(colour[RED] + b, colour[GREEN] + b, colour[BLUE] + b, colour[FILTER] + b, colour[TRANSM] + b);
384 }
385
386 GenericColour operator-(DBL b) const
387 {
388 return GenericColour(colour[RED] - b, colour[GREEN] - b, colour[BLUE] - b, colour[FILTER] - b, colour[TRANSM] - b);
389 }
390
391 GenericColour operator*(DBL b) const
392 {
393 return GenericColour(colour[RED] * b, colour[GREEN] * b, colour[BLUE] * b, colour[FILTER] * b, colour[TRANSM] * b);
394 }
395
396 GenericColour operator/(DBL b) const
397 {
398 return GenericColour(colour[RED] / b, colour[GREEN] / b, colour[BLUE] / b, colour[FILTER] / b, colour[TRANSM] / b);
399 }
400
401 GenericColour& operator+=(DBL b)
402 {
403 colour[RED] += b;
404 colour[GREEN] += b;
405 colour[BLUE] += b;
406 colour[FILTER] += b;
407 colour[TRANSM] += b;
408 return *this;
409 }
410
411 GenericColour& operator-=(DBL b)
412 {
413 colour[RED] -= b;
414 colour[GREEN] -= b;
415 colour[BLUE] -= b;
416 colour[FILTER] -= b;
417 colour[TRANSM] -= b;
418 return *this;
419 }
420
421 GenericColour& operator*=(DBL b)
422 {
423 colour[RED] *= b;
424 colour[GREEN] *= b;
425 colour[BLUE] *= b;
426 colour[FILTER] *= b;
427 colour[TRANSM] *= b;
428 return *this;
429 }
430
431 GenericColour& operator/=(DBL b)
432 {
433 colour[RED] /= b;
434 colour[GREEN] /= b;
435 colour[BLUE] /= b;
436 colour[FILTER] /= b;
437 colour[TRANSM] /= b;
438 return *this;
439 }
440 private:
441 DATA colour;
442 };
443
444 template<typename T>
445 class GenericRGBColour
446 {
447 public:
448 typedef DBL VECTOR[3];
449 typedef COLC RGB[3];
450 typedef T DATA[3];
451
452 enum
453 {
454 RED = 0,
455 GREEN = 1,
456 BLUE = 2
457 };
458
GenericRGBColour()459 GenericRGBColour()
460 {
461 colour[RED] = 0.0;
462 colour[GREEN] = 0.0;
463 colour[BLUE] = 0.0;
464 }
465
GenericRGBColour(T grey)466 explicit GenericRGBColour(T grey)
467 {
468 colour[RED] = grey;
469 colour[GREEN] = grey;
470 colour[BLUE] = grey;
471 }
472
GenericRGBColour(T nred,T ngreen,T nblue)473 GenericRGBColour(T nred, T ngreen, T nblue)
474 {
475 colour[RED] = nred;
476 colour[GREEN] = ngreen;
477 colour[BLUE] = nblue;
478 }
479
GenericRGBColour(const RGB col)480 explicit GenericRGBColour(const RGB col)
481 {
482 colour[RED] = col[RED];
483 colour[GREEN] = col[GREEN];
484 colour[BLUE] = col[BLUE];
485 }
486
GenericRGBColour(const VECTOR col)487 explicit GenericRGBColour(const VECTOR col)
488 {
489 colour[RED] = col[RED];
490 colour[GREEN] = col[GREEN];
491 colour[BLUE] = col[BLUE];
492 }
493
GenericRGBColour(const GenericColour<T> & col)494 explicit GenericRGBColour(const GenericColour<T>& col)
495 {
496 colour[RED] = col[RED];
497 colour[GREEN] = col[GREEN];
498 colour[BLUE] = col[BLUE];
499 }
500
GenericRGBColour(const GenericRGBColour & col)501 GenericRGBColour(const GenericRGBColour& col)
502 {
503 colour[RED] = col[RED];
504 colour[GREEN] = col[GREEN];
505 colour[BLUE] = col[BLUE];
506 }
507
508 template<typename T2>
GenericRGBColour(const GenericRGBColour<T2> & col)509 explicit GenericRGBColour(const GenericRGBColour<T2>& col)
510 {
511 colour[RED] = col[RED];
512 colour[GREEN] = col[GREEN];
513 colour[BLUE] = col[BLUE];
514 }
515
GenericRGBColour(vector<POVMSFloat>::const_iterator & it)516 GenericRGBColour(vector<POVMSFloat>::const_iterator& it)
517 {
518 colour[RED] = *it++;
519 colour[GREEN] = *it++;
520 colour[BLUE] = *it++;
521 }
522
523 GenericRGBColour& operator=(const GenericRGBColour& col)
524 {
525 colour[RED] = col[RED];
526 colour[GREEN] = col[GREEN];
527 colour[BLUE] = col[BLUE];
528 return *this;
529 }
530
531 GenericRGBColour& operator=(const T& col)
532 {
533 colour[RED] = col;
534 colour[GREEN] = col;
535 colour[BLUE] = col;
536 return *this;
537 }
538
539 T operator[](int idx) const { return colour[idx]; }
540 T& operator[](int idx) { return colour[idx]; }
541
542 const DATA& operator*() const { return colour; }
543 DATA& operator*() { return colour; }
544
red()545 T red() const { return colour[RED]; }
red()546 T& red() { return colour[RED]; }
547
green()548 T green() const { return colour[GREEN]; }
green()549 T& green() { return colour[GREEN]; }
550
blue()551 T blue() const { return colour[BLUE]; }
blue()552 T& blue() { return colour[BLUE]; }
553
greyscale()554 T greyscale() const { return RED_INTENSITY * colour[RED] + GREEN_INTENSITY * colour[GREEN] + BLUE_INTENSITY * colour[BLUE]; }
555
isZero()556 bool isZero() const { return (colour[RED] == 0) && (colour[GREEN] == 0) && (colour[BLUE] == 0); }
557
clear()558 void clear()
559 {
560 colour[RED] = 0.0;
561 colour[GREEN] = 0.0;
562 colour[BLUE] = 0.0;
563 }
564
set(T grey)565 void set(T grey)
566 {
567 colour[RED] = grey;
568 colour[GREEN] = grey;
569 colour[BLUE] = grey;
570 }
571
set(T nred,T ngreen,T nblue)572 void set(T nred, T ngreen, T nblue)
573 {
574 colour[RED] = nred;
575 colour[GREEN] = ngreen;
576 colour[BLUE] = nblue;
577 }
578
clip(T minc,T maxc)579 GenericRGBColour clip(T minc, T maxc)
580 {
581 return GenericRGBColour(pov_base::clip<T>(colour[RED], minc, maxc),
582 pov_base::clip<T>(colour[GREEN], minc, maxc),
583 pov_base::clip<T>(colour[BLUE], minc, maxc));
584 }
585
586 GenericRGBColour operator+(const GenericRGBColour& b) const
587 {
588 return GenericRGBColour(colour[RED] + b[RED], colour[GREEN] + b[GREEN], colour[BLUE] + b[BLUE]);
589 }
590
591 GenericRGBColour operator-(const GenericRGBColour& b) const
592 {
593 return GenericRGBColour(colour[RED] - b[RED], colour[GREEN] - b[GREEN], colour[BLUE] - b[BLUE]);
594 }
595
596 GenericRGBColour operator*(const GenericRGBColour& b) const
597 {
598 return GenericRGBColour(colour[RED] * b[RED], colour[GREEN] * b[GREEN], colour[BLUE] * b[BLUE]);
599 }
600
601 GenericRGBColour operator/(const GenericRGBColour& b) const
602 {
603 return GenericRGBColour(colour[RED] / b[RED], colour[GREEN] / b[GREEN], colour[BLUE] / b[BLUE]);
604 }
605
606 GenericRGBColour& operator+=(const GenericRGBColour& b)
607 {
608 colour[RED] += b[RED];
609 colour[GREEN] += b[GREEN];
610 colour[BLUE] += b[BLUE];
611 return *this;
612 }
613
614 GenericRGBColour& operator-=(const GenericRGBColour& b)
615 {
616 colour[RED] -= b[RED];
617 colour[GREEN] -= b[GREEN];
618 colour[BLUE] -= b[BLUE];
619 return *this;
620 }
621
622 GenericRGBColour& operator*=(const GenericRGBColour& b)
623 {
624 colour[RED] *= b[RED];
625 colour[GREEN] *= b[GREEN];
626 colour[BLUE] *= b[BLUE];
627 return *this;
628 }
629
630 GenericRGBColour& operator/=(const GenericRGBColour& b)
631 {
632 colour[RED] /= b[RED];
633 colour[GREEN] /= b[GREEN];
634 colour[BLUE] /= b[BLUE];
635 return *this;
636 }
637
638 GenericRGBColour operator-() const
639 {
640 return GenericRGBColour(-colour[RED], -colour[GREEN], -colour[BLUE]);
641 }
642
643 GenericRGBColour operator+(DBL b) const
644 {
645 return GenericRGBColour(colour[RED] + b, colour[GREEN] + b, colour[BLUE] + b);
646 }
647
648 GenericRGBColour operator-(DBL b) const
649 {
650 return GenericRGBColour(colour[RED] - b, colour[GREEN] - b, colour[BLUE] - b);
651 }
652
653 GenericRGBColour operator*(DBL b) const
654 {
655 return GenericRGBColour(colour[RED] * b, colour[GREEN] * b, colour[BLUE] * b);
656 }
657
658 GenericRGBColour operator/(DBL b) const
659 {
660 return GenericRGBColour(colour[RED] / b, colour[GREEN] / b, colour[BLUE] / b);
661 }
662
663 GenericRGBColour& operator+=(DBL b)
664 {
665 colour[RED] += b;
666 colour[GREEN] += b;
667 colour[BLUE] += b;
668 return *this;
669 }
670
671 GenericRGBColour& operator-=(DBL b)
672 {
673 colour[RED] -= b;
674 colour[GREEN] -= b;
675 colour[BLUE] -= b;
676 return *this;
677 }
678
679 GenericRGBColour& operator*=(DBL b)
680 {
681 colour[RED] *= b;
682 colour[GREEN] *= b;
683 colour[BLUE] *= b;
684 return *this;
685 }
686
687 GenericRGBColour& operator/=(DBL b)
688 {
689 colour[RED] /= b;
690 colour[GREEN] /= b;
691 colour[BLUE] /= b;
692 return *this;
693 }
694 private:
695 DATA colour;
696 };
697
698 template<typename T>
GenericColour(const GenericRGBColour<T> & col)699 inline GenericColour<T>::GenericColour(const GenericRGBColour<T>& col)
700 {
701 colour[RED] = col[RED];
702 colour[GREEN] = col[GREEN];
703 colour[BLUE] = col[BLUE];
704 colour[FILTER] = 0.0;
705 colour[TRANSM] = 0.0;
706 }
707
708 template<typename T>
GenericColour(const GenericRGBColour<T> & col,T nfilter,T ntransm)709 inline GenericColour<T>::GenericColour(const GenericRGBColour<T>& col, T nfilter, T ntransm)
710 {
711 colour[RED] = col[RED];
712 colour[GREEN] = col[GREEN];
713 colour[BLUE] = col[BLUE];
714 colour[FILTER] = nfilter;
715 colour[TRANSM] = ntransm;
716 }
717
718 template<typename T>
rgbTransm()719 inline GenericRGBColour<T> GenericColour<T>::rgbTransm() const
720 {
721 return GenericRGBColour<T>( colour[RED] * colour[FILTER] + colour[TRANSM],
722 colour[GREEN] * colour[FILTER] + colour[TRANSM],
723 colour[BLUE] * colour[FILTER] + colour[TRANSM] );
724 }
725
726 template<typename T>
727 inline GenericColour<T> operator* (double a, const GenericColour<T>& b) { return b * a; }
728 template<typename T>
729 inline GenericRGBColour<T> operator* (double a, const GenericRGBColour<T>& b) { return b * a; }
730
731 template<typename T>
colourDistance(const GenericColour<T> & a,const GenericColour<T> & b)732 inline double colourDistance (const GenericColour<T>& a, const GenericColour<T>& b) { return fabs(a.red() - b.red()) + fabs(a.green() - b.green()) + fabs(a.blue() - b.blue()); }
733 template<typename T>
colourDistance(const GenericRGBColour<T> & a,const GenericRGBColour<T> & b)734 inline double colourDistance (const GenericRGBColour<T>& a, const GenericRGBColour<T>& b) { return fabs(a.red() - b.red()) + fabs(a.green() - b.green()) + fabs(a.blue() - b.blue()); }
735
736 template<typename T>
Sqr(const GenericRGBColour<T> & a)737 inline GenericRGBColour<T> Sqr(const GenericRGBColour<T>& a) { return a * a; }
738 template<typename T>
exp(const GenericRGBColour<T> & a)739 inline GenericRGBColour<T> exp(const GenericRGBColour<T>& a) { return GenericRGBColour<T>(::exp(a.red()), ::exp(a.green()), ::exp(a.blue())); }
740 template<typename T>
sqrt(const GenericRGBColour<T> & a)741 inline GenericRGBColour<T> sqrt(const GenericRGBColour<T>& a) { return GenericRGBColour<T>(::sqrt(a.red()), ::sqrt(a.green()), ::sqrt(a.blue())); }
742
743 typedef GenericColour<COLC> Colour;
744 typedef GenericColour<DBL> DblColour;
745 typedef GenericRGBColour<COLC> RGBColour;
746 typedef GenericRGBColour<DBL> DblRGBColour;
747
748 struct POVRect
749 {
750 unsigned int top;
751 unsigned int left;
752 unsigned int bottom;
753 unsigned int right;
754
POVRectPOVRect755 POVRect() : top(0), left(0), bottom(0), right(0) { }
POVRectPOVRect756 POVRect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) :
757 top(y1), left(x1), bottom(y2), right(x2) { }
758
GetAreaPOVRect759 unsigned int GetArea() const { return ((bottom - top + 1) * (right - left + 1)); }
GetWidthPOVRect760 unsigned int GetWidth() const { return (right - left + 1); }
GetHeightPOVRect761 unsigned int GetHeight() const { return (bottom - top + 1); }
762 };
763
764 class GenericSetting
765 {
766 public:
set(set)767 explicit GenericSetting(bool set = false): set(set) {}
Unset()768 void Unset() { set = false; }
isSet()769 bool isSet() const { return set; }
770 protected:
771 bool set;
772 };
773
774 class FloatSetting : public GenericSetting
775 {
776 public:
data(data)777 explicit FloatSetting(double data = 0.0, bool set = false): data(data), GenericSetting(set) {}
778 double operator=(double b) { data = b; set = true; return data; }
779 operator double() const { return data; }
operator()780 double operator()(double def) const { if (set) return data; else return def; }
781 private:
782 double data;
783 };
784
785 }
786
787 #endif // POVRAY_BASE_TYPES_H
788