Field3D
FieldMapping.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
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
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
43 //----------------------------------------------------------------------------//
44 
45 #include <iostream>
46 #include <vector>
47 
48 #include "Field.h"
49 #include "FieldMapping.h"
50 #include "Types.h"
51 
52 //----------------------------------------------------------------------------//
53 
54 using namespace boost;
55 using namespace std;
56 
57 //----------------------------------------------------------------------------//
58 
60 
61 //----------------------------------------------------------------------------//
62 // Field3D namespaces
63 //----------------------------------------------------------------------------//
64 
65 
66 //----------------------------------------------------------------------------//
67 // Local namespace
68 //----------------------------------------------------------------------------//
69 
70 namespace {
71 
72  // Strings ---
73 
74  const string k_mappingName("FieldMapping");
75  const string k_nullMappingName("NullFieldMapping");
76  const string k_matrixMappingName("MatrixFieldMapping");
77  const string k_frustumMappingName("FrustumFieldMapping");
78 
79  // Functions ---
80 
81  template <class Matrix_T>
82  bool checkMatricesIdentical(const Matrix_T &m1, const Matrix_T &m2,
83  double tolerance)
84  {
85  if (m1.equalWithRelError(m2, tolerance)) {
86  return true;
87  }
88  V3d s1, r1, t1, sh1, s2, r2, t2, sh2;
89  if (!FIELD3D_EXTRACT_SHRT(m1, s1, sh1, r1, t1, false)) {
90  return false;
91  }
92  if (!FIELD3D_EXTRACT_SHRT(m2, s2, sh2, r2, t2, false)) {
93  return false;
94  }
95  if (!s1.equalWithRelError(s2, tolerance) ||
96  !r1.equalWithAbsError(r2, tolerance) ||
97  !t1.equalWithRelError(t2, tolerance)) {
98  return false;
99  }
100  return true;
101  }
102 
103 }
104 
105 //----------------------------------------------------------------------------//
106 // FieldMapping
107 //----------------------------------------------------------------------------//
108 
110  : RefBase(),
111  m_origin(V3i(0)),
112  m_res(V3i(1))
113 {
114  /* Empty */
115 }
116 
117 //----------------------------------------------------------------------------//
118 
120  : RefBase()
121 {
122  setExtents(extents);
123 }
124 
125 //----------------------------------------------------------------------------//
126 
128 {
129  /* Empty */
130 }
131 
132 //----------------------------------------------------------------------------//
133 
134 
135 std::string FieldMapping::className() const
136 {
137  return std::string(classType());
138 }
139 
140 //----------------------------------------------------------------------------//
141 
142 void FieldMapping::setExtents(const Box3i &extents)
143 {
144  m_origin = extents.min;
145  m_res = extents.max - extents.min + V3i(1);
146  extentsChanged();
147 }
148 
149 //----------------------------------------------------------------------------//
150 
151 void FieldMapping::localToVoxel(const V3d &lsP, V3d &vsP) const
152 {
153  vsP = m_origin + lsP * m_res;
154 }
155 
156 //----------------------------------------------------------------------------//
157 
158 void FieldMapping::voxelToLocal(const V3d &vsP, V3d &lsP) const
159 {
160  lsP.x = FIELD3D_LERPFACTOR(vsP.x, m_origin.x, m_origin.x + m_res.x);
161  lsP.y = FIELD3D_LERPFACTOR(vsP.y, m_origin.y, m_origin.y + m_res.y);
162  lsP.z = FIELD3D_LERPFACTOR(vsP.z, m_origin.z, m_origin.z + m_res.z);
163 }
164 
165 //----------------------------------------------------------------------------//
166 // NullFieldMapping
167 //----------------------------------------------------------------------------//
168 
169 std::string NullFieldMapping::className() const
170 {
171  return std::string(classType());
172 }
173 
174 //----------------------------------------------------------------------------//
175 
177  double tolerance) const
178 {
179  // For null mappings it's simple - if the other one is also a null mapping
180  // then true, otherwise it's false.
181 
182  return other->className() == k_nullMappingName;
183 }
184 
185 //----------------------------------------------------------------------------//
186 
188 {
189  return Ptr(new NullFieldMapping(*this));
190 }
191 
192 //----------------------------------------------------------------------------//
193 // MatrixFieldMapping
194 //----------------------------------------------------------------------------//
195 
197  : FieldMapping()
198 {
199  makeIdentity();
200 }
201 
202 //----------------------------------------------------------------------------//
203 
205  : FieldMapping(extents)
206 {
207  makeIdentity();
208 }
209 
210 //----------------------------------------------------------------------------//
211 
213 {
214  if (m_lsToWsCurve.numSamples() > 0) {
215  makeIdentity();
216  }
217  setLocalToWorld(0.0f, lsToWs);
218 }
219 
220 //----------------------------------------------------------------------------//
221 
222 void MatrixFieldMapping::setLocalToWorld(float t, const M44d &lsToWs)
223 {
224  m_lsToWsCurve.addSample(t, lsToWs);
225  updateTransform();
226 }
227 
228 //----------------------------------------------------------------------------//
229 
231 {
233  updateTransform();
234 }
235 
236 //----------------------------------------------------------------------------//
237 
239 {
240  updateTransform();
241 }
242 
243 //----------------------------------------------------------------------------//
244 
245 std::string MatrixFieldMapping::className() const
246 {
247  return std::string(classType());
248 }
249 
250 //----------------------------------------------------------------------------//
251 
253  double tolerance) const
254 {
256 
257  if (other->className() != k_matrixMappingName) {
258  return false;
259  } else {
260 
262  FIELD_DYNAMIC_CAST<MatrixFieldMapping>(other);
263 
264  if (mm) {
265 
266  const SampleVec lsToWs1 = m_lsToWsCurve.samples();
267  const SampleVec lsToWs2 = mm->m_lsToWsCurve.samples();
268  const SampleVec vsToWs1 = m_vsToWsCurve.samples();
269  const SampleVec vsToWs2 = mm->m_vsToWsCurve.samples();
270 
271  size_t numSamples = lsToWs1.size();
272 
273  // First check if time sample counts differ
274  // lsToWs and vsToWs are guaranteed to have same sample count.
275  if (lsToWs1.size() != lsToWs2.size()) {
276  return false;
277  }
278 
279  // Then check if all time samples match, then check localToWorld
280  // and voxelToWorld matrices
281  for (size_t i = 0; i < numSamples; ++i) {
282  if (lsToWs1[i].first != lsToWs2[i].first) {
283  return false;
284  }
285  if (!checkMatricesIdentical(lsToWs1[i].second, lsToWs2[i].second,
286  tolerance)) {
287  return false;
288  }
289  if (!checkMatricesIdentical(vsToWs1[i].second, vsToWs2[i].second,
290  tolerance)) {
291  return false;
292  }
293  }
294 
295  return true;
296 
297  } else {
298  return false;
299  }
300  }
301  return false;
302 }
303 
304 //----------------------------------------------------------------------------//
305 
307 {
308  typedef MatrixCurve::SampleVec::const_iterator SampleIter;
309 
310  // Build the voxel to world space transforms ---
311  M44d lsToVs;
312  getLocalToVoxelMatrix(lsToVs);
313  M44d vsToLs = lsToVs.inverse();
314  // Loop over all samples in lsToWs, append vsToLs and create new curve
315  // Also handle the special case where lsToWs has no samples. In that
316  // case m_vsToWsCurve still has to have one sample.
317  const MatrixCurve::SampleVec &lsToWs = m_lsToWsCurve.samples();
319  for (SampleIter i = lsToWs.begin(), end = lsToWs.end(); i != end; i++) {
320  m_vsToWsCurve.addSample(i->first, vsToLs * i->second);
321  }
322 
323  // See if the curve has more than just a single sample
325 
326  // Sample the time-varying transforms at time=0.0
328  m_wsToLs = m_lsToWs.inverse();
329  m_vsToWs = vsToLs * m_lsToWs;
330  m_wsToVs = m_vsToWs.inverse();
331 
332  // Precompute the voxel size
333  V3d voxelOrigin, nextVoxel;
334  m_vsToWs.multVecMatrix(V3d(0, 0, 0), voxelOrigin);
335  m_vsToWs.multVecMatrix(V3d(1, 0, 0), nextVoxel);
336  m_wsVoxelSize.x = (nextVoxel - voxelOrigin).length();
337  m_vsToWs.multVecMatrix(V3d(0, 1, 0), nextVoxel);
338  m_wsVoxelSize.y = (nextVoxel - voxelOrigin).length();
339  m_vsToWs.multVecMatrix(V3d(0, 0, 1), nextVoxel);
340  m_wsVoxelSize.z = (nextVoxel - voxelOrigin).length();
341 }
342 
343 //----------------------------------------------------------------------------//
344 
346 {
347  // Local to voxel is a scale by the resolution of the field, offset
348  // to the origin of the extents
349  M44d scaling, translation;
350  scaling.setScale(m_res);
351  translation.setTranslation(m_origin);
352  result = scaling * translation;
353 }
354 
355 //----------------------------------------------------------------------------//
356 
358 {
359  return Ptr(new MatrixFieldMapping(*this));
360 }
361 
362 //----------------------------------------------------------------------------//
363 // FrustumFieldMapping
364 //----------------------------------------------------------------------------//
365 
367  : FieldMapping(),
368  m_zDistribution(PerspectiveDistribution),
369  m_defaultState(true)
370 {
371  reset();
372 }
373 
374 //----------------------------------------------------------------------------//
375 
377  : FieldMapping(extents)
378 {
379  reset();
380 }
381 
382 //----------------------------------------------------------------------------//
383 
384 void FrustumFieldMapping::setTransforms(const M44d &ssToWs, const M44d &csToWs)
385 {
386  setTransforms(0.0, ssToWs, csToWs);
387 }
388 
389 //----------------------------------------------------------------------------//
390 
392  const M44d &ssToWs, const M44d &csToWs)
393 {
394  if (m_defaultState) {
395  clearCurves();
396  m_defaultState = false;
397  }
398 
399  // Construct local-to-world transform from ssToWs
400  M44d lsToSs, scale, translation;
401  scale.setScale(V3d(2.0, 2.0, 1.0));
402  translation.setTranslation(V3d(-1.0, -1.0, 0.0));
403  lsToSs = scale * translation;
404  M44d lpsToWs = lsToSs * ssToWs;
405 
406  // Add samples to Curves
407  m_ssToWsCurve.addSample(t, ssToWs);
408  m_lpsToWsCurve.addSample(t, lpsToWs);
409  m_csToWsCurve.addSample(t, csToWs);
410 
411  // Compute near and far planes ---
412 
413  // Because the frustum may be skewed we can't just measure distance from
414  // the apex of the frustum to the world-space center point of the frustum.
415  // Instead, we transform into camera space and measure z depth there.
416 
417  V3d lsNearP(0.5, 0.5, 0.0), lsFarP(0.5, 0.5, 1.0);
418  V3d wsNearP, wsFarP, csNearP, csFarP;
419 
420  lpsToWs.multVecMatrix(lsNearP, wsNearP);
421  lpsToWs.multVecMatrix(lsFarP, wsFarP);
422 
423  M44d wsToCs = csToWs.inverse();
424  wsToCs.multVecMatrix(wsNearP, csNearP);
425  wsToCs.multVecMatrix(wsFarP, csFarP);
426 
427  double near = -csNearP.z;
428  double far = -csFarP.z;
429 
430  // Catch NaN here
431  if (isnan(near) || isnan(far)) {
432  throw BadPerspectiveMatrix("FrustumFieldMapping::setTransforms "
433  "received bad screen-to-world matrix");
434  }
435 
436  m_nearCurve.addSample(t, near);
437  m_farCurve.addSample(t, far);
438 
440 }
441 
442 //----------------------------------------------------------------------------//
443 
445 {
446  // Default camera to world ---
447 
448  M44d csToWs;
449  csToWs.makeIdentity();
450 
451  // Default screen to world ---
452 
453  double near = 1;
454  double far = 2;
455  double fovRadians = 45.0 * M_PI / 180.0;
456  double invTan = 1.0 / std::tan(fovRadians / 2.0);
457  double imageAspectRatio = 1.0;
458 
459  M44d perspective(1, 0, 0, 0,
460  0, 1, 0, 0,
461  0, 0, (far) / (far - near), 1,
462  0, 0, (- far * near) / (far - near), 0);
463 
464  M44d fov;
465  fov.setScale(V3d(invTan / imageAspectRatio, invTan, 1.0));
466 
467  M44d flipZ;
468  flipZ.setScale(V3d(1.0, 1.0, -1.0));
469 
470  M44d csToSs = flipZ * perspective * fov;
471 
472  M44d standardSsToWs = csToSs.inverse() * csToWs;
473 
474  // Set default state ---
475 
476  clearCurves();
477  setTransforms(standardSsToWs, csToWs);
478 
479  m_defaultState = true;
480 
482 }
483 
484 //----------------------------------------------------------------------------//
485 
487 {
489 }
490 
491 //----------------------------------------------------------------------------//
492 
493 void FrustumFieldMapping::worldToVoxel(const V3d &wsP, V3d &vsP) const
494 {
495  worldToVoxel(wsP, vsP, 0.0);
496 }
497 
498 //----------------------------------------------------------------------------//
499 
500 void FrustumFieldMapping::worldToVoxel(const V3d &wsP, V3d &vsP, float time) const
501 {
502  V3d lsP;
503  worldToLocal(wsP, lsP, time);
504  localToVoxel(lsP, vsP);
505 }
506 
507 //----------------------------------------------------------------------------//
508 
509 void FrustumFieldMapping::voxelToWorld(const V3d &vsP, V3d &wsP) const
510 {
511  voxelToWorld(vsP, wsP, 0.0);
512 }
513 
514 //----------------------------------------------------------------------------//
515 
516 void FrustumFieldMapping::voxelToWorld(const V3d &vsP, V3d &wsP, float time) const
517 {
518  V3d lsP;
519  voxelToLocal(vsP, lsP);
520  localToWorld(lsP, wsP, time);
521 }
522 
523 //----------------------------------------------------------------------------//
524 
525 void FrustumFieldMapping::worldToLocal(const V3d &wsP, V3d &lsP) const
526 {
527  worldToLocal(wsP, lsP, 0.0);
528 }
529 
530 //----------------------------------------------------------------------------//
531 
532 void FrustumFieldMapping::worldToLocal(const V3d &wsP, V3d &lsP, float time) const
533 {
534  switch (m_zDistribution) {
535  case UniformDistribution:
536  {
537  // First transform to local perspective space
538  V3d lpsP;
539  m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsP, lpsP);
540  // Also transform to camera space
541  V3d csP;
542  m_csToWsCurve.linear(time).inverse().multVecMatrix(wsP, csP);
543  // Interpolate near and far plane at current time
544  double near = m_nearCurve.linear(time);
545  double far = m_farCurve.linear(time);
546  // Use perspective-space X/Y and normalized depth for Z.
547  lsP = V3d(lpsP.x, lpsP.y, FIELD3D_LERPFACTOR(-csP.z, near, far));
548  break;
549  }
551  default:
552  {
553  m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsP, lsP);
554  break;
555  }
556  }
557 }
558 
559 //----------------------------------------------------------------------------//
560 
561 void FrustumFieldMapping::localToWorld(const V3d &lsP, V3d &wsP) const
562 {
563  localToWorld(lsP, wsP, 0.0);
564 }
565 
566 //----------------------------------------------------------------------------//
567 
568 void FrustumFieldMapping::localToWorld(const V3d &lsP, V3d &wsP, float time) const
569 {
570  switch (m_zDistribution) {
571  case UniformDistribution:
572  {
573  // Interpolate near and far plane at current time
574  double near = m_nearCurve.linear(time);
575  double far = m_farCurve.linear(time);
576  // In this case, local space is -not- equal to local perspective space
577  // Determine distance from camera
578  double wsDepthFromCam = FIELD3D_LERP(near, far, lsP.z);
579  // Transform point right in front of camera, X units away into world space
580  V3d lpsCenterP, wsCenterP, csCenterP(0.0, 0.0, -wsDepthFromCam);
581  m_csToWsCurve.linear(time).multVecMatrix(csCenterP, wsCenterP);
582  // Transform center point into screen space so we know what depth
583  // (in screen space) the voxel would live at -if- it were in local
584  // perspective space.
585  m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsCenterP, lpsCenterP);
586  // Now we create a local perspective coordinate that can be transformed
587  // using m_lpsToWsCurve
588  V3d lpsP(lsP.x, lsP.y, lpsCenterP.z);
589  // Now we can use m_lpsToWsCurve to transform the actual voxel location
590  m_lpsToWsCurve.linear(time).multVecMatrix(lpsP, wsP);
591  break;
592  }
594  default:
595  {
596  // In this case, local space and local perspective space are the same.
597  m_lpsToWsCurve.linear(time).multVecMatrix(lsP, wsP);
598  break;
599  }
600  }
601 }
602 
603 //----------------------------------------------------------------------------//
604 
606 {
607  return std::string(classType());
608 }
609 
610 //----------------------------------------------------------------------------//
611 
613  double tolerance) const
614 {
616 
617  if (other->className() != k_frustumMappingName) {
618  return false;
619  } else {
620 
622  FIELD_DYNAMIC_CAST<FrustumFieldMapping>(other);
623 
624  if (fm) {
625 
626  const SampleVec lpsToWs1 = m_lpsToWsCurve.samples();
627  const SampleVec lpsToWs2 = fm->m_lpsToWsCurve.samples();
628  const SampleVec csToWs1 = m_csToWsCurve.samples();
629  const SampleVec csToWs2 = fm->m_csToWsCurve.samples();
630 
631  size_t numSamples = lpsToWs1.size();
632 
633  // Check that slice distributions match
634  if (m_zDistribution != fm->m_zDistribution) {
635  return false;
636  }
637 
638  // First check if time sample counts differ
639  // lpsToWs and csToWs are guaranteed to have same sample count.
640  if (lpsToWs1.size() != lpsToWs2.size()) {
641  return false;
642  }
643 
644  // Then check if all time samples match, then check localToWorld
645  // and voxelToWorld matrices
646  for (size_t i = 0; i < numSamples; ++i) {
647  if (lpsToWs1[i].first != lpsToWs2[i].first) {
648  return false;
649  }
650  if (!checkMatricesIdentical(lpsToWs1[i].second, lpsToWs2[i].second,
651  tolerance)) {
652  return false;
653  }
654  if (!checkMatricesIdentical(csToWs1[i].second, csToWs2[i].second,
655  tolerance)) {
656  return false;
657  }
658  }
659 
660  return true;
661 
662  } else {
663  return false;
664  }
665  }
666  return false;
667 }
668 
669 //----------------------------------------------------------------------------//
670 
671 V3d FrustumFieldMapping::wsVoxelSize(int /*i*/, int /*j*/, int k) const
672 {
673  k = std::min(std::max(k, static_cast<int>(m_origin.z)),
674  static_cast<int>(m_origin.z + m_res.z - 1));
675  return m_wsVoxelSize[k - static_cast<int>(m_origin.z)];
676 }
677 
678 //----------------------------------------------------------------------------//
679 
681 {
682  // Precompute the voxel size ---
683 
684  m_wsVoxelSize.resize(static_cast<int>(m_res.z),V3d(0.0));
685 
686  int i = m_origin.x + m_res.x / 2;
687  int j = m_origin.y + m_res.y / 2;
688 
689  // Do all z slices except last
690  int zMin = static_cast<int>(m_origin.z);
691  int zMax = static_cast<int>(m_origin.z + m_res.z - 1);
692 
693  for (int k = zMin, idx = 0; k < zMax; ++k, ++idx) {
694  V3d wsP, wsPx, wsPy, wsPz;
695  V3d vsP = discToCont(V3i(i, j, k));
696  V3d vsPx = discToCont(V3i(i + 1, j, k));
697  V3d vsPy = discToCont(V3i(i, j + 1, k));
698  V3d vsPz = discToCont(V3i(i, j, k + 1));
699  voxelToWorld(vsP, wsP);
700  voxelToWorld(vsPx, wsPx);
701  voxelToWorld(vsPy, wsPy);
702  voxelToWorld(vsPz, wsPz);
703  m_wsVoxelSize[idx] = V3d((wsPx - wsP).length(),
704  (wsPy - wsP).length(),
705  (wsPz - wsP).length());
706  }
707 
708  // Duplicate last value since there are no further slices to differentiate
709  // against
710  if (m_res.z >= 2) {
711  m_wsVoxelSize[m_res.z - 1] = m_wsVoxelSize[m_res.z - 2];
712  }
713 
714 }
715 
716 //----------------------------------------------------------------------------//
717 
719 {
720  // Local to voxel is a scale by the resolution of the field, offset
721  // to the origin of the extents
722  M44d scaling, translation;
723  scaling.setScale(m_res);
724  translation.setTranslation(m_origin);
725  result = scaling * translation;
726 }
727 
728 //----------------------------------------------------------------------------//
729 
731 {
734  m_nearCurve.clear();
735  m_farCurve.clear();
736 }
737 
738 //----------------------------------------------------------------------------//
739 
741 {
742  return Ptr(new FrustumFieldMapping(*this));
743 }
744 
745 //----------------------------------------------------------------------------//
746 
748 
749 //----------------------------------------------------------------------------//
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Imath::M44d M44d
Definition: SpiMathLib.h:82
Contains typedefs for the commonly used types in Field3D.
size_t numSamples() const
Returns the number of samples in the curve.
Definition: Curve.h:99
V3d m_origin
The integer voxel-space origin of the underlying Field object. Is equal to field.extents.min.
Definition: FieldMapping.h:190
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
const string k_matrixMappingName("MatrixFieldMapping")
FloatCurve m_farCurve
Time-varying far plane. Computed from m_lpsToWsCurve.
Definition: FieldMapping.h:702
void clearCurves()
Clears all Curve data members. Used by setTransforms() to prepare for the first sample to be added...
#define FIELD3D_LERP
Definition: SpiMathLib.h:91
M44d m_vsToWs
Voxel space to world space.
Definition: FieldMapping.h:481
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
MatrixCurve m_vsToWsCurve
Time-varying voxel to world space transform.
Definition: FieldMapping.h:489
FieldMapping()
Constructor.
void setLocalToWorld(const M44d &lsToWs)
Sets the local to world transform. All other matrices will be updated based on this.
virtual void voxelToWorld(const V3d &vsP, V3d &wsP) const
Transform from voxel space position into world space.
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
Definition: FieldMapping.h:161
void getLocalToVoxelMatrix(M44d &result)
virtual void localToWorld(const V3d &lsP, V3d &wsP) const
Transform from local space position into world space.
Base class for mapping between world-, local- and voxel coordinates.
Definition: FieldMapping.h:86
void voxelToLocal(const V3d &vsP, V3d &lsP) const
Inverse of localToVoxel.
MatrixCurve m_lsToWsCurve
Time-varying local to world space transform.
Definition: FieldMapping.h:487
M44d m_lsToWs
Local space to world space.
Definition: FieldMapping.h:475
V3d m_res
The integer voxel-space resolution of the underlying Field object. Is equal to field.extents.max - field.extents.min + 1.
Definition: FieldMapping.h:193
void localToVoxel(const V3d &lsP, V3d &vsP) const
Transform from local space to voxel space. This is just a multiplication by the resolution of the Fie...
Imath::V3i V3i
Definition: SpiMathLib.h:71
virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const
Transform from world space position into voxel space.
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
void computeVoxelSize()
Updates the local to world transformation matrix.
boost::intrusive_ptr< FieldMapping > Ptr
Definition: FieldMapping.h:92
void addSample(const float t, const T &value)
Adds a sample point to the curve.
Definition: Curve.h:172
static const char * classType()
Definition: FieldMapping.h:332
MatrixCurve m_lpsToWsCurve
Time-varying local perspective to world space transform. Computed from m_ssToWsCurve.
Definition: FieldMapping.h:698
std::vector< V3d > m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency...
Definition: FieldMapping.h:706
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
void reset()
Resets the transform. Makes a perspective transform at the origin, looking down the negative Z axis w...
boost::intrusive_ptr< NullFieldMapping > Ptr
Convenience typedef.
Definition: FieldMapping.h:225
static const char * classType()
Definition: FieldMapping.h:567
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
bool m_defaultState
Boolean to tell us if the mapping is in its 'default' state. This is needed because the class has a d...
Definition: FieldMapping.h:712
Imath::V3d V3d
Definition: SpiMathLib.h:74
MatrixCurve m_ssToWsCurve
Time-varying local perspective to world space transform This is not used in calculations, but rather as the public interface to the class.
Definition: FieldMapping.h:693
static const char * classType()
Definition: FieldMapping.h:99
virtual ~FieldMapping()
Destructor.
Contains the FieldMapping base class and the NullFieldMapping and MatrixFieldMapping subclasses...
const SampleVec & samples() const
Returns a const reference to the samples in the curve.
Definition: Curve.h:103
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
const string k_mappingName("FieldMapping")
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
virtual void worldToLocal(const V3d &wsP, V3d &lsP) const
Transform from world space position into local space.
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
#define FIELD3D_EXTRACT_SHRT
Definition: SpiMathLib.h:93
FloatCurve m_nearCurve
Time-varying near plane. Computed from m_lpsToWsCurve.
Definition: FieldMapping.h:700
Contains Field, WritableField and ResizableField classes.
T linear(const float t) const
Linearly interpolates a value from the curve.
Definition: Curve.h:199
void getLocalToVoxelMatrix(M44d &result)
virtual V3d wsVoxelSize(int i, int j, int k) const
Returns world-space size of a voxel at the specified coordinate.
void setTransforms(const M44d &ssToWs, const M44d &csToWs)
Sets the screenToWorld and cameraToWorld transforms. All other internal matrices will be updated base...
MatrixCurve m_csToWsCurve
Time-varying camera to world space transform.
Definition: FieldMapping.h:695
bool m_isTimeVarying
Stores whether the curve has more than one time sample.
Definition: FieldMapping.h:493
void makeIdentity()
Sets the transform to identity. This makes it functionally equivalent to a NullFieldMapping.
void updateTransform()
Updates the local to world transformation matrix.
const string k_nullMappingName("NullFieldMapping")
virtual std::string className() const =0
Returns the FieldMapping type name. Used when writing/reading from disk.
std::vector< Sample > SampleVec
Definition: Curve.h:85
ZDistribution m_zDistribution
Slice distribution type.
Definition: FieldMapping.h:688
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
V3d m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency...
Definition: FieldMapping.h:497
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
void clear()
Clears all samples in curve.
Definition: Curve.h:107
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
Definition: FieldMapping.h:323
M44d m_wsToLs
World space to local space.
Definition: FieldMapping.h:478
bool checkMatricesIdentical(const Matrix_T &m1, const Matrix_T &m2, double tolerance)
boost::intrusive_ptr< FrustumFieldMapping > Ptr
Convenience typedef.
Definition: FieldMapping.h:543
const string k_frustumMappingName("FrustumFieldMapping")
M44d m_wsToVs
World space to voxel space.
Definition: FieldMapping.h:484
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel...
Definition: Field.h:1027
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
void setExtents(const Box3i &extents)
This sets the field extents information to use for defining the local coordinate space.
#define FIELD3D_LERPFACTOR
Definition: SpiMathLib.h:92
#define FIELD3D_NAMESPACE_OPEN
Definition: ns.h:56
static const char * classType()
Definition: FieldMapping.h:232