Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/openexr/Imath/ImathFrustum.h
16337 views
1
///////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4
// Digital Ltd. LLC
5
//
6
// All rights reserved.
7
//
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
10
// met:
11
// * Redistributions of source code must retain the above copyright
12
// notice, this list of conditions and the following disclaimer.
13
// * Redistributions in binary form must reproduce the above
14
// copyright notice, this list of conditions and the following disclaimer
15
// in the documentation and/or other materials provided with the
16
// distribution.
17
// * Neither the name of Industrial Light & Magic nor the names of
18
// its contributors may be used to endorse or promote products derived
19
// from this software without specific prior written permission.
20
//
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
//
33
///////////////////////////////////////////////////////////////////////////
34
35
36
37
#ifndef INCLUDED_IMATHFRUSTUM_H
38
#define INCLUDED_IMATHFRUSTUM_H
39
40
41
#include "ImathVec.h"
42
#include "ImathPlane.h"
43
#include "ImathLine.h"
44
#include "ImathMatrix.h"
45
#include "ImathLimits.h"
46
#include "ImathFun.h"
47
#include "IexMathExc.h"
48
49
namespace Imath {
50
51
//
52
// template class Frustum<T>
53
//
54
// The frustum is always located with the eye point at the
55
// origin facing down -Z. This makes the Frustum class
56
// compatable with OpenGL (or anything that assumes a camera
57
// looks down -Z, hence with a right-handed coordinate system)
58
// but not with RenderMan which assumes the camera looks down
59
// +Z. Additional functions are provided for conversion from
60
// and from various camera coordinate spaces.
61
//
62
// nearPlane/farPlane: near/far are keywords used by Microsoft's
63
// compiler, so we use nearPlane/farPlane instead to avoid
64
// issues.
65
66
67
template<class T>
68
class Frustum
69
{
70
public:
71
Frustum();
72
Frustum(const Frustum &);
73
Frustum(T nearPlane, T farPlane, T left, T right, T top, T bottom, bool ortho=false);
74
Frustum(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
75
virtual ~Frustum();
76
77
//--------------------
78
// Assignment operator
79
//--------------------
80
81
const Frustum &operator = (const Frustum &);
82
83
//--------------------
84
// Operators: ==, !=
85
//--------------------
86
87
bool operator == (const Frustum<T> &src) const;
88
bool operator != (const Frustum<T> &src) const;
89
90
//--------------------------------------------------------
91
// Set functions change the entire state of the Frustum
92
//--------------------------------------------------------
93
94
void set(T nearPlane, T farPlane,
95
T left, T right,
96
T top, T bottom,
97
bool ortho=false);
98
99
void set(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
100
101
//------------------------------------------------------
102
// These functions modify an already valid frustum state
103
//------------------------------------------------------
104
105
void modifyNearAndFar(T nearPlane, T farPlane);
106
void setOrthographic(bool);
107
108
//--------------
109
// Access
110
//--------------
111
112
bool orthographic() const { return _orthographic; }
113
T nearPlane() const { return _nearPlane; }
114
T hither() const { return _nearPlane; }
115
T farPlane() const { return _farPlane; }
116
T yon() const { return _farPlane; }
117
T left() const { return _left; }
118
T right() const { return _right; }
119
T bottom() const { return _bottom; }
120
T top() const { return _top; }
121
122
//-----------------------------------------------------------------------
123
// Sets the planes in p to be the six bounding planes of the frustum, in
124
// the following order: top, right, bottom, left, near, far.
125
// Note that the planes have normals that point out of the frustum.
126
// The version of this routine that takes a matrix applies that matrix
127
// to transform the frustum before setting the planes.
128
//-----------------------------------------------------------------------
129
130
void planes(Plane3<T> p[6]);
131
void planes(Plane3<T> p[6], const Matrix44<T> &M);
132
133
//----------------------
134
// Derived Quantities
135
//----------------------
136
137
T fovx() const;
138
T fovy() const;
139
T aspect() const;
140
Matrix44<T> projectionMatrix() const;
141
bool degenerate() const;
142
143
//-----------------------------------------------------------------------
144
// Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1
145
// and -1 <= bottom <= top <= 1) of this Frustum, and returns a new
146
// Frustum whose near clipping-plane window is that rectangle in local
147
// space.
148
//-----------------------------------------------------------------------
149
150
Frustum<T> window(T left, T right, T top, T bottom) const;
151
152
//----------------------------------------------------------
153
// Projection is in screen space / Conversion from Z-Buffer
154
//----------------------------------------------------------
155
156
Line3<T> projectScreenToRay( const Vec2<T> & ) const;
157
Vec2<T> projectPointToScreen( const Vec3<T> & ) const;
158
159
T ZToDepth(long zval, long min, long max) const;
160
T normalizedZToDepth(T zval) const;
161
long DepthToZ(T depth, long zmin, long zmax) const;
162
163
T worldRadius(const Vec3<T> &p, T radius) const;
164
T screenRadius(const Vec3<T> &p, T radius) const;
165
166
167
protected:
168
169
Vec2<T> screenToLocal( const Vec2<T> & ) const;
170
Vec2<T> localToScreen( const Vec2<T> & ) const;
171
172
protected:
173
T _nearPlane;
174
T _farPlane;
175
T _left;
176
T _right;
177
T _top;
178
T _bottom;
179
bool _orthographic;
180
};
181
182
183
template<class T>
184
inline Frustum<T>::Frustum()
185
{
186
set(T (0.1),
187
T (1000.0),
188
T (-1.0),
189
T (1.0),
190
T (1.0),
191
T (-1.0),
192
false);
193
}
194
195
template<class T>
196
inline Frustum<T>::Frustum(const Frustum &f)
197
{
198
*this = f;
199
}
200
201
template<class T>
202
inline Frustum<T>::Frustum(T n, T f, T l, T r, T t, T b, bool o)
203
{
204
set(n,f,l,r,t,b,o);
205
}
206
207
template<class T>
208
inline Frustum<T>::Frustum(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
209
{
210
set(nearPlane,farPlane,fovx,fovy,aspect);
211
}
212
213
template<class T>
214
Frustum<T>::~Frustum()
215
{
216
}
217
218
template<class T>
219
const Frustum<T> &
220
Frustum<T>::operator = (const Frustum &f)
221
{
222
_nearPlane = f._nearPlane;
223
_farPlane = f._farPlane;
224
_left = f._left;
225
_right = f._right;
226
_top = f._top;
227
_bottom = f._bottom;
228
_orthographic = f._orthographic;
229
230
return *this;
231
}
232
233
template <class T>
234
bool
235
Frustum<T>::operator == (const Frustum<T> &src) const
236
{
237
return
238
_nearPlane == src._nearPlane &&
239
_farPlane == src._farPlane &&
240
_left == src._left &&
241
_right == src._right &&
242
_top == src._top &&
243
_bottom == src._bottom &&
244
_orthographic == src._orthographic;
245
}
246
247
template <class T>
248
inline bool
249
Frustum<T>::operator != (const Frustum<T> &src) const
250
{
251
return !operator== (src);
252
}
253
254
template<class T>
255
void Frustum<T>::set(T n, T f, T l, T r, T t, T b, bool o)
256
{
257
_nearPlane = n;
258
_farPlane = f;
259
_left = l;
260
_right = r;
261
_bottom = b;
262
_top = t;
263
_orthographic = o;
264
}
265
266
template<class T>
267
void Frustum<T>::modifyNearAndFar(T n, T f)
268
{
269
if ( _orthographic )
270
{
271
_nearPlane = n;
272
}
273
else
274
{
275
Line3<T> lowerLeft( Vec3<T>(0,0,0), Vec3<T>(_left,_bottom,-_nearPlane) );
276
Line3<T> upperRight( Vec3<T>(0,0,0), Vec3<T>(_right,_top,-_nearPlane) );
277
Plane3<T> nearPlane( Vec3<T>(0,0,-1), n );
278
279
Vec3<T> ll,ur;
280
nearPlane.intersect(lowerLeft,ll);
281
nearPlane.intersect(upperRight,ur);
282
283
_left = ll.x;
284
_right = ur.x;
285
_top = ur.y;
286
_bottom = ll.y;
287
_nearPlane = n;
288
_farPlane = f;
289
}
290
291
_farPlane = f;
292
}
293
294
template<class T>
295
void Frustum<T>::setOrthographic(bool ortho)
296
{
297
_orthographic = ortho;
298
}
299
300
template<class T>
301
void Frustum<T>::set(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
302
{
303
if (fovx != 0 && fovy != 0)
304
throw Iex::ArgExc ("fovx and fovy cannot both be non-zero.");
305
306
const T two = static_cast<T>(2);
307
308
if (fovx != 0)
309
{
310
_right = nearPlane * Math<T>::tan(fovx / two);
311
_left = -_right;
312
_top = ((_right - _left) / aspect) / two;
313
_bottom = -_top;
314
}
315
else
316
{
317
_top = nearPlane * Math<T>::tan(fovy / two);
318
_bottom = -_top;
319
_right = (_top - _bottom) * aspect / two;
320
_left = -_right;
321
}
322
_nearPlane = nearPlane;
323
_farPlane = farPlane;
324
_orthographic = false;
325
}
326
327
template<class T>
328
T Frustum<T>::fovx() const
329
{
330
return Math<T>::atan2(_right,_nearPlane) - Math<T>::atan2(_left,_nearPlane);
331
}
332
333
template<class T>
334
T Frustum<T>::fovy() const
335
{
336
return Math<T>::atan2(_top,_nearPlane) - Math<T>::atan2(_bottom,_nearPlane);
337
}
338
339
template<class T>
340
T Frustum<T>::aspect() const
341
{
342
T rightMinusLeft = _right-_left;
343
T topMinusBottom = _top-_bottom;
344
345
if (abs(topMinusBottom) < 1 &&
346
abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
347
{
348
throw Iex::DivzeroExc ("Bad viewing frustum: "
349
"aspect ratio cannot be computed.");
350
}
351
352
return rightMinusLeft / topMinusBottom;
353
}
354
355
template<class T>
356
Matrix44<T> Frustum<T>::projectionMatrix() const
357
{
358
T rightPlusLeft = _right+_left;
359
T rightMinusLeft = _right-_left;
360
361
T topPlusBottom = _top+_bottom;
362
T topMinusBottom = _top-_bottom;
363
364
T farPlusNear = _farPlane+_nearPlane;
365
T farMinusNear = _farPlane-_nearPlane;
366
367
if ((abs(rightMinusLeft) < 1 &&
368
abs(rightPlusLeft) > limits<T>::max() * abs(rightMinusLeft)) ||
369
(abs(topMinusBottom) < 1 &&
370
abs(topPlusBottom) > limits<T>::max() * abs(topMinusBottom)) ||
371
(abs(farMinusNear) < 1 &&
372
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear)))
373
{
374
throw Iex::DivzeroExc ("Bad viewing frustum: "
375
"projection matrix cannot be computed.");
376
}
377
378
if ( _orthographic )
379
{
380
T tx = -rightPlusLeft / rightMinusLeft;
381
T ty = -topPlusBottom / topMinusBottom;
382
T tz = -farPlusNear / farMinusNear;
383
384
if ((abs(rightMinusLeft) < 1 &&
385
2 > limits<T>::max() * abs(rightMinusLeft)) ||
386
(abs(topMinusBottom) < 1 &&
387
2 > limits<T>::max() * abs(topMinusBottom)) ||
388
(abs(farMinusNear) < 1 &&
389
2 > limits<T>::max() * abs(farMinusNear)))
390
{
391
throw Iex::DivzeroExc ("Bad viewing frustum: "
392
"projection matrix cannot be computed.");
393
}
394
395
T A = 2 / rightMinusLeft;
396
T B = 2 / topMinusBottom;
397
T C = -2 / farMinusNear;
398
399
return Matrix44<T>( A, 0, 0, 0,
400
0, B, 0, 0,
401
0, 0, C, 0,
402
tx, ty, tz, 1.f );
403
}
404
else
405
{
406
T A = rightPlusLeft / rightMinusLeft;
407
T B = topPlusBottom / topMinusBottom;
408
T C = -farPlusNear / farMinusNear;
409
410
T farTimesNear = -2 * _farPlane * _nearPlane;
411
if (abs(farMinusNear) < 1 &&
412
abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
413
{
414
throw Iex::DivzeroExc ("Bad viewing frustum: "
415
"projection matrix cannot be computed.");
416
}
417
418
T D = farTimesNear / farMinusNear;
419
420
T twoTimesNear = 2 * _nearPlane;
421
422
if ((abs(rightMinusLeft) < 1 &&
423
abs(twoTimesNear) > limits<T>::max() * abs(rightMinusLeft)) ||
424
(abs(topMinusBottom) < 1 &&
425
abs(twoTimesNear) > limits<T>::max() * abs(topMinusBottom)))
426
{
427
throw Iex::DivzeroExc ("Bad viewing frustum: "
428
"projection matrix cannot be computed.");
429
}
430
431
T E = twoTimesNear / rightMinusLeft;
432
T F = twoTimesNear / topMinusBottom;
433
434
return Matrix44<T>( E, 0, 0, 0,
435
0, F, 0, 0,
436
A, B, C, -1,
437
0, 0, D, 0 );
438
}
439
}
440
441
template<class T>
442
bool Frustum<T>::degenerate() const
443
{
444
return (_nearPlane == _farPlane) ||
445
(_left == _right) ||
446
(_top == _bottom);
447
}
448
449
template<class T>
450
Frustum<T> Frustum<T>::window(T l, T r, T t, T b) const
451
{
452
// move it to 0->1 space
453
454
Vec2<T> bl = screenToLocal( Vec2<T>(l,b) );
455
Vec2<T> tr = screenToLocal( Vec2<T>(r,t) );
456
457
return Frustum<T>(_nearPlane, _farPlane, bl.x, tr.x, tr.y, bl.y, _orthographic);
458
}
459
460
461
template<class T>
462
Vec2<T> Frustum<T>::screenToLocal(const Vec2<T> &s) const
463
{
464
return Vec2<T>( _left + (_right-_left) * (1.f+s.x) / 2.f,
465
_bottom + (_top-_bottom) * (1.f+s.y) / 2.f );
466
}
467
468
template<class T>
469
Vec2<T> Frustum<T>::localToScreen(const Vec2<T> &p) const
470
{
471
T leftPlusRight = _left - T (2) * p.x + _right;
472
T leftMinusRight = _left-_right;
473
T bottomPlusTop = _bottom - T (2) * p.y + _top;
474
T bottomMinusTop = _bottom-_top;
475
476
if ((abs(leftMinusRight) < T (1) &&
477
abs(leftPlusRight) > limits<T>::max() * abs(leftMinusRight)) ||
478
(abs(bottomMinusTop) < T (1) &&
479
abs(bottomPlusTop) > limits<T>::max() * abs(bottomMinusTop)))
480
{
481
throw Iex::DivzeroExc
482
("Bad viewing frustum: "
483
"local-to-screen transformation cannot be computed");
484
}
485
486
return Vec2<T>( leftPlusRight / leftMinusRight,
487
bottomPlusTop / bottomMinusTop );
488
}
489
490
template<class T>
491
Line3<T> Frustum<T>::projectScreenToRay(const Vec2<T> &p) const
492
{
493
Vec2<T> point = screenToLocal(p);
494
if (orthographic())
495
return Line3<T>( Vec3<T>(point.x,point.y, 0.0),
496
Vec3<T>(point.x,point.y,-_nearPlane));
497
else
498
return Line3<T>( Vec3<T>(0, 0, 0), Vec3<T>(point.x,point.y,-_nearPlane));
499
}
500
501
template<class T>
502
Vec2<T> Frustum<T>::projectPointToScreen(const Vec3<T> &point) const
503
{
504
if (orthographic() || point.z == T (0))
505
return localToScreen( Vec2<T>( point.x, point.y ) );
506
else
507
return localToScreen( Vec2<T>( point.x * _nearPlane / -point.z,
508
point.y * _nearPlane / -point.z ) );
509
}
510
511
template<class T>
512
T Frustum<T>::ZToDepth(long zval,long zmin,long zmax) const
513
{
514
int zdiff = zmax - zmin;
515
516
if (zdiff == 0)
517
{
518
throw Iex::DivzeroExc
519
("Bad call to Frustum::ZToDepth: zmax == zmin");
520
}
521
522
if ( zval > zmax+1 ) zval -= zdiff;
523
524
T fzval = (T(zval) - T(zmin)) / T(zdiff);
525
return normalizedZToDepth(fzval);
526
}
527
528
template<class T>
529
T Frustum<T>::normalizedZToDepth(T zval) const
530
{
531
T Zp = zval * 2.0 - 1;
532
533
if ( _orthographic )
534
{
535
return -(Zp*(_farPlane-_nearPlane) + (_farPlane+_nearPlane))/2;
536
}
537
else
538
{
539
T farTimesNear = 2 * _farPlane * _nearPlane;
540
T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
541
542
if (abs(farMinusNear) < 1 &&
543
abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
544
{
545
throw Iex::DivzeroExc
546
("Frustum::normalizedZToDepth cannot be computed. The "
547
"near and far clipping planes of the viewing frustum "
548
"may be too close to each other");
549
}
550
551
return farTimesNear / farMinusNear;
552
}
553
}
554
555
template<class T>
556
long Frustum<T>::DepthToZ(T depth,long zmin,long zmax) const
557
{
558
long zdiff = zmax - zmin;
559
T farMinusNear = _farPlane-_nearPlane;
560
561
if ( _orthographic )
562
{
563
T farPlusNear = 2*depth + _farPlane + _nearPlane;
564
565
if (abs(farMinusNear) < 1 &&
566
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
567
{
568
throw Iex::DivzeroExc
569
("Bad viewing frustum: near and far clipping planes "
570
"are too close to each other");
571
}
572
573
T Zp = -farPlusNear/farMinusNear;
574
return long(0.5*(Zp+1)*zdiff) + zmin;
575
}
576
else
577
{
578
// Perspective
579
580
T farTimesNear = 2*_farPlane*_nearPlane;
581
if (abs(depth) < 1 &&
582
abs(farTimesNear) > limits<T>::max() * abs(depth))
583
{
584
throw Iex::DivzeroExc
585
("Bad call to DepthToZ function: value of `depth' "
586
"is too small");
587
}
588
589
T farPlusNear = farTimesNear/depth + _farPlane + _nearPlane;
590
if (abs(farMinusNear) < 1 &&
591
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
592
{
593
throw Iex::DivzeroExc
594
("Bad viewing frustum: near and far clipping planes "
595
"are too close to each other");
596
}
597
598
T Zp = farPlusNear/farMinusNear;
599
return long(0.5*(Zp+1)*zdiff) + zmin;
600
}
601
}
602
603
template<class T>
604
T Frustum<T>::screenRadius(const Vec3<T> &p, T radius) const
605
{
606
// Derivation:
607
// Consider X-Z plane.
608
// X coord of projection of p = xp = p.x * (-_nearPlane / p.z)
609
// Let q be p + (radius, 0, 0).
610
// X coord of projection of q = xq = (p.x - radius) * (-_nearPlane / p.z)
611
// X coord of projection of segment from p to q = r = xp - xq
612
// = radius * (-_nearPlane / p.z)
613
// A similar analysis holds in the Y-Z plane.
614
// So r is the quantity we want to return.
615
616
if (abs(p.z) > 1 || abs(-_nearPlane) < limits<T>::max() * abs(p.z))
617
{
618
return radius * (-_nearPlane / p.z);
619
}
620
else
621
{
622
throw Iex::DivzeroExc
623
("Bad call to Frustum::screenRadius: the magnitude of `p' "
624
"is too small");
625
}
626
627
return radius * (-_nearPlane / p.z);
628
}
629
630
template<class T>
631
T Frustum<T>::worldRadius(const Vec3<T> &p, T radius) const
632
{
633
if (abs(-_nearPlane) > 1 || abs(p.z) < limits<T>::max() * abs(-_nearPlane))
634
{
635
return radius * (p.z / -_nearPlane);
636
}
637
else
638
{
639
throw Iex::DivzeroExc
640
("Bad viewing frustum: the near clipping plane is too "
641
"close to zero");
642
}
643
}
644
645
template<class T>
646
void Frustum<T>::planes(Plane3<T> p[6])
647
{
648
//
649
// Plane order: Top, Right, Bottom, Left, Near, Far.
650
// Normals point outwards.
651
//
652
653
if (! _orthographic)
654
{
655
Vec3<T> a( _left, _bottom, -_nearPlane);
656
Vec3<T> b( _left, _top, -_nearPlane);
657
Vec3<T> c( _right, _top, -_nearPlane);
658
Vec3<T> d( _right, _bottom, -_nearPlane);
659
Vec3<T> o(0,0,0);
660
661
p[0].set( o, c, b );
662
p[1].set( o, d, c );
663
p[2].set( o, a, d );
664
p[3].set( o, b, a );
665
}
666
else
667
{
668
p[0].set( Vec3<T>( 0, 1, 0), _top );
669
p[1].set( Vec3<T>( 1, 0, 0), _right );
670
p[2].set( Vec3<T>( 0,-1, 0),-_bottom );
671
p[3].set( Vec3<T>(-1, 0, 0),-_left );
672
}
673
p[4].set( Vec3<T>(0, 0, 1), -_nearPlane );
674
p[5].set( Vec3<T>(0, 0,-1), _farPlane );
675
}
676
677
678
template<class T>
679
void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M)
680
{
681
//
682
// Plane order: Top, Right, Bottom, Left, Near, Far.
683
// Normals point outwards.
684
//
685
686
Vec3<T> a = Vec3<T>( _left, _bottom, -_nearPlane) * M;
687
Vec3<T> b = Vec3<T>( _left, _top, -_nearPlane) * M;
688
Vec3<T> c = Vec3<T>( _right, _top, -_nearPlane) * M;
689
Vec3<T> d = Vec3<T>( _right, _bottom, -_nearPlane) * M;
690
if (! _orthographic)
691
{
692
double s = _farPlane / double(_nearPlane);
693
T farLeft = (T) (s * _left);
694
T farRight = (T) (s * _right);
695
T farTop = (T) (s * _top);
696
T farBottom = (T) (s * _bottom);
697
Vec3<T> e = Vec3<T>( farLeft, farBottom, -_farPlane) * M;
698
Vec3<T> f = Vec3<T>( farLeft, farTop, -_farPlane) * M;
699
Vec3<T> g = Vec3<T>( farRight, farTop, -_farPlane) * M;
700
Vec3<T> o = Vec3<T>(0,0,0) * M;
701
p[0].set( o, c, b );
702
p[1].set( o, d, c );
703
p[2].set( o, a, d );
704
p[3].set( o, b, a );
705
p[4].set( a, d, c );
706
p[5].set( e, f, g );
707
}
708
else
709
{
710
Vec3<T> e = Vec3<T>( _left, _bottom, -_farPlane) * M;
711
Vec3<T> f = Vec3<T>( _left, _top, -_farPlane) * M;
712
Vec3<T> g = Vec3<T>( _right, _top, -_farPlane) * M;
713
Vec3<T> h = Vec3<T>( _right, _bottom, -_farPlane) * M;
714
p[0].set( c, g, f );
715
p[1].set( d, h, g );
716
p[2].set( a, e, h );
717
p[3].set( b, f, e );
718
p[4].set( a, d, c );
719
p[5].set( e, f, g );
720
}
721
}
722
723
typedef Frustum<float> Frustumf;
724
typedef Frustum<double> Frustumd;
725
726
727
} // namespace Imath
728
729
730
#if defined _WIN32 || defined _WIN64
731
#ifdef _redef_near
732
#define near
733
#endif
734
#ifdef _redef_far
735
#define far
736
#endif
737
#endif
738
739
#endif
740
741