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 //----------------------------------------------------------------------------//
Trivial class, world space is equal to local space, i.e. the field is contained in the unit cube [0...
Definition: FieldMapping.h:218
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
T linear(const float t) const
Linearly interpolates a value from the curve.
Definition: Curve.h:199
Imath::M44d M44d
Definition: SpiMathLib.h:82
Contains typedefs for the commonly used types in Field3D.
V3d m_origin
The integer voxel-space origin of the underlying Field object. Is equal to field.extents.min.
Definition: FieldMapping.h:190
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
const string k_matrixMappingName("MatrixFieldMapping")
FloatCurve m_farCurve
Time-varying far plane. Computed from m_lpsToWsCurve.
Definition: FieldMapping.h:702
virtual V3d wsVoxelSize(int i, int j, int k) const
Returns world-space size of a voxel at the specified coordinate.
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
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 FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
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 extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
Definition: FieldMapping.h:161
size_t numSamples() const
Returns the number of samples in the curve.
Definition: Curve.h:99
void getLocalToVoxelMatrix(M44d &result)
Base class for mapping between world-, local- and voxel coordinates.
Definition: FieldMapping.h:86
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
virtual void worldToLocal(const V3d &wsP, V3d &lsP) const
Transform from world space position into local space.
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
const SampleVec & samples() const
Returns a const reference to the samples in the curve.
Definition: Curve.h:103
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
Imath::V3i V3i
Definition: SpiMathLib.h:71
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
void reset()
Resets the transform. Makes a perspective transform at the origin, looking down the negative Z axis w...
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
static const char * classType()
Definition: FieldMapping.h:567
bool m_defaultState
Boolean to tell us if the mapping is in its &#39;default&#39; 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...
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
const string k_mappingName("FieldMapping")
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
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...
virtual void voxelToWorld(const V3d &vsP, V3d &wsP) const
Transform from voxel space position into world space.
Contains Field, WritableField and ResizableField classes.
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
void getLocalToVoxelMatrix(M44d &result)
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.
virtual void localToWorld(const V3d &lsP, V3d &wsP) const
Transform from local space position into world space.
virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const
Transform from world space position into voxel space.
std::vector< Sample > SampleVec
Definition: Curve.h:85
ZDistribution m_zDistribution
Slice distribution type.
Definition: FieldMapping.h:688
V3d m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency...
Definition: FieldMapping.h:497
void clear()
Clears all samples in curve.
Definition: Curve.h:107
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
Definition: FieldMapping.h:323
void voxelToLocal(const V3d &vsP, V3d &lsP) const
Inverse of localToVoxel.
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
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel...
Definition: Field.h:1027
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