HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_PrimVolumeXform.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_PrimVolume.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GA_PrimVolumeXform__
12 #define __GA_PrimVolumeXform__
13 
14 #include <GA/GA_API.h>
15 #include <UT/UT_BoundingBox.h>
16 #include <UT/UT_BoundingRect.h>
17 #include <UT/UT_Matrix3.h>
18 #include <UT/UT_Matrix4.h>
19 
20 class GA_Detail;
21 
22 ///
23 /// Stores the transform associated with a volume, allowing the
24 /// to/from code to be inlined outside of this library.
25 ///
27 {
28 public:
29  // Converts from world space to [0,1] space.
31  {
32  pos -= myCenter;
33  pos *= myInverseXform;
34 
35  // Undo any taper effect.
36  if (myHasTaper)
37  {
38  fpreal zscale = (1 - pos.z()) * 0.5f;
39  fpreal taperx = 1 + (-1 + myTaperX) * zscale;
40  fpreal tapery = 1 + (-1 + myTaperY) * zscale;
41 
42  if (taperx == 0.0f)
43  pos.x() = 0.0;
44  else
45  pos.x() /= taperx;
46  if (tapery == 0.0f)
47  pos.y() = 0.0;
48  else
49  pos.y() /= tapery;
50  }
51 
52  // This gets us a value in the -1 to 1 box. We need to evaluate
53  // in the 0 to 1 box, however.
54  pos.x() += 1;
55  pos.y() += 1;
56  pos.z() += 1;
57  pos *= 0.5;
58 
59  return pos;
60  }
61 
62  // Converts from [0,1] space over the voxels to world space
64  {
65  // convert to -1 to 1 box.
66  pos.x() -= 0.5;
67  pos.y() -= 0.5;
68  pos.z() -= 0.5;
69  pos *= 2;
70 
71  // Apply the taper effect.
72  if (myHasTaper)
73  {
74  fpreal zscale = (1 - pos.z()) * 0.5f;
75  fpreal taperx = 1 + (-1 + myTaperX) * zscale;
76  fpreal tapery = 1 + (-1 + myTaperY) * zscale;
77 
78  pos.x() *= taperx;
79  pos.y() *= tapery;
80  }
81  // Convert to world space.
82  pos *= myXform;
83  pos += myCenter;
84 
85  return pos;
86  }
87 
88  // Returns jacobian of the transformation `toVoxelSpace` at point `pos`
89  //
90  // If `myHasTaper() == false` then the jacobian does not depend on the position `pos`.
91  //
92  // Vector `v` located at point `pos` gets transformed by `toVoxelSpace` map as:
93  // v -> v * toVoxelSpaceJacobian(pos)
94  //
95  // `toVoxelSpaceJacobian(pos)` is inverse of `fromVoxelSpaceJacobian(toVoxelSpace(pos))`
97  {
98  if (!myHasTaper)
99  return myInverseXform*0.5;
100 
101  pos -= myCenter;
102  pos *= myInverseXform;
103 
104  float zscale = (1 - pos.z()) * 0.5f;
105  float taperx = 1 + (-1 + myTaperX) * zscale;
106  float tapery = 1 + (-1 + myTaperY) * zscale;
107 
108  UT_Matrix3 tapergrad{
109  1.f / taperx,
110  0.f,
111  0.f,
112  0.f,
113  1.f / tapery,
114  0.f,
115  0.5f * (myTaperX - 1.f) * pos.x() / (taperx * taperx),
116  0.5f * (myTaperY - 1.f) * pos.y() / (tapery * tapery),
117  1.f};
118 
119  return myInverseXform*tapergrad*0.5;
120  }
121 
122  // Returns jacobian of the transformation `fromVoxelSpace` at point `pos`
123  //
124  // If `myHasTaper == false` then the jacobian does not depend on the position `pos`.
125  //
126  // Vector `v` located at point `pos` gets transformed by `fromVoxelSpace` map as:
127  // v -> v * fromVoxelSpaceJacobian(pos)
128  //
129  // `fromVoxelSpaceJacobian(pos)` is inverse of `toVoxelSpaceJacobian(fromVoxelSpace(pos))`
131  {
132  if (!myHasTaper)
133  return 2.f*myXform;
134 
135  pos.x() -= 0.5;
136  pos.y() -= 0.5;
137  pos.z() -= 0.5;
138  pos *= 2;
139 
140  float zscale = (1 - pos.z()) * 0.5f;
141  float taperx = 1 + (-1 + myTaperX) * zscale;
142  float tapery = 1 + (-1 + myTaperY) * zscale;
143 
144  UT_Matrix3 tapergrad{
145  1.f * taperx,
146  0.f,
147  0.f,
148  0.f,
149  1.f * tapery,
150  0.f,
151  0.5f * (1.f - myTaperX) * pos.x(),
152  0.5f * (1.f - myTaperY) * pos.y(),
153  1.f};
154 
155  return 2.f*tapergrad*myXform;
156  }
157 
158 
159  inline void transform(const UT_Matrix4 &xform)
160  {
161  myCenter *= xform;
162  myXform.multiply3(xform);
163  myInverseXform = myXform;
164  myInverseXform.invert();
165  }
166 
167  inline void transform(const UT_Matrix4D &xform)
168  {
169  myCenter *= xform;
170  myXform *= UT_Matrix3D(xform);
171  myInverseXform = myXform;
172  myInverseXform.invert();
173  }
174 
175  inline void toVoxelSpace(UT_BoundingBox &box) const
176  {
177  int i;
178  UT_Vector3 v[8] = {
179  UT_Vector3(box.xmin(), box.ymin(), box.zmin()),
180  UT_Vector3(box.xmin(), box.ymin(), box.zmax()),
181  UT_Vector3(box.xmin(), box.ymax(), box.zmin()),
182  UT_Vector3(box.xmin(), box.ymax(), box.zmax()),
183  UT_Vector3(box.xmax(), box.ymin(), box.zmin()),
184  UT_Vector3(box.xmax(), box.ymin(), box.zmax()),
185  UT_Vector3(box.xmax(), box.ymax(), box.zmin()),
186  UT_Vector3(box.xmax(), box.ymax(), box.zmax()),
187  };
188 
189  box.initBounds();
190  for (i = 0; i < 8; i++)
191  {
192  box.enlargeBounds(toVoxelSpace(v[i]));
193  }
194  }
195 
196  inline void fromVoxelSpace(UT_BoundingBox &box) const
197  {
198  int i;
199  UT_Vector3 v[8] = {
200  UT_Vector3(box.xmin(), box.ymin(), box.zmin()),
201  UT_Vector3(box.xmin(), box.ymin(), box.zmax()),
202  UT_Vector3(box.xmin(), box.ymax(), box.zmin()),
203  UT_Vector3(box.xmin(), box.ymax(), box.zmax()),
204  UT_Vector3(box.xmax(), box.ymin(), box.zmin()),
205  UT_Vector3(box.xmax(), box.ymin(), box.zmax()),
206  UT_Vector3(box.xmax(), box.ymax(), box.zmin()),
207  UT_Vector3(box.xmax(), box.ymax(), box.zmax()),
208  };
209 
210  box.initBounds();
211  for (i = 0; i < 8; i++)
212  {
213  box.enlargeBounds(fromVoxelSpace(v[i]));
214  }
215  }
216 
217  /// Returns the *un-tapered* matrix4 corresponding to fromVoxelSpace().
218  /// @{
219  void getTransform4(UT_Matrix4F &matx) const;
220  void getTransform4(UT_Matrix4D &matx) const;
221  /// @}
222 
223  /// Returns if the transform is flagged as having a taper.
224  bool isTapered() const { return myHasTaper; }
225 
226  /// Compute the size for this transform (relative to myCenter)
227  UT_Vector3R computeSize() const;
228 
229  // NOTE: This ordering is saved in .hip files!
231  {
232  NON_SQUARE = 0,
237  BY_SIZE
238  };
239 
240  /// Convert the "uniformsamples" parm menu item index to a sampling type
242  { return SamplingType(i); }
243 
244  /// Compute the resolution (and size) from a common set of parameters.
245  /// If twod_axis is one of [0,1,2], then that axis clamped to a divisions
246  /// of 1 and a size of 0. The number of divisions is returned with size
247  /// set to div_size multiplied by divisions before the z_div_scale.
248  static UT_Vector3R computeResolution(
249  SamplingType sampling_type,
250  const UT_Vector3R &non_uniform_divs,
251  fpreal uniform_divs,
252  fpreal div_size,
253  fpreal z_div_scale,
254  UT_Vector3R &size_inout,
255  int twod_axis = -1);
256 
257  /// Compute a space transform from center, size, and taper
258  static GA_PrimVolumeXform frustumSpaceTransform(
259  const UT_Vector3R &size,
260  const UT_Vector3R &center,
261  fpreal taper_x, fpreal taper_y);
262 
263  static GA_PrimVolumeXform cameraFrustum(
264  fpreal focal,
265  fpreal aperture,
266  const UT_Vector2R &image_res,
267  fpreal pixel_aspect,
268  bool is_ortho,
269  fpreal ortho_zoom,
270  fpreal clip_near,
271  fpreal clip_far,
272  bool use_cam_window,
273  const UT_BoundingRectR &cam_window,
274  const UT_BoundingRectR &cam_crop,
275  const UT_BoundingRectR &window,
276  const UT_Matrix4R &post_xform,
277  const GA_Detail *match_src);
278 
279 public:
280  // @{
281  void save(std::ostream &os, bool binary = false) const;
282  bool load(UT_IStream &is);
283  // @}
284 
285  void init()
286  {
287  myCenter.assign(0, 0, 0);
288  myXform.identity();
289  myInverseXform.identity();
290  myHasTaper = false;
291  myTaperX = 1.0;
292  myTaperY = 1.0;
293  }
294 
295  bool operator==(const GA_PrimVolumeXform &x) const
296  {
297  return
298  myXform == x.myXform &&
299  myCenter == x.myCenter &&
300  myHasTaper == x.myHasTaper &&
301  myTaperX == x.myTaperX &&
302  myTaperY == x.myTaperY;
303  }
304 
305  UT_Matrix3 myXform, myInverseXform;
308  float myTaperX, myTaperY;
309 };
310 
311 #endif
const GLdouble * v
Definition: glcorearb.h:837
void transform(const UT_Matrix4 &xform)
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
UT_Vector3T< float > UT_Vector3
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
bool operator==(const GA_PrimVolumeXform &x) const
#define GA_API
Definition: GA_API.h:14
UT_Vector3 toVoxelSpace(UT_Vector3 pos) const
void fromVoxelSpace(UT_BoundingBox &box) const
GLfloat f
Definition: glcorearb.h:1926
void enlargeBounds(const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
GLint GLenum GLint x
Definition: glcorearb.h:409
static SamplingType samplingType(int i)
Convert the "uniformsamples" parm menu item index to a sampling type.
GLsizeiptr size
Definition: glcorearb.h:664
fpreal64 fpreal
Definition: SYS_Types.h:278
SYS_FORCE_INLINE void initBounds()
UT_Vector3 fromVoxelSpace(UT_Vector3 pos) const
int invert(T tol=0.0F)
Container class for all geometry.
Definition: GA_Detail.h:96
void transform(const UT_Matrix4D &xform)
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
UT_Matrix3 toVoxelSpaceJacobian(UT_Vector3 pos) const
void toVoxelSpace(UT_BoundingBox &box) const
UT_Matrix3T< fpreal64 > UT_Matrix3D
bool isTapered() const
Returns if the transform is flagged as having a taper.
UT_Matrix3 fromVoxelSpaceJacobian(UT_Vector3 pos) const
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663