opennurbs_viewport.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 ////////////////////////////////////////////////////////////////
18 //
19 // defines ON_Viewport
20 //
21 ////////////////////////////////////////////////////////////////
22 
23 #if !defined(OPENNURBS_VIEWPORT_INC_)
24 #define OPENNURBS_VIEWPORT_INC_
25 
26 ///////////////////////////////////////////////////////////////////////////////
27 // Class ON_Viewport
28 //
29 // This object represents a viewing frustum
30 ///////////////////////////////////////////////////////////////////////////////
31 class ON_CLASS ON_Viewport : public ON_Geometry
32 {
33  ON_OBJECT_DECLARE( ON_Viewport );
34 public:
35 
36  static const double DefaultNearDist; // 0.005
37  static const double DefaultFarDist; // 1000.0
38  static const double DefaultMinNearDist; // 0.0001
39  static const double DefaultMinNearOverFar; // 0.0001
40 
41  static const ON_3dPoint DefaultCameraLocation; // (0.0,0.0,100.0)
42  static const ON_3dVector Default3dCameraDirection; // (-0.43301270189221932338186158537647,0.75,-0.5)
43 
44  /*
45  Description:
46  A Y-up parallel projection looking at the origin of the XYplane.
47  up = ON_3dVector::Yaxis,
48  dir = -ON_3dVector::Zaxis
49  */
50  static const ON_Viewport DefaultTopViewYUp;
51 
52  /*
53  Description:
54  A Z-up perspective projection looking down on the origin of the XY plane.
55  up = ON_3dVector::Zaxis,
56  dir = ON_3dVector:Default3dCameraDirection
57  */
58  static const ON_Viewport DefaultPerspectiveViewZUp;
59 
60  // Construction
61  // Default constructor creates a copy of ON_Viewport::DefaultTopViewYUp;
62  ON_Viewport() = default;
63  ~ON_Viewport() = default;
64  ON_Viewport( const ON_Viewport& ) = default;
65  ON_Viewport& operator=( const ON_Viewport& ) = default;
66 
67  /*
68  Returns:
69  A sha1 hash of all the settings that effect view projection matrices.
70  view projection, camera location, camera X,Y,Z frame, frustum, port.
71  If two ON_Viewport classes have identical values ViewProjectionContentHash(),
72  then they will have identical view projection matrices and generate identical
73  images from the same model content.
74  */
75  ON_SHA1_Hash ViewProjectionContentHash() const;
76 
77  /*
78  Returns:
79  candidate_point.IsValid()
80  && candidate_point.MaximumCoordinate() < ON_NONSENSE_WORLD_COORDINATE_VALUE;
81  */
82  static bool IsValidCameraLocation(
83  ON_3dPoint candidate_point
84  );
85 
86  /*
87  Returns:
88  candidate_vector.IsValid()
89  && candidate_vector.MaximumCoordinate() < ON_NONSENSE_WORLD_COORDINATE_VALUE
90  && candidate_vector.MaximumCoordinate() > ON_ZERO_TOLERANCE
91  ;
92  */
93  static bool IsValidCameraUpOrDirection(
94  ON_3dVector candidate_vector
95  );
96 
97  /*
98  Returns:
99  True if camera up, direction, X, Y, and Z are valid.
100  */
101  bool IsValidCameraFrame() const;
102 
103  /*
104  Returns:
105  True if camera location is valid and camera up, direction, X, Y, and Z are valid.
106  */
107  bool IsValidCamera() const;
108 
109  /*
110  Returns:
111  True if camera frustum is valid.
112  */
113  bool IsValidFrustum() const;
114 
115  // ON_Object overrides //////////////////////////////////////////////////////
116  //
117  bool IsValid( class ON_TextLog* text_log = nullptr ) const override;
118 
119  // Description:
120  // Dumps debugging text description to a text log.
121  //
122  // Parameters:
123  // dump_target - [in] text log
124  //
125  // Remarks:
126  // This overrides the virtual ON_Object::Dump() function.
127  void Dump(
128  ON_TextLog& // dump_target
129  ) const override;
130 
131  // Description:
132  // Writes ON_Viewport defintion from a binary archive.
133  //
134  // Parameters:
135  // binary_archive - [in] open binary archive
136  //
137  // Returns:
138  // true if successful.
139  //
140  // Remarks:
141  // This overrides the virtual ON_Object::Write() function.
142  bool Write(
143  ON_BinaryArchive& // binary_archive
144  ) const override;
145 
146 
147  // Description:
148  // Reads ON_Viewport defintion from a binary archive.
149  //
150  // Parameters:
151  // binary_archive - [in] open binary archive
152  //
153  // Returns:
154  // true if successful.
155  //
156  // Remarks:
157  // This overrides the virtual ON_Object::Read() function.
158  bool Read(
159  ON_BinaryArchive& // binary_archive
160  ) override;
161 
162 
163  // ON_Geometry overrides //////////////////////////////////////////////////////
164  //
165 
166  // Description:
167  // The dimension of a camera view frustum is 3.
168  //
169  // Returns:
170  // 3
171  //
172  // Remarks:
173  // This is virtual ON_Geometry function.
174  int Dimension() const override;
175 
176  // virtual ON_Geometry GetBBox override
177  bool GetBBox( double* boxmin, double* boxmax, bool bGrowBox = false ) const override;
178 
179  // Description:
180  // Transforms the view camera location, direction, and up.
181  //
182  // Parameters:
183  // xform - [in] transformation to apply to camera.
184  //
185  // Returns:
186  // @untitled table
187  // true Valid camera was transformed.
188  // false Invalid camera, frustum, or transformation.
189  //
190  // Remarks:
191  // This overrides the virtual ON_Geometry::Transform() function.
192  bool Transform(
193  const ON_Xform& // xform
194  ) override;
195 
196  // Interface /////////////////////////////////////////////////////////////////
197  //
198 
199  /*
200  */
201  ON_DEPRECATED_MSG("Use = ON_Viewport::DefaultTopViewYUp")
202  void Initialize();
203 
204  ON::view_projection Projection() const;
205 
206  /*
207  Description:
208  Unconditionally set the projection.
209  Parameters:
210  projection - [in]
211  See Also:
212  ON_Viewport::SetParallelProjection
213  ON_Viewport::SetPerpectiveProjection
214  ON_Viewport::SetTwoPointPerspectiveProjection
215  */
216  bool SetProjection( ON::view_projection projection );
217 
218  /*
219  Description:
220  Use this function to change projections of valid viewports
221  from persective to parallel. It will make common additional
222  adjustments to the frustum so the resulting views are similar.
223  The camera location and direction will not be changed.
224  Parameters:
225  bSymmetricFrustum - [in]
226  True if you want the resulting frustum to be symmetric.
227  Remarks:
228  If the current projection is parallel and bSymmetricFrustum,
229  FrustumIsLeftRightSymmetric() and FrustumIsTopBottomSymmetric()
230  are all equal, then no changes are made and true is returned.
231  */
232  bool ChangeToParallelProjection( bool bSymmetricFrustum );
233 
234  /*
235  Description:
236  Use this function to change projections of valid viewports
237  from parallel to perspective. It will make common additional
238  adjustments to the frustum and camera location so the resulting
239  views are similar. The camera direction and target point are
240  not be changed.
241  Parameters:
242  target_distance - [in]
243  If ON_UNSET_VALUE this parameter is ignored. Otherwise
244  it must be > 0 and indicates which plane in the current
245  view frustum should be perserved.
246  bSymmetricFrustum - [in]
247  True if you want the resulting frustum to be symmetric.
248  lens_length - [in] (pass 50.0 when in doubt)
249  35 mm lens length to use when changing from parallel
250  to perspective projections. If the current projection
251  is perspective or lens_length is <= 0.0,
252  then this parameter is ignored.
253  Remarks:
254  If the current projection is perspective and bSymmetricFrustum,
255  FrustumIsLeftRightSymmetric() and FrustumIsTopBottomSymmetric()
256  are all equal, then no changes are made and true is returned.
257  */
258  bool ChangeToPerspectiveProjection(
259  double target_distance,
260  bool bSymmetricFrustum,
261  double lens_length
262  );
263 
264  /*
265  Description:
266  Use this function to change projections of valid viewports
267  to a two point perspective. It will make common additional
268  adjustments to the frustum and camera location and direction
269  so the resulting views are similar.
270  Parameters:
271  target_distance - [in]
272  If ON_UNSET_VALUE this parameter is ignored. Otherwise
273  it must be > 0 and indicates which plane in the current
274  view frustum should be perserved.
275  up - [in]
276  This direction will be the locked up direction. Pass
277  ON_3dVector::ZeroVector if you want to use the world axis
278  direction that is closest to the current up direction.
279  Pass CameraY() if you want to preserve the current up direction.
280  lens_length - [in] (pass 50.0 when in doubt)
281  35 mm lens length to use when changing from parallel
282  to perspective projections. If the current projection
283  is perspective or lens_length is <= 0.0,
284  then this parameter is ignored.
285  Remarks:
286  If the current projection is perspective and
287  FrustumIsLeftRightSymmetric() is true and
288  FrustumIsTopBottomSymmetric() is false, then no changes are
289  made and true is returned.
290  */
291  bool ChangeToTwoPointPerspectiveProjection(
292  double target_distance,
293  ON_3dVector up,
294  double lens_length
295  );
296 
297  /*
298  Returns:
299  True if the projection is ON::perspective_view.
300  */
301  bool IsPerspectiveProjection() const;
302 
303  /*
304  Returns
305  IsPerspectiveProjection()
306  && CameraUpIsLocked()
307  && FrustumIsLeftRightSymmetric
308  && !FrustumIsTopBottomSymmetric
309  */
310  bool IsTwoPointPerspectiveProjection() const;
311 
312  /*
313  Returns:
314  True if the projection is ON::parallel_view.
315  */
316  bool IsParallelProjection() const;
317 
318  // These return true if the current direction and up are not zero and not
319  // parallel so the camera position is well defined.
320  bool SetCameraLocation( const ON_3dPoint& );
321  bool SetCameraDirection( const ON_3dVector& );
322  bool SetCameraUp( const ON_3dVector& );
323 
324  ON_3dPoint CameraLocation() const;
325  ON_3dVector CameraDirection() const;
326  ON_3dVector CameraUp() const;
327 
328  /*
329  Description:
330  Copy camera location, up, direction and frame from source_viewport.
331  Parameters:
332  source_viewport - [in]
333  camera location to copy
334  bBreakLocks - [in]
335  If true, any locked frustum settings will be unlocked.
336  */
337  bool SetCamera(
338  const ON_Viewport& source_viewport,
339  bool bBreakLocks
340  );
341 
342  bool CameraLocationIsLocked() const;
343  bool CameraDirectionIsLocked() const;
344  bool CameraUpIsLocked() const;
345  bool FrustumIsLeftRightSymmetric() const;
346  bool FrustumIsTopBottomSymmetric() const;
347 
348  void SetCameraLocationLock( bool bLockCameraLocation );
349  void SetCameraDirectionLock( bool bLockCameraDirection ) ;
350  void SetCameraUpLock( bool bLockCameraUp );
351  void SetFrustumLeftRightSymmetry( bool bForceLeftRightSymmetry );
352  void SetFrustumTopBottomSymmetry( bool bForceTopBottomSymmetry );
353  void UnlockCamera(); // sets all camera locks to false
354  void UnlockFrustumSymmetry(); // sets all frustum symmetry locks to false
355 
356  // returns true if current camera orientation is valid
357  bool GetCameraFrame(
358  double*, // CameraLocation[3]
359  double*, // CameraX[3]
360  double*, // CameraY[3]
361  double* // CameraZ[3]
362  ) const;
363 
364  // these do not check for a valid camera orientation
365  ON_3dVector CameraX() const; // unit to right vector
366  ON_3dVector CameraY() const; // unit up vector
367  ON_3dVector CameraZ() const; // unit vector in -CameraDirection
368 
369 
370  bool IsCameraFrameWorldPlan(
371  // Returns true if the camera direction = some world axis.
372  // The indices report which axes are used. For a "twisted"
373  // plan view it is possible to have zero x and y indices.
374  // This function returns true if and only if the "z" index
375  // is non-zero.
376  //
377  // Indices are +/-1 = world +/-x, +/-2 = world +/-y, +/-3 = world +/-z,
378  int*, // if true and plan is axis aligned, view x index, else 0
379  int*, // if true and plan is axis aligned, view y index, else 0
380  int* // if true, view z index, else 0
381  );
382 
383  bool GetCameraExtents(
384  // returns bounding box in camera coordinates - this is useful information
385  // for setting view frustrums to include the point list
386  int, // count = number of 3d points
387  int, // stride = number of doubles to skip between points (>=3)
388  const double*, // 3d points in world coordinates
389  ON_BoundingBox& cambbox, // bounding box in camera coordinates
390  int bGrowBox = false // set to true if you want to enlarge an existing camera coordinate box
391  ) const;
392 
393  bool GetCameraExtents(
394  // returns bounding box in camera coordinates - this is useful information
395  // for setting view frustrums to include the point list
396  const ON_BoundingBox&, // world coordinate bounding box
397  ON_BoundingBox& cambbox, // bounding box in camera coordinates
398  int bGrowBox = false // set to true if you want to enlarge an existing camera coordinate box
399  ) const;
400 
401  bool GetCameraExtents(
402  // returns bounding box in camera coordinates - this is useful information
403  // for setting view frustrums to include the point list
404  ON_3dPoint&, // world coordinate bounding sphere center
405  double, // world coordinate bounding sphere radius
406  ON_BoundingBox& cambox, // bounding box in camera coordinates
407  int bGrowBox = false // set to true if you want to enlarge an existing camera coordinate box
408  ) const;
409 
410  /*
411  Description:
412  Set the view frustum. If FrustumSymmetryIsLocked() is true
413  and left != -right or bottom != -top, then they will be
414  adjusted so the resulting frustum is symmetric.
415  */
416  bool SetFrustum(
417  double left, //
418  double right, // ( left < right )
419  double bottom, //
420  double top, // ( bottom < top )
421  double near_dist, //
422  double far_dist // ( 0 < near_dist < far_dist ) // ignored by Rhino version 1.0
423  );
424  bool GetFrustum(
425  double* left, //
426  double* right, // (left < right)
427  double* bottom, //
428  double* top, // (bottom < top)
429  double* near_dist = nullptr, //
430  double* far_dist = nullptr // (0 < near_dist < far_dist)
431  ) const;
432 
433 
434  /*
435  Description:
436  Copy frustum information from source_viewport.
437  Parameters:
438  source_viewport - [in]
439  bBreakLocks - [in]
440  If true, any locked frustum settings will be unlocked.
441  */
442  bool SetFrustum(
443  const ON_Viewport& source_viewport,
444  bool bBreakLocks
445  );
446 
447 
448  // SetFrustumAspect() changes the larger of the frustum's widht/height
449  // so that the resulting value of width/height matches the requested
450  // aspect. The camera angle is not changed. If you change the shape
451  // of the view port with a call SetScreenPort(), then you generally
452  // want to call SetFrustumAspect() with the value returned by
453  // GetScreenPortAspect().
454  bool SetFrustumAspect( double );
455 
456  // Returns frustum's width/height
457  bool GetFrustumAspect( double& ) const;
458 
459  // Returns world coordinates of frustum's center
460  bool GetFrustumCenter( double* ) const;
461 
462  // The near clipping plane stored in the Rhino 1.0 file is frequently very
463  // small and useless for high quality z-buffer based rendering. The far
464  // clipping value is not stored in the file. Use these functions to set
465  // the frustum's near and far clipping planes to appropriate values.
466  double FrustumLeft() const;
467  double FrustumRight() const;
468  double FrustumBottom() const;
469  double FrustumTop() const;
470  double FrustumNear() const;
471  double FrustumFar() const;
472 
473  /*
474  Returns:
475  frustum right - frustum left
476  */
477  double FrustumWidth() const; // right - left
478 
479  /*
480  Returns:
481  frustum right - frustum left
482  */
483  double FrustumHeight() const; // top - bottom
484 
485  /*
486  Returns:
487  Minimum of fabs(FrustumWidth()) and fabs(FrustumHeight())
488  */
489  double FrustumMinimumDiameter() const;
490 
491  /*
492  Returns:
493  Maximum of fabs(FrustumWidth()) and fabs(FrustumHeight())
494  */
495  double FrustumMaximumDiameter() const;
496 
497 
498  bool SetFrustumNearFar(
499  const double* bboxmin, // 3d bounding box min
500  const double* bboxmax // 3d bounding box max
501  );
502  bool SetFrustumNearFar(
503  const double* center, // 3d bounding sphere center
504  double radius // 3d bounding sphere radius
505  );
506  bool SetFrustumNearFar(
507  double near_dist, // ( > 0 )
508  double far_dist //
509  );
510 
511  /*
512  Description:
513  If needed, adjust the current frustum so it has the
514  specified symmetries and adjust the camera location
515  so the target plane remains visible.
516  Parameters:
517  bLeftRightSymmetric - [in]
518  If true, the frustum will be adjusted so left = -right.
519  bTopBottomSymmetric - [in]
520  If true, the frustum will be adjusted so top = -bottom.
521  target_distance - [in]
522  If projection is not perspective or target_distance
523  is ON_UNSET_VALUE, this this parameter is ignored.
524  If the projection is perspective and target_distance
525  is not ON_UNSET_VALUE, then it must be > 0.0 and
526  it is used to determine which plane in the old
527  frustum will appear unchanged in the new frustum.
528  bool
529  Returns true if the returned viewport has a frustum
530  with the specified symmetries.
531  */
532  bool ChangeToSymmetricFrustum(
533  bool bLeftRightSymmetric,
534  bool bTopBottomSymmetric,
535  double target_distance
536  );
537 
538  /*
539  Description:
540  Get near and far clipping distances of a point
541  Parameters:
542  point - [in]
543  near_dist - [out]
544  near distance of the point (can be < 0)
545  far_dist - [out]
546  far distance of the point (can be equal to near_dist)
547  bGrowNearFar - [in]
548  If true and input values of near_dist and far_dist
549  are not ON_UNSET_VALUE, the near_dist and far_dist
550  are enlarged to include bbox.
551  Returns:
552  True if the point is ing the view frustum and
553  near_dist/far_dist were set.
554  False if the bounding box does not intesect the
555  view frustum.
556  */
557  bool GetPointDepth(
558  ON_3dPoint point,
559  double* near_dist,
560  double* far_dist,
561  bool bGrowNearFar=false
562  ) const;
563 
564  /*
565  Description:
566  Get the view plane depth of a point
567  Parameters:
568  point - [in]
569  view_plane_depth - [out]
570  positive values are in front of the camera and negative
571  values are behind the camera.
572  If 0 <= point_depth < FrustumNear(), the point's view
573  plane is between the camera and the frustum's near plane.
574  If point_depth > FrustumFar(), the point's view
575  plane is farther from the camera and the frustum's far plane.
576  Returns:
577  True if the point is ing the view frustum and
578  near_dist/far_dist were set.
579  False if the bounding box does not intesect the
580  view frustum.
581  */
582  bool GetPointDepth(
583  ON_3dPoint point,
584  double* view_plane_depth
585  ) const;
586 
587  /*
588  Description:
589  Get near and far clipping distances of a bounding box.
590  Parameters:
591  bbox - [in]
592  bounding box
593  near_dist - [out]
594  near distance of the box
595  This value can be zero or negative when the camera
596  location is inside bbox.
597  far_dist - [out]
598  far distance of the box
599  This value can be equal to near_dist, zero or negative
600  when the camera location is in front of the bounding box.
601  bGrowNearFar - [in]
602  If true and input values of near_dist and far_dist
603  are not ON_UNSET_VALUE, the near_dist and far_dist
604  are enlarged to include bbox.
605  Returns:
606  True if the bounding box intersects the view frustum and
607  near_dist/far_dist were set.
608  False if the bounding box does not intesect the view frustum.
609  Remarks:
610  This function ignores the current value of the viewport's
611  near and far settings. If the viewport is a perspective
612  projection, the it intersects the semi infinite frustum
613  volume with the bounding box and returns the near and far
614  distances of the intersection. If the viewport is a parallel
615  projection, it instersects the infinte view region with the
616  bounding box and returns the near and far distances of the
617  projection.
618  */
619  bool GetBoundingBoxDepth(
620  ON_BoundingBox bbox,
621  double* near_dist,
622  double* far_dist,
623  bool bGrowNearFar=false
624  ) const;
625 
626  /*
627  Description:
628  Get near and far clipping distances of a bounding box.
629  Parameters:
630  bbox - [in]
631  bounding box
632  bbox_xform - [in]
633  If not nullptr, this transformation to applied to the corners of bbox.
634  It should have positive determinant for the results to be meaningful.
635  Typically bbox_xform is used to pass an instance reference transformation.
636  near_dist - [out]
637  near distance of the box
638  This value can be zero or negative when the camera
639  location is inside bbox.
640  far_dist - [out]
641  far distance of the box
642  This value can be equal to near_dist, zero or negative
643  when the camera location is in front of the bounding box.
644  bGrowNearFar - [in]
645  If true and input values of near_dist and far_dist
646  are not ON_UNSET_VALUE, the near_dist and far_dist
647  are enlarged to include bbox.
648  Returns:
649  0: The bounding box does not intersectthe view frustum.
650  1: A proper subset of the bounding box is inside the view frustum
651  and near_dist/far_dist were set.
652  2: The entire bounding box is inside the view frustum
653  and near_dist/far_dist were set.
654  Remarks:
655  This function ignores the current value of the viewport's
656  near and far settings. If the viewport is a perspective
657  projection, the it intersects the semi infinite frustum
658  volume with the bounding box and returns the near and far
659  distances of the intersection. If the viewport is a parallel
660  projection, it instersects the infinte view region with the
661  bounding box and returns the near and far distances of the
662  projection.
663  */
664  int GetBoundingBoxDepth(
665  ON_BoundingBox bbox,
666  const ON_Xform* bbox_xform,
667  double* near_dist,
668  double* far_dist,
669  bool bGrowNearFar
670  ) const;
671 
672  /*
673  Description:
674  Get the normalized extents of the smallest rectangle that
675  contains the intersection of bbox and the view's frustum.
676  Parameters:
677  bbox - [in]
678  bounding box
679  x_extents - [out]
680  y_extents - [out]
681  0 <= x_extents[0] <= x_extents[1] <= 1.0
682  0 <= y_extents[0] <= y_extents[1] <= 1.0
683  If true is returned, then intersection of the bbox
684  and the view's frustum is not empty and the bounding
685  rectangle of the projection of the intersection set
686  is returned in x_range and y_range. The returned values
687  are normalized image extents. For example, if
688  x_extents[0] = 0.0, x_extents[1] = 0.25, y_extents[0] = 0.75
689  and y_extents[1] = 1.0, then the portion of bbox in the
690  view's frustum would project to the upper left corner
691  of the image.
692  Returns:
693  True if the bounding box intersects the view frustum and
694  x_range and y_range were set.
695  False if the bounding box does not intersect the view
696  frustum.
697  Remarks:
698  This function takes the viewport's near and far settings
699  into account. Set them to something appropriate before
700  calling this function.
701  */
702  bool GetBoundingBoxProjectionExtents(
703  ON_BoundingBox bbox,
704  ON_Interval& x_extents,
705  ON_Interval& y_extents
706  ) const;
707 
708  /*
709  Description:
710  Get near and far clipping distances of a bounding sphere.
711  Parameters:
712  sphere - [in]
713  bounding sphere
714  near_dist - [out]
715  near distance of the sphere (can be < 0)
716  far_dist - [out]
717  far distance of the sphere (can be equal to near_dist)
718  bGrowNearFar - [in]
719  If true and input values of near_dist and far_dist
720  are not ON_UNSET_VALUE, the near_dist and far_dist
721  are enlarged to include bbox.
722  Returns:
723  True if the sphere intersects the view frustum and
724  near_dist/far_dist were set.
725  False if the sphere does not intesect the view frustum.
726  */
727  bool GetSphereDepth(
728  ON_Sphere sphere,
729  double* near_dist,
730  double* far_dist,
731  bool bGrowNearFar=false
732  ) const;
733 
734  /*
735  Description:
736  Set near and far clipping distance subject to constraints.
737  Parameters:
738  near_dist - [in] (>0) desired near clipping distance
739  far_dist - [in] (>near_dist) desired near clipping distance
740  min_near_dist - [in]
741  If min_near_dist <= 0.0, it is ignored.
742  If min_near_dist > 0 and near_dist < min_near_dist,
743  then the frustum's near_dist will be increased to
744  min_near_dist.
745  min_near_over_far - [in]
746  If min_near_over_far <= 0.0, it is ignored.
747  If near_dist < far_dist*min_near_over_far, then
748  near_dist is increased and/or far_dist is decreased
749  so that near_dist = far_dist*min_near_over_far.
750  If near_dist < target_dist < far_dist, then near_dist
751  near_dist is increased and far_dist is decreased so that
752  projection precision will be good at target_dist.
753  Otherwise, near_dist is simply set to
754  far_dist*min_near_over_far.
755  target_dist - [in]
756  If target_dist <= 0.0, it is ignored.
757  If target_dist > 0, it is used as described in the
758  description of the min_near_over_far parameter.
759  relative_depth_bias - [in]
760  If relative_depth_bias <= 0.0, it is ignored.
761  If relative_depth_bias > 0, it is assumed that
762  the requested near_dist and far_dist were calculated
763  assuming no depth bias and the values will be
764  appropriately adjusted to ensure the frustum's
765  near and far clipping planes will not clip biased
766  objects.
767  */
768  bool SetFrustumNearFar(
769  double near_dist,
770  double far_dist,
771  double min_near_dist,
772  double min_near_over_far,
773  double target_dist
774  );
775 
776  bool SetFrustumNearFar(
777  double near_dist,
778  double far_dist,
779  double min_near_dist,
780  double min_near_over_far,
781  double target_dist,
782  double relative_depth_bias
783  );
784 
785  // Description:
786  // Get near clipping plane.
787  //
788  // near_plane - [out] near clipping plane if camera and frustum
789  // are valid. The plane's frame is the same as the camera's
790  // frame. The origin is located at the intersection of the
791  // camera direction ray and the near clipping plane. The plane's
792  // normal points out of the frustum towards the camera
793  // location.
794  //
795  // Returns:
796  // true if camera and frustum are valid.
797  bool GetNearPlane(
798  ON_Plane& near_plane
799  ) const;
800 
801  bool GetNearPlaneEquation(
802  ON_PlaneEquation& near_plane_equation
803  ) const;
804 
805  // Description:
806  // Get far clipping plane.
807  //
808  // far_plane - [out] far clipping plane if camera and frustum
809  // are valid. The plane's frame is the same as the camera's
810  // frame. The origin is located at the intersection of the
811  // camera direction ray and the far clipping plane. The plane's
812  // normal points into the frustum towards the camera location.
813  //
814  // Returns:
815  // true if camera and frustum are valid.
816  bool GetFarPlane(
817  ON_Plane& far_plane
818  ) const;
819 
820  bool GetFarPlaneEquation(
821  ON_PlaneEquation& far_plane_equation
822  ) const;
823 
824  /*
825  Description:
826  Get the plane that is a specified distance from the camera.
827  This plane is parallel to the frustum's near and far planes.
828  Parameters:
829  view_plane_depth - [in]
830  The distance from the camera location to the view plane.
831  Positive distances are in front of the camera and
832  negative distances are behind the camera.
833  A value of FrustumNear() will return the frustum's
834  near plane and a valud of FrustumFar() will return
835  the frustum's far plane.
836  view_plane - [out]
837  View plane
838  view_plane_equation - [out]
839  Equation of the view plane.
840  Returns:
841  True if the camera and frustum are valid and view_plane
842  was calculated. False otherwise.
843  */
844  bool GetViewPlane(
845  double view_plane_depth,
846  ON_Plane& view_plane
847  ) const;
848 
849  bool GetViewPlaneEquation(
850  double view_plane_depth,
851  ON_PlaneEquation& view_plane_equation
852  ) const;
853 
854  /*
855  Description:
856  Get left world frustum clipping plane.
857  Parameters:
858  left_plane - [out]
859  frustum left side clipping plane. The normal points
860  into the visible region of the frustum. If the projection
861  is perspective, the origin is at the camera location,
862  otherwise the origin isthe point on the plane that is
863  closest to the camera location.
864  Returns:
865  True if camera and frustum are valid and plane was set.
866  */
867  bool GetFrustumLeftPlane(
868  ON_Plane& left_plane
869  ) const;
870 
871  bool GetFrustumLeftPlaneEquation(
872  ON_PlaneEquation& left_plane_equation
873  ) const;
874 
875  /*
876  Description:
877  Get right world frustum clipping plane.
878  Parameters:
879  right_plane - [out]
880  frustum right side clipping plane. The normal points
881  into the visible region of the frustum. If the projection
882  is perspective, the origin is at the camera location,
883  otherwise the origin isthe point on the plane that is
884  closest to the camera location.
885  Returns:
886  True if camera and frustum are valid and plane was set.
887  */
888  bool GetFrustumRightPlane(
889  ON_Plane& right_plane
890  ) const;
891 
892  bool GetFrustumRightPlaneEquation(
893  ON_PlaneEquation& right_plane_equation
894  ) const;
895 
896  /*
897  Description:
898  Get bottom world frustum clipping plane.
899  Parameters:
900  bottom_plane - [out]
901  frustum bottom side clipping plane. The normal points
902  into the visible region of the frustum. If the projection
903  is perspective, the origin is at the camera location,
904  otherwise the origin isthe point on the plane that is
905  closest to the camera location.
906  Returns:
907  True if camera and frustum are valid and plane was set.
908  */
909  bool GetFrustumBottomPlane(
910  ON_Plane& bottom_plane
911  ) const;
912 
913  bool GetFrustumBottomPlaneEquation(
914  ON_PlaneEquation& bottom_plane_equation
915  ) const;
916  /*
917  Description:
918  Get top world frustum clipping plane.
919  Parameters:
920  top_plane - [out]
921  frustum top side clipping plane. The normal points
922  into the visible region of the frustum. If the projection
923  is perspective, the origin is at the camera location,
924  otherwise the origin isthe point on the plane that is
925  closest to the camera location.
926  Returns:
927  True if camera and frustum are valid and plane was set.
928  */
929  bool GetFrustumTopPlane(
930  ON_Plane& top_plane
931  ) const;
932 
933  bool GetFrustumTopPlaneEquation(
934  ON_PlaneEquation& top_plane_equation
935  ) const;
936 
937  // Description:
938  // Get corners of near clipping plane rectangle.
939  //
940  // Parameters:
941  // left_bottom - [out]
942  // right_bottom - [out]
943  // left_top - [out]
944  // right_top - [out]
945  //
946  // Returns:
947  // true if camera and frustum are valid.
948  bool GetNearRect(
949  ON_3dPoint& left_bottom,
950  ON_3dPoint& right_bottom,
951  ON_3dPoint& left_top,
952  ON_3dPoint& right_top
953  ) const;
954 
955  // Description:
956  // Get corners of far clipping plane rectangle.
957  //
958  // Parameters:
959  // left_bottom - [out]
960  // right_bottom - [out]
961  // left_top - [out]
962  // right_top - [out]
963  //
964  // Returns:
965  // true if camera and frustum are valid.
966  bool GetFarRect(
967  ON_3dPoint& left_bottom,
968  ON_3dPoint& right_bottom,
969  ON_3dPoint& left_top,
970  ON_3dPoint& right_top
971  ) const;
972 
973  /*
974  Description:
975  Get the world coordinate corners of the rectangle of
976  a view plane that is a specified distance from the camera.
977  This rectangle is parallel to the frustum's near and far planes.
978  Parameters:
979  view_plane_depth - [in]
980  The distance from the camera location to the view plane.
981  Positive distances are in front of the camera and
982  negative distances are behind the camera.
983  A value of FrustumNear() will return the frustum's
984  near rectangle and a valud of FrustumFar() will return
985  the frustum's far rectangle.
986  left_bottom - [out]
987  right_bottom - [out]
988  left_top - [out]
989  right_top - [out]
990  Returns:
991  True if the camera and frustum are valid and view_plane
992  was calculated. False otherwise.
993  */
994  bool GetViewPlaneRect(
995  double view_plane_depth,
996  ON_3dPoint& left_bottom,
997  ON_3dPoint& right_bottom,
998  ON_3dPoint& left_top,
999  ON_3dPoint& right_top
1000  ) const;
1001 
1002 
1003  /*
1004  Description:
1005  Location of viewport in pixels.
1006  These are provided so you can set the port you are using
1007  and get the appropriate transformations to and from
1008  screen space.
1009  Parameters:
1010  port_left - [in]
1011  port_right - [in] (port_left != port_right)
1012  port_bottom - [in]
1013  port_top - [in] (port_top != port_bottom)
1014  port_near - [in]
1015  port_far - [in]
1016  Example:
1017 
1018  // For a Windows window
1019  int width = width of window client area in pixels;
1020  int height = height of window client area in pixels;
1021  port_left = 0;
1022  port_right = width;
1023  port_top = 0;
1024  port_bottom = height;
1025  port_near = 0;
1026  port_far = 1;
1027  SetScreenPort( port_left, port_right,
1028  port_bottom, port_top,
1029  port_near, port_far );
1030 
1031  Returns:
1032  true if input is valid.
1033  See Also:
1034  ON_Viewport::GetScreenPort
1035  */
1036  bool SetScreenPort(
1037  int port_left,
1038  int port_right,
1039  int port_bottom,
1040  int port_top,
1041  int port_near = 0,
1042  int port_far = 0
1043  );
1044 
1045  bool GetScreenPort(
1046  int* left,
1047  int* right, //( port_left != port_right )
1048  int* port_bottom,
1049  int* port_top, //( port_bottom != port_top)
1050  int* port_near=nullptr,
1051  int* port_far=nullptr
1052  ) const;
1053 
1054  /*
1055  Returns:
1056  std::abs(port_right - port_left)
1057  */
1058  int ScreenPortWidth() const;
1059 
1060  /*
1061  Returns:
1062  std::abs(port_bottom - port_top)
1063  */
1064  int ScreenPortHeight() const;
1065 
1066  ON_2iSize ScreenPortSize() const;
1067 
1068  bool GetScreenPortAspect( double& ) const; // port's |width/height|
1069 
1070  bool GetCameraAngle(
1071  double* half_diagonal_angle, // 1/2 of diagonal subtended angle
1072  double* half_vertical_angle, // 1/2 of vertical subtended angle
1073  double* half_horizontal_angle // 1/2 of horizontal subtended angle
1074  ) const;
1075  bool GetCameraAngle(
1076  double* half_smallest_angle // 1/2 of smallest subtended view angle
1077  ) const;
1078  bool SetCameraAngle(
1079  double half_smallest_angle // 1/2 of smallest subtended view angle
1080  // 0 < angle < pi/2
1081  );
1082 
1083  // These functions assume the camera is horizontal and crop the
1084  // film rather than the image when the aspect of the frustum
1085  // is not 36/24. (35mm film is 36mm wide and 24mm high.)
1086  //
1087  // The SetCamera35mmLensLength() preserves camera location,
1088  // changes the frustum, but maintains the frsutrum's aspect.
1089  bool GetCamera35mmLensLength(
1090  double* lens_length
1091  ) const;
1092  bool SetCamera35mmLensLength(
1093  double lens_length
1094  );
1095 
1096  // Same as GetCamera35mmLensLength() with "lens" misspelled.
1097  bool GetCamera35mmLenseLength(
1098  double* lens_length
1099  ) const;
1100 
1101  // Same as SetCamera35mmLensLength() with "lens" misspelled.
1102  bool SetCamera35mmLenseLength(
1103  double lens_length
1104  );
1105 
1106  bool GetXform(
1107  ON::coordinate_system srcCS,
1108  ON::coordinate_system destCS,
1109  ON_Xform& matrix // 4x4 transformation matrix (acts on the left)
1110  ) const;
1111 
1112  /*
1113  Description:
1114  Get the world coordinate line in the view frustum
1115  that projects to a point on the screen.
1116  Parameters:
1117  screenx - [in]
1118  screeny - [in] (screenx,screeny) = screen location
1119  world_line - [out] 3d world coordinate line segment
1120  starting on the near clipping plane and ending
1121  on the far clipping plane.
1122  Returns:
1123  true if successful.
1124  false if view projection or frustum is invalid.
1125  */
1126  bool GetFrustumLine(
1127  double screenx,
1128  double screeny,
1129  ON_Line& world_line
1130  ) const;
1131 
1132  // display tools
1133 
1134  /*
1135  Description:
1136  Get the number of horizontal pixels per world unit at the
1137  location in screen space where world_point would be rendered.
1138  Parameters:
1139  world_point - [in] (ignored for parallel projection viewports)
1140  world location
1141  frustum_depth - [in] (ignored for parallel projection viewports)
1142  If the viewport has a perspective projection, then this parameter
1143  specifies the depth in the view frustum where the scale is calculated.
1144  If frustum_depth is not > 0.0, then FrustumNear() is used.
1145  pixels_per_unit - [out]
1146  number of horizontal screen pixels per world unit at the location
1147  in screen space where world_point would be rendered.
1148  If the viewport is not valid, then 0.0 is returned.
1149  Returns:
1150  true: success.
1151  false: The view projection or frustum is invalid.
1152  */
1153  bool GetWorldToScreenScale(
1154  ON_3dPoint world_point,
1155  double* pixels_per_unit
1156  ) const;
1157 
1158  /*
1159  Description:
1160  Get the number of horizontal pixels per world unit at the
1161  location in screen space where world_point would be rendered.
1162  Parameters:
1163  frustum_depth - [in] (ignored for parallel projection viewports)
1164  If the viewport has a perspective projection, then this parameter
1165  specifies the depth in the view frustum where the scale is calculated.
1166  If frustum_depth is not > 0.0, then FrustumNear() is used.
1167  pixels_per_unit - [out]
1168  number of horizontal screen pixels per world unit at the location
1169  in screen space where frustum_depth would be rendered.
1170  If the viewport is not valid, then 0.0 is returned.
1171  Returns:
1172  true: success.
1173  false: The view projection or frustum is invalid.
1174  */
1175  bool GetWorldToScreenScale(
1176  double frustum_depth,
1177  double* pixels_per_unit
1178  ) const;
1179 
1180  bool GetCoordinateSprite(
1181  int, // size in pixels of coordinate sprite axes
1182  int, int, // screen (x,y) for sprite origin
1183  int[3], // returns depth order for axes
1184  double [3][2] // screen coords for axes ends
1185  ) const;
1186 
1187  // Use Extents() as a quick way to set a viewport to so that bounding
1188  // volume is inside of a viewports frusmtrum.
1189  // The view angle is used to determine the position of the camera.
1190  bool Extents(
1191  double half_view_angle, // 1/2 smallest subtended view angle
1192  // (0 < angle < pi/2)
1193  const ON_BoundingBox& world_bbox// 3d world coordinate bounding box
1194  );
1195  bool Extents(
1196  double half_view_angle, // 1/2 smallest subtended view angle
1197  // (0 < angle < pi/2)
1198  const ON_3dPoint& center, // 3d world coordinate bounding sphere center
1199  double radius // 3d sphere radius
1200  );
1201 
1202  ////////////////////////////////////////////////////////////////////////
1203  // View changing from screen input points. Handy for
1204  // using a mouse to manipulate a view.
1205  //
1206 
1207  //////////
1208  // ZoomToScreenRect() may change camera and frustum settings
1209  bool ZoomToScreenRect(
1210  int screen_x0,
1211  int screen_y0, // (x,y) screen coords of a rectangle corner
1212  int screen_x1,
1213  int screen_y1 // (x,y) screen coords of opposite rectangle corner
1214  );
1215 
1216  //////////
1217  // DollyCamera() does not update the frustum's clipping planes.
1218  // To update the frustum's clipping planes call DollyFrustum(d)
1219  // with d = dollyVector o cameraFrameZ. To convert screen locations
1220  // into a dolly vector, use GetDollyCameraVector().
1221  bool DollyCamera( // Does not update frustum. To update frustum use
1222  // DollyFrustum(d) with d = dollyVector o cameraFrameZ
1223  const ON_3dVector& dolly_vector // dolly vector in world coordinates
1224  );
1225 
1226  //////////
1227  // Gets a world coordinate dolly vector that can be passed to
1228  // DollyCamera().
1229  bool GetDollyCameraVector(
1230  int screen_x0,
1231  int screen_y0, // (x,y) screen coords of start point
1232  int screen_x1,
1233  int screen_y1, // (x,y) screen coords of end point
1234  double proj_plane_dist, // distance of projection plane from camera.
1235  // When in doubt, use 0.5*(frus_near+frus_far).
1236  ON_3dVector& dolly_vector // world coordinate dolly vector returned here
1237  ) const;
1238 
1239  //////////
1240  // Moves frustum's clipping planes
1241  bool DollyFrustum(
1242  double dolly_distance // distance to move in camera direction
1243  );
1244 
1245  /*
1246  Description:
1247  Apply scaling factors to parallel projection clipping coordinates
1248  by setting the m_clip_mod transformation.
1249  Parameters:
1250  x - [in] x > 0
1251  y - [in] y > 0
1252  Example:
1253  If you want to compress the view projection across the viewing
1254  plane, then set x = 0.5, y = 1.0, and z = 1.0.
1255  Returns:
1256  True if successful.
1257  False if input is invalid or the view is a perspective view.
1258  */
1259  bool SetViewScale( double x, double y );
1260  void GetViewScale( double* x, double* y ) const;
1261 
1262  /*
1263  Description:
1264  Gets the m_clip_mod transformation;
1265  Returns:
1266  value of the m_clip_mod transformation.
1267  */
1268  ON_Xform ClipModXform() const;
1269 
1270  /*
1271  Description:
1272  Gets the m_clip_mod_inverse transformation;
1273  Returns:
1274  value of the m_clip_mod_inverse transformation.
1275  */
1276  ON_Xform ClipModInverseXform() const;
1277 
1278  /*
1279  Returns:
1280  True if clip mod xform is identity.
1281  */
1282  bool ClipModXformIsIdentity() const;
1283 
1284  /*
1285  Description:
1286  Return a point on the central axis of the view frustum.
1287  This point is a good choice for a general purpose target point.
1288  Parameters:
1289  target_distance - [in]
1290  If target_distance > 0.0, then the distance from the returned
1291  point to the camera plane will be target_distance. Note that
1292  if the frustum is not symmetric, the distance from the
1293  returned point to the camera location will be larger than
1294  target_distanct.
1295  If target_distance == ON_UNSET_VALUE and the frustum
1296  is valid with near > 0.0, then 0.5*(near + far) will be used
1297  as the target_distance.
1298  Returns:
1299  A point on the frustum's central axis. If the viewport or input
1300  is not valid, then ON_3dPoint::UnsetPoint is returned.
1301  */
1302  ON_3dPoint FrustumCenterPoint( double target_distance ) const;
1303 
1304  /*
1305  Returns:
1306  The current value of the target point. This point does not play
1307  a role in the view projection calculations. It can be used as a
1308  fixed point when changing the camera so the visible regions of the
1309  before and after frustums both contain the region of interest.
1310  Remarks:
1311  The default constructor sets this point on ON_3dPoint::UnsetPoint.
1312  You must explicitly call one SetTargetPoint() functions to set
1313  the target point.
1314  */
1315  ON_3dPoint TargetPoint() const;
1316 
1317  /*
1318  Description:
1319  Set the target point.
1320  Parameters:
1321  target_point - [in]
1322  When in doubt, the point returned by FrustumCenterPoint(ON_UNSET_VALUE)
1323  is a good choice.
1324  Remarks:
1325  The default constructor sets this point on ON_3dPoint::UnsetPoint.
1326  You must explicitly call one SetTargetPoint() functions to set
1327  the target point.
1328  */
1329  bool SetTargetPoint( ON_3dPoint target_point );
1330 
1331  /*
1332  Description:
1333  Get the distance from the target point to the camera plane.
1334  Note that if the frustum is not symmetric, then this distance
1335  is shorter than the distance from the target to the camera location.
1336  Parameters:
1337  bUseFrustumCenterFallback - [in]
1338  If bUseFrustumCenterFallback is false and the target point is
1339  not valid, then ON_UNSET_VALUE is returned.
1340  If bUseFrustumCenterFallback is true and the frustum is valid
1341  and current target point is not valid or is behind the camera,
1342  then 0.5*(near + far) is returned.
1343  Returns:
1344  Shortest signed distance from camera plane to target point.
1345  If the target point is on the visible side of the camera,
1346  a positive value is returned. ON_UNSET_VALUE is returned
1347  when the input of view is not valid.
1348  */
1349  double TargetDistance( bool bUseFrustumCenterFallback ) const;
1350 
1351  /*
1352  Description:
1353  Get suggested values for setting the perspective minimum
1354  near distance and minimum near/far ratio.
1355  Parameters:
1356  camera_location - [in]
1357  depth_buffer_bit_depth - [in]
1358  typically 32, 24, 16 or 8, but any positive value can be
1359  passed in.
1360  min_near_dist - [out]
1361  Suggest value for passing to SetPerspectiveMinNearDist().
1362  min_near_over_far - [out]
1363  Suggest value for passing to SetPerspectiveMinNearOverFar().
1364  */
1365  static void GetPerspectiveClippingPlaneConstraints(
1366  ON_3dPoint camera_location,
1367  unsigned int depth_buffer_bit_depth,
1368  double* min_near_dist,
1369  double* min_near_over_far
1370  );
1371 
1372  /*
1373  Description:
1374  Calculate the value to add to homogeneous "z" clipping coordinate
1375  that corresponds to moving the corresponding euclidean camera
1376  coordinate by relative_depth_bias*(far - near).
1377  Parameters:
1378  relative_depth_bias - [in]
1379  signed relative bias.
1380  = 0: no bias,
1381  > 0: bias towards frustum's near clipping plane
1382  < 0: bias towards frustum's far clipping plane
1383  When you have curves and points that are "on" shaded objects,
1384  values around 1/256 work well to move the wire objects
1385  in front of or behind shaded objects.
1386  clip_z [-in]
1387  clip_w [-in]
1388  clip_z and clip_w are the homogeneous "w" and "w" coordinates
1389  of a homogeneous clipping coordinate point.
1390  Returns:
1391  The clipping coordinate depth bias to add to the z-clipping
1392  coordinate that corresponds to adding cam_depth_bias
1393  to the z camera coordinate.
1394  Remarks:
1395  For perspective views, this bias is largest in the vicinity
1396  of the frustum's near clipping plane and smallest in the
1397  vicinity of the frustum's far clipping plane.
1398  For orthographic projectsions, this bias is constant.
1399  */
1400  double ClipCoordDepthBias(
1401  double relative_depth_bias,
1402  double clip_z,
1403  double clip_w
1404  ) const;
1405 
1406  /*
1407  Description:
1408  Calculate a transformation to apply to clipping coordinates to
1409  bias their depth.
1410 
1411  Parameters:
1412  relative_depth_bias - [in]
1413  signed relative bias.
1414  = 0: no bias,
1415  > 0: bias towards frustum's near clipping plane
1416  < 0: bias towards frustum's far clipping plane
1417  When you have curves and points that are "on" shaded objects,
1418  values around 1/512 work well to move the wire objects
1419  in front of or behind shaded objects.
1420 
1421  clip_bias - [out]
1422  clip_bias = cam2clip * delta * clip2cam,
1423  where delta = 1 0 0 0
1424  0 1 0 0
1425  0 0 1 D
1426  0 0 0 1
1427  and D = relative_depth_bias*(far-near).
1428 
1429  Returns:
1430  True if the function worked. False if the frustum settings
1431  are not valild, in which cate the identity matrix is returned.
1432 
1433  Remarks:
1434  The inverse of the transformations returned by
1435  GetClipCoordDepthBiasXform(+r,...) is the transformation
1436  returned by GetClipCoordDepthBiasXform(-r,...).
1437  */
1438  bool GetClipCoordDepthBiasXform(
1439  double relative_depth_bias,
1440  ON_Xform& clip_bias
1441  ) const;
1442 
1443  /*
1444  Description:
1445  Set suggested the perspective minimum near distance and
1446  minimum near/far ratio to the suggested values returned
1447  by GetPerspectiveClippingPlaneConstraints().
1448  Parameters:
1449  depth_buffer_bit_depth - [in]
1450  typically 32, 24, 16 or 8, but any positive value can be
1451  passed in.
1452  */
1453  void SetPerspectiveClippingPlaneConstraints(
1454  unsigned int depth_buffer_bit_depth
1455  );
1456 
1457  /*
1458  Description:
1459  Expert user function to control the minimum
1460  ratio of near/far when perspective projections
1461  are begin used.
1462  Parameters:
1463  min_near_over_far - [in]
1464  Remarks:
1465  This is a runtime setting and is not saved in 3dm files.
1466  */
1467  void SetPerspectiveMinNearOverFar(double min_near_over_far);
1468 
1469  /*
1470  Description:
1471  Expert user function to get the minimum runtime
1472  value of near/far when perspective projections
1473  are begin used.
1474  Returns:
1475  The minimum permitted value of near/far when perspective
1476  projections are begin used.
1477  Remarks:
1478  This is a runtime setting and is not saved in 3dm files.
1479  */
1480  double PerspectiveMinNearOverFar() const;
1481 
1482  /*
1483  Description:
1484  Expert user function to control the minimum
1485  value of near when perspective projections
1486  are begin used.
1487  Parameters:
1488  min_near_dist - [in]
1489  Remarks:
1490  This is a runtime setting and is not saved in 3dm files.
1491  */
1492  void SetPerspectiveMinNearDist(double min_near_dist);
1493 
1494  /*
1495  Description:
1496  Expert user function to get the minimum
1497  value of near when perspective projections
1498  are begin used.
1499  Returns:
1500  The minimum permitted value of near when perspective
1501  projections are begin used.
1502  Remarks:
1503  This is a runtime setting and is not saved in 3dm files.
1504  */
1505  double PerspectiveMinNearDist() const;
1506 
1507  /*
1508  Description:
1509  Sets the viewport's id to the value used to
1510  uniquely identify this viewport.
1511  Parameters:
1512  viewport_id - [in]
1513  Returns:
1514  True if the viewport's id was successfully set
1515  and false otherwise (ie. the viewport uuid has
1516  already been set).
1517  Remarks:
1518  There is no approved way to change the viewport
1519  id once it is set in order to maintain consistency
1520  across multiple viewports and those routines that
1521  manage them.
1522  */
1523  bool SetViewportId(const ON_UUID& viewport_id );
1524 
1525  ON_UUID ViewportId(void) const;
1526 
1527  /*
1528  Description:
1529  EXPERT USER function to change the viewport's id.
1530  If you change the id, you risk damaging display
1531  and visibility relationships in the model.
1532  Parameters:
1533  viewport_id - [in]
1534  */
1535  void ChangeViewportId(const ON_UUID& viewport_id);
1536 
1537 
1538  /*
1539  Description:
1540  The "view frustum" is the frustum the m_xform transformation
1541  maps to clipping coordinate box (-1,+1)^3. These functions
1542  determine if some portion of the convex hull of the test points
1543  is inside the view frustum.
1544  Parameters:
1545  P - [in] point
1546  box - [in] bounding box
1547  count - [in] number of points
1548  p - [in] array of points
1549  bEnableClippingPlanes - [in]
1550  If true, then the additional clipping planes are tested.
1551  If false, then the additional clipping planes are ignored.
1552  Returns:
1553  0 = No part of the of the convex hull of the tested points
1554  is in the view frustum or the view camera and frustum
1555  have not been set.
1556  1 = A portion of the convex hull of the otested points may
1557  be in the view frustum.
1558  2 = The entire convex hull of the tested points is in the
1559  view frustum.
1560 
1561  Remarks:
1562  Each call to ON_Viewport::InViewFrustum() requires the calculation
1563  of the world-to-clipping coordinates transformation. If multiple
1564  queries are required, fewer computation resources will be used
1565  if you set ON_ClippingRegion.m_xform to the viewport's world-to-
1566  clipping coordinate transformation and then call the
1567  ON_ClippingRegion::InViewFrustum() functions.
1568  */
1569  int InViewFrustum(
1570  ON_3dPoint P
1571  ) const;
1572  int InViewFrustum(
1573  const ON_BoundingBox& bbox
1574  ) const;
1575  int InViewFrustum(
1576  int count,
1577  const ON_3fPoint* p
1578  ) const;
1579  int InViewFrustum(
1580  int count,
1581  const ON_3dPoint* p
1582  ) const;
1583  int InViewFrustum(
1584  int count,
1585  const ON_4dPoint* p
1586  ) const;
1588  /*
1589  Description:
1590  Determine if some portion of the transformed bounding box
1591  is inside the view frustum.
1592  Parameters:
1593  bInfiniteFrustum - [in]
1594  ignore the near and far clipping planes of the viewport.
1595  bbox - [in]
1596  bounding box
1597  bbox_xform - [in]
1598  If not nullptr, this transformation is applied to the bounding box.
1599  Typically bbox_xform is used to pass an instance reference transformation.
1600  Returns:
1601  0 = No part of the of the transformed bounding box
1602  is in the view frustum or the view camera and frustum
1603  have not been set.
1604  1 = A portion of of the transformed bounding box is
1605  in the view frustum
1606  2 = The entire transformed bounding box is in the
1607  view frustum.
1608  */
1609  int InViewFrustum(
1610  bool bInfiniteFrustum,
1611  const ON_BoundingBox& bbox,
1612  const ON_Xform* bbox_xform
1613  ) const;
1614 
1615 protected:
1617  // These boolean status flags are set to true when
1618  // the associated fields contain valid values.
1619  bool m_bValidCamera = true;
1620  bool m_bValidFrustum = true;
1621  bool m_bValidPort = false;
1622  bool m_bValidCameraFrame = true;
1623 
1624  // Camera Settings: ///////////////////////////////////////////////
1626  // perspective or parallel projection
1627  ON::view_projection m_projection = ON::parallel_view;
1629  // Camera location, direction and orientation (in world coordinates).
1630  // These values are used to set the camera frame vectors CamX, CamY,
1631  // CamZ. If bValidCamera is true, then the CamX, CamY and CamZ
1632  // vectors are properly initialized and should be used
1633  // instead of CamDir[] and CamUp[]. The frame vectors CamX, CamY, CamZ
1634  // are always a right handed orthonormal frame. The CamDir
1635  // and CamUp vectors contain the values passed to SetViewCamera().
1636 
1637  // If true and the camera is valid, then the corresponding camera
1638  // parameter will not be changed by view editing functions. This
1639  // permits user interface to easily preserve important camera
1640  // features without having to perform excessive calculations.
1641  bool m_bLockCamUp = false;
1642  bool m_bLockCamDir = false;
1643  bool m_bLockCamLoc = false;
1644  unsigned char m_frustum_symmetry_flags = 0; // 0 != (flags & 1) top/bottom symmetry enforced
1645  // 0 != (flags & 2) left/right symmetry enforced.
1646  ON_3dPoint m_CamLoc = ON_Viewport::DefaultCameraLocation; // camera location
1647  ON_3dVector m_CamDir = -ON_3dVector::ZAxis; // from camera towards view (nonzero and not parallel to m_CamUp)
1648  ON_3dVector m_CamUp = ON_3dVector::YAxis; // (nonzero and not parallel to m_CamDir)
1650  // The camera frame vectors are properly initialized by SetCamera()
1651  ON_3dVector m_CamX = ON_3dVector::XAxis;
1652  ON_3dVector m_CamY = ON_3dVector::YAxis;
1653  ON_3dVector m_CamZ = ON_3dVector::ZAxis;
1654 
1655  // View Frustum Settings: ///////////////////////////////////////
1656  // left, right are camera X coords on near clipping plane
1657  // bottom, top are camera Y coords on near clipping plane
1658  // near = distance from camera to near clipping plane
1659  // far = distance from camera to far clipping plane
1660  double m_frus_left = -20.0; // frus_left < frus_right
1661  double m_frus_right = 20.0;
1662  double m_frus_bottom = -20.0; // frus_bottom < frus_top
1663  double m_frus_top = 20.0;
1664  double m_frus_near = ON_Viewport::DefaultMinNearDist; // 0 < frus_near < frus_far
1665  double m_frus_far = ON_Viewport::DefaultFarDist;
1666 
1667  // Device View Port Box Settings: ( in display device coordinates ) ////
1668  // The point (left,bottom,-near), in camera coordinates, of the view
1669  // frustum is mapped to pixel coordinate (port_left,port_bottom,port_near).
1670  // The point (right,top,-far), in camera coordinates, of the view frustum
1671  // is mapped to pixel coordinate (port_right,port_top,port_far).
1672  // In many situations including Microsoft Windows coordinates,
1673  // port_left = 0,
1674  // port_right = viewport width-1,
1675  // port_top = 0,
1676  // port_bottom = viewport height-1.
1677  int m_port_left = 0; // port_left != port_right
1678  int m_port_right = 1000;
1679  int m_port_bottom = 0; // port_bottom != port_top
1680  int m_port_top = 1000;
1681  // (If you want an 8 bit z-buffer with
1682  // z=255 being "in front of" z=0, then
1683  // set port_near = 255 and port_far = 0.)
1684  int m_port_near = 0;
1685  int m_port_far = 1;
1686 
1687 
1688  // The location of this point has no impact on the
1689  // view projection. It is simply a suggestion for a
1690  // fixed point when views are rotated or the isometric
1691  // depth when perpsective views are dollied. The default
1692  // is ON_3dPoint::UnsetPoint.
1693  ON_3dPoint m_target_point = ON_3dPoint::UnsetPoint;
1694 
1695 private:
1696  // When this id matches the viewport id saved in an ON_DisplayMaterialRef
1697  // list in ON_3dmObjectAttributes, then the the display material is used
1698  // for that object in this view.
1699  ON_UUID m_viewport_id = ON_nil_uuid;
1700 
1701  bool SetCameraFrame(); // used to set m_CamX, m_CamY, m_CamZ
1702 
1703  // This transform is used to tweak the clipping
1704  // coordinates. The default is the identity.
1705  // Modify this transformation when you need to do
1706  // things like z-buffer bias, non-uniform viewplane
1707  // scaling, and so on.
1708 
1709  /*
1710  Description:
1711  Sets the m_clip_mod transformation;
1712  Parameters:
1713  clip_mod_xform - [in] invertable transformation
1714  */
1715  bool SetClipModXform( ON_Xform clip_mod_xform );
1716  ON_Xform m_clip_mods = ON_Xform::IdentityTransformation;
1717  ON_Xform m_clip_mods_inverse = ON_Xform::IdentityTransformation;
1718 
1719  // Runtime values that depend on the graphics hardware being used.
1720  // These values are not saved in 3dm files.
1721  double m__MIN_NEAR_DIST = ON_Viewport::DefaultMinNearDist;
1722  double m__MIN_NEAR_OVER_FAR = ON_Viewport::DefaultMinNearOverFar;
1723 
1724 private:
1725  mutable ON_SHA1_Hash m_projection_content_sha1 = ON_SHA1_Hash::ZeroDigest;
1726 };
1727 
1728 ON_DECL
1729 bool
1730 ON_GetViewportRotationAngles(
1731  const ON_3dVector&, // X, // X,Y,Z must be a right handed orthonormal basis
1732  const ON_3dVector&, // Y,
1733  const ON_3dVector&, // Z,
1734  double*, // angle1, // returns rotation about world Z
1735  double*, // angle2, // returns rotation about world X ( 0 <= a2 <= pi )
1736  double* // angle3 // returns rotation about world Z
1737  );
1738 
1739 ON_DECL
1740 bool
1741 ON_ViewportFromRhinoView( // create ON_Viewport from legacy Rhino projection info
1742  ON::view_projection, // projection,
1743  const ON_3dPoint&, // rhvp_target, // 3d point
1744  double, // rhvp_angle1 in radians
1745  double, // rhvp_angle2 in radians
1746  double, // rhvp_angle3 in radians
1747  double, // rhvp_viewsize, // > 0
1748  double, // rhvp_cameradist, // > 0
1749  int, // screen_width,
1750  int, // screen_height,
1751  ON_Viewport&
1752  );
1753 
1754 /*
1755 Description:
1756  Calculate the corners of the polygon that is the
1757  intersection of a view frustum with and infinte plane.
1758 Parameters:
1759  vp - [in] defines view frustum
1760  plane_equation - [in] defined infinte plane
1761  points - [out] corners of the polygon.
1762  If true is returned and points.Count() is zero, then
1763  the plane missed the frustum. Note that the start/end
1764  point is not duplicated in the list.
1765 Returns:
1766  True if input was valid, false otherwise. Note that
1767  even when true is returned, the returned points.Count()
1768  may be zero if the plane and frustum do not intersect.
1769 */
1770 ON_DECL
1771 bool
1772 ON_IntersectViewFrustumPlane(
1773  const ON_Viewport& vp,
1774  const ON_PlaneEquation& plane_equation,
1775  ON_SimpleArray<ON_3dPoint>& points
1776  );
1777 
1778 #endif
1779 
virtual bool Transform(const ON_Xform &xform)
Transforms the object.
ON_UUID is a 16 byte universally unique identifier.
Definition: opennurbs_uuid.h:32
virtual int Dimension() const
Dimension of the object.
Definition: opennurbs_ipoint.h:236
virtual bool GetBBox(double *boxmin, double *boxmax, bool bGrowBox=false) const
This is the virtual function that actually calculates axis aligned bounding boxes.
Definition: opennurbs_array.h:36
Definition: opennurbs_sha1.h:19
Definition: opennurbs_fpoint.h:211
Base class for all geometry classes that must provide runtime class id. Provides interface for common...
Definition: opennurbs_geometry.h:37
static const double DefaultMinNearDist
Definition: opennurbs_viewport.h:38
Definition: opennurbs_point.h:648
Definition: opennurbs_bounding_box.h:25
Definition: opennurbs_xform.h:28
virtual void Dump(ON_TextLog &) const
Creates a text dump of the object.
Definition: opennurbs_line.h:20
ON_Geometry & operator=(const ON_Geometry &)=default
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783
static const double DefaultMinNearOverFar
Definition: opennurbs_viewport.h:39
Definition: opennurbs_viewport.h:31
virtual bool Read(ON_BinaryArchive &binary_archive)
Low level archive writing tool used by ON_BinaryArchive::ReadObject().
Definition: opennurbs_point.h:460
bool IsValid(class ON_TextLog *text_log=nullptr) const override
Tests an object to see if its data members are correctly initialized.
virtual bool Write(ON_BinaryArchive &binary_archive) const
Low level archive writing tool used by ON_BinaryArchive::WriteObject().
static const double DefaultFarDist
Definition: opennurbs_viewport.h:37
static const ON_3dVector Default3dCameraDirection
Definition: opennurbs_viewport.h:42
Definition: opennurbs_plane.h:20
static const double DefaultNearDist
Definition: opennurbs_viewport.h:36
Typically the vector portion is a unit vector and m_d = -(x*P.x + y*P.y + z*P.z) for a point P on the...
Definition: opennurbs_point.h:1433
Definition: opennurbs_point.h:1152
Definition: opennurbs_point.h:46
Definition: opennurbs_sphere.h:22
static const ON_3dPoint DefaultCameraLocation
Definition: opennurbs_viewport.h:41