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 #ifdef WIN32
53 #define isnan(__x__) _isnan(__x__)
54 #endif
55 
56 //----------------------------------------------------------------------------//
57 
58 using namespace boost;
59 using namespace std;
60 
61 //----------------------------------------------------------------------------//
62 
64 
65 //----------------------------------------------------------------------------//
66 // Field3D namespaces
67 //----------------------------------------------------------------------------//
68 
69 
70 //----------------------------------------------------------------------------//
71 // Local namespace
72 //----------------------------------------------------------------------------//
73 
74 namespace {
75 
76  // Strings ---
77 
78  const string k_mappingName("FieldMapping");
79  const string k_nullMappingName("NullFieldMapping");
80  const string k_matrixMappingName("MatrixFieldMapping");
81  const string k_frustumMappingName("FrustumFieldMapping");
82 
83  // Functions ---
84 
85  template <class Matrix_T>
86  bool checkMatricesIdentical(const Matrix_T &m1, const Matrix_T &m2,
87  double tolerance)
88  {
89  if (m1.equalWithRelError(m2, tolerance)) {
90  return true;
91  }
92  V3d s1, r1, t1, sh1, s2, r2, t2, sh2;
93  if (!FIELD3D_EXTRACT_SHRT(m1, s1, sh1, r1, t1, false)) {
94  return false;
95  }
96  if (!FIELD3D_EXTRACT_SHRT(m2, s2, sh2, r2, t2, false)) {
97  return false;
98  }
99  if (!s1.equalWithRelError(s2, tolerance) ||
100  !r1.equalWithAbsError(r2, tolerance) ||
101  !t1.equalWithRelError(t2, tolerance)) {
102  return false;
103  }
104  return true;
105  }
106 
107 }
108 
109 //----------------------------------------------------------------------------//
110 // FieldMapping
111 //----------------------------------------------------------------------------//
112 
114  : RefBase(),
115  m_origin(V3i(0)),
116  m_res(V3i(1))
117 {
118  /* Empty */
119 }
120 
121 //----------------------------------------------------------------------------//
122 
124  : RefBase()
125 {
126  setExtents(extents);
127 }
128 
129 //----------------------------------------------------------------------------//
130 
132 {
133  /* Empty */
134 }
135 
136 //----------------------------------------------------------------------------//
137 
138 
139 std::string FieldMapping::className() const
140 {
141  return std::string(staticClassType());
142 }
143 
144 //----------------------------------------------------------------------------//
145 
146 void FieldMapping::setExtents(const Box3i &extents)
147 {
148  m_origin = extents.min;
149  m_res = extents.max - extents.min + V3i(1);
150  extentsChanged();
151 }
152 
153 //----------------------------------------------------------------------------//
154 
155 void FieldMapping::localToVoxel(const V3d &lsP, V3d &vsP) const
156 {
157  vsP = m_origin + lsP * m_res;
158 }
159 
160 //----------------------------------------------------------------------------//
161 
162 void FieldMapping::voxelToLocal(const V3d &vsP, V3d &lsP) const
163 {
164  lsP.x = FIELD3D_LERPFACTOR(vsP.x, m_origin.x, m_origin.x + m_res.x);
165  lsP.y = FIELD3D_LERPFACTOR(vsP.y, m_origin.y, m_origin.y + m_res.y);
166  lsP.z = FIELD3D_LERPFACTOR(vsP.z, m_origin.z, m_origin.z + m_res.z);
167 }
168 
169 //----------------------------------------------------------------------------//
170 // Utilities
171 //----------------------------------------------------------------------------//
172 
173 void worldToVoxel(const Field3D::FieldMapping* mapping,
174  const Box3d &wsBounds,
175  Box3d &vsBounds)
176 {
177  V3d test1, test2;
178  mapping->worldToVoxel(test1, test2);
180  V3d wsVerts[] = {
181  V3d(wsBounds.min.x, wsBounds.min.y, wsBounds.min.z),
182  V3d(wsBounds.max.x, wsBounds.min.y, wsBounds.min.z),
183  V3d(wsBounds.min.x, wsBounds.max.y, wsBounds.min.z),
184  V3d(wsBounds.max.x, wsBounds.max.y, wsBounds.min.z),
185  V3d(wsBounds.min.x, wsBounds.min.y, wsBounds.max.z),
186  V3d(wsBounds.max.x, wsBounds.min.y, wsBounds.max.z),
187  V3d(wsBounds.min.x, wsBounds.max.y, wsBounds.max.z),
188  V3d(wsBounds.max.x, wsBounds.max.y, wsBounds.max.z)
189  };
190  vsBounds.makeEmpty();
191  V3d vsP;
192  for (int i = 0; i < 8; i++) {
193  mapping->worldToVoxel(wsVerts[i], vsP);
194  vsBounds.extendBy(vsP);
195  }
196 }
197 
198 //----------------------------------------------------------------------------//
199 // NullFieldMapping
200 //----------------------------------------------------------------------------//
201 
202 std::string NullFieldMapping::className() const
203 {
204  return std::string(staticClassType());
205 }
206 
207 //----------------------------------------------------------------------------//
208 
210  double /* tolerance */) const
211 {
212  // For null mappings it's simple - if the other one is also a null mapping
213  // then true, otherwise it's false.
214 
215  return other->className() == k_nullMappingName;
216 }
217 
218 //----------------------------------------------------------------------------//
219 
221 {
222  return Ptr(new NullFieldMapping(*this));
223 }
224 
225 //----------------------------------------------------------------------------//
226 // MatrixFieldMapping
227 //----------------------------------------------------------------------------//
228 
230  : FieldMapping()
231 {
232  makeIdentity();
233 }
234 
235 //----------------------------------------------------------------------------//
236 
238  : FieldMapping(extents)
239 {
240  makeIdentity();
241 }
242 
243 //----------------------------------------------------------------------------//
244 
246 {
247  if (m_lsToWsCurve.numSamples() > 0) {
248  makeIdentity();
249  }
250  setLocalToWorld(0.0f, lsToWs);
251 }
252 
253 //----------------------------------------------------------------------------//
254 
255 void MatrixFieldMapping::setLocalToWorld(float t, const M44d &lsToWs)
256 {
257  m_lsToWsCurve.addSample(t, lsToWs);
258  updateTransform();
259 }
260 
261 //----------------------------------------------------------------------------//
262 
264 {
266  updateTransform();
267 }
268 
269 //----------------------------------------------------------------------------//
270 
272 {
273  updateTransform();
274 }
275 
276 //----------------------------------------------------------------------------//
277 
278 std::string MatrixFieldMapping::className() const
279 {
280  return std::string(staticClassType());
281 }
282 
283 //----------------------------------------------------------------------------//
284 
286  double tolerance) const
287 {
289 
290  if (other->className() != k_matrixMappingName) {
291  return false;
292  } else {
293 
295  FIELD_DYNAMIC_CAST<MatrixFieldMapping>(other);
296 
297  if (mm) {
298 
299  const SampleVec lsToWs1 = m_lsToWsCurve.samples();
300  const SampleVec lsToWs2 = mm->m_lsToWsCurve.samples();
301  const SampleVec vsToWs1 = m_vsToWsCurve.samples();
302  const SampleVec vsToWs2 = mm->m_vsToWsCurve.samples();
303 
304  size_t numSamples = lsToWs1.size();
305 
306  // First check if time sample counts differ
307  // lsToWs and vsToWs are guaranteed to have same sample count.
308  if (lsToWs1.size() != lsToWs2.size()) {
309  return false;
310  }
311 
312  // Then check if all time samples match, then check localToWorld
313  // and voxelToWorld matrices
314  for (size_t i = 0; i < numSamples; ++i) {
315  if (lsToWs1[i].first != lsToWs2[i].first) {
316  return false;
317  }
318  if (!checkMatricesIdentical(lsToWs1[i].second, lsToWs2[i].second,
319  tolerance)) {
320  return false;
321  }
322  if (!checkMatricesIdentical(vsToWs1[i].second, vsToWs2[i].second,
323  tolerance)) {
324  return false;
325  }
326  }
327 
328  return true;
329 
330  } else {
331  return false;
332  }
333  }
334  return false;
335 }
336 
337 //----------------------------------------------------------------------------//
338 
340 {
341  typedef MatrixCurve::SampleVec::const_iterator SampleIter;
342 
343  // Build the voxel to world space transforms ---
344  M44d lsToVs;
345  getLocalToVoxelMatrix(lsToVs);
346  M44d vsToLs = lsToVs.inverse();
347  // Loop over all samples in lsToWs, append vsToLs and create new curve
348  // Also handle the special case where lsToWs has no samples. In that
349  // case m_vsToWsCurve still has to have one sample.
350  const MatrixCurve::SampleVec &lsToWs = m_lsToWsCurve.samples();
352  for (SampleIter i = lsToWs.begin(), end = lsToWs.end(); i != end; i++) {
353  m_vsToWsCurve.addSample(i->first, vsToLs * i->second);
354  }
355 
356  // See if the curve has more than just a single sample
358 
359  // Sample the time-varying transforms at time=0.0
361  m_wsToLs = m_lsToWs.inverse();
362  m_vsToWs = vsToLs * m_lsToWs;
363  m_wsToVs = m_vsToWs.inverse();
364 
365  // Precompute the voxel size
366  V3d voxelOrigin, nextVoxel;
367  m_vsToWs.multVecMatrix(V3d(0, 0, 0), voxelOrigin);
368  m_vsToWs.multVecMatrix(V3d(1, 0, 0), nextVoxel);
369  m_wsVoxelSize.x = (nextVoxel - voxelOrigin).length();
370  m_vsToWs.multVecMatrix(V3d(0, 1, 0), nextVoxel);
371  m_wsVoxelSize.y = (nextVoxel - voxelOrigin).length();
372  m_vsToWs.multVecMatrix(V3d(0, 0, 1), nextVoxel);
373  m_wsVoxelSize.z = (nextVoxel - voxelOrigin).length();
374 }
375 
376 //----------------------------------------------------------------------------//
377 
379 {
380  // Local to voxel is a scale by the resolution of the field, offset
381  // to the origin of the extents
382  M44d scaling, translation;
383  scaling.setScale(m_res);
384  translation.setTranslation(m_origin);
385  result = scaling * translation;
386 }
387 
388 //----------------------------------------------------------------------------//
389 
391 {
392  return Ptr(new MatrixFieldMapping(*this));
393 }
394 
395 //----------------------------------------------------------------------------//
396 // FrustumFieldMapping
397 //----------------------------------------------------------------------------//
398 
400  : FieldMapping(),
401  m_zDistribution(PerspectiveDistribution),
402  m_defaultState(true)
403 {
404  reset();
405 }
406 
407 //----------------------------------------------------------------------------//
408 
410  : FieldMapping(extents)
411 {
412  reset();
413 }
414 
415 //----------------------------------------------------------------------------//
416 
417 void FrustumFieldMapping::setTransforms(const M44d &ssToWs, const M44d &csToWs)
418 {
419  setTransforms(0.0, ssToWs, csToWs);
420 }
421 
422 //----------------------------------------------------------------------------//
423 
425  const M44d &ssToWs, const M44d &csToWs)
426 {
427  if (m_defaultState) {
428  clearCurves();
429  m_defaultState = false;
430  }
431 
432  // Construct local-to-world transform from ssToWs
433  M44d lsToSs, scale, translation;
434  scale.setScale(V3d(2.0, 2.0, 1.0));
435  translation.setTranslation(V3d(-1.0, -1.0, 0.0));
436  lsToSs = scale * translation;
437  M44d lpsToWs = lsToSs * ssToWs;
438 
439  // Add samples to Curves
440  m_ssToWsCurve.addSample(t, ssToWs);
441  m_lpsToWsCurve.addSample(t, lpsToWs);
442  m_csToWsCurve.addSample(t, csToWs);
443 
444  // Compute near and far planes ---
445 
446  // Because the frustum may be skewed we can't just measure distance from
447  // the apex of the frustum to the world-space center point of the frustum.
448  // Instead, we transform into camera space and measure z depth there.
449 
450  V3d lsNearP(0.5, 0.5, 0.0), lsFarP(0.5, 0.5, 1.0);
451  V3d wsNearP, wsFarP, csNearP, csFarP;
452 
453  lpsToWs.multVecMatrix(lsNearP, wsNearP);
454  lpsToWs.multVecMatrix(lsFarP, wsFarP);
455 
456  M44d wsToCs = csToWs.inverse();
457  wsToCs.multVecMatrix(wsNearP, csNearP);
458  wsToCs.multVecMatrix(wsFarP, csFarP);
459 
460  double near = -csNearP.z;
461  double far = -csFarP.z;
462 
463  // Catch NaN here
464  if (isnan(near) || isnan(far)) {
465  throw BadPerspectiveMatrix("FrustumFieldMapping::setTransforms "
466  "received bad screen-to-world matrix");
467  }
468 
469  m_nearCurve.addSample(t, near);
470  m_farCurve.addSample(t, far);
471 
473 }
474 
475 //----------------------------------------------------------------------------//
476 
478 {
479  // Default camera to world ---
480 
481  M44d csToWs;
482  csToWs.makeIdentity();
483 
484  // Default screen to world ---
485 
486  double near = 1;
487  double far = 2;
488  double fovRadians = 45.0 * M_PI / 180.0;
489  double invTan = 1.0 / std::tan(fovRadians / 2.0);
490  double imageAspectRatio = 1.0;
491 
492  M44d perspective(1, 0, 0, 0,
493  0, 1, 0, 0,
494  0, 0, (far) / (far - near), 1,
495  0, 0, (- far * near) / (far - near), 0);
496 
497  M44d fov;
498  fov.setScale(V3d(invTan / imageAspectRatio, invTan, 1.0));
499 
500  M44d flipZ;
501  flipZ.setScale(V3d(1.0, 1.0, -1.0));
502 
503  M44d csToSs = flipZ * perspective * fov;
504 
505  M44d standardSsToWs = csToSs.inverse() * csToWs;
506 
507  // Set default state ---
508 
509  clearCurves();
510  setTransforms(standardSsToWs, csToWs);
511 
512  m_defaultState = true;
513 
515 }
516 
517 //----------------------------------------------------------------------------//
518 
520 {
522 }
523 
524 //----------------------------------------------------------------------------//
525 
526 void FrustumFieldMapping::worldToVoxel(const V3d &wsP, V3d &vsP) const
527 {
528  worldToVoxel(wsP, vsP, 0.0);
529 }
530 
531 //----------------------------------------------------------------------------//
532 
533 void FrustumFieldMapping::worldToVoxel(const V3d &wsP, V3d &vsP, float time) const
534 {
535  V3d lsP;
536  worldToLocal(wsP, lsP, time);
537  localToVoxel(lsP, vsP);
538 }
539 
540 //----------------------------------------------------------------------------//
541 
542 void FrustumFieldMapping::voxelToWorld(const V3d &vsP, V3d &wsP) const
543 {
544  voxelToWorld(vsP, wsP, 0.0);
545 }
546 
547 //----------------------------------------------------------------------------//
548 
549 void FrustumFieldMapping::voxelToWorld(const V3d &vsP, V3d &wsP, float time) const
550 {
551  V3d lsP;
552  voxelToLocal(vsP, lsP);
553  localToWorld(lsP, wsP, time);
554 }
555 
556 //----------------------------------------------------------------------------//
557 
558 void FrustumFieldMapping::worldToLocal(const V3d &wsP, V3d &lsP) const
559 {
560  worldToLocal(wsP, lsP, 0.0);
561 }
562 
563 //----------------------------------------------------------------------------//
564 
565 void FrustumFieldMapping::worldToLocal(const V3d &wsP, V3d &lsP, float time) const
566 {
567  switch (m_zDistribution) {
568  case UniformDistribution:
569  {
570  // First transform to local perspective space
571  V3d lpsP;
572  m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsP, lpsP);
573  // Also transform to camera space
574  V3d csP;
575  m_csToWsCurve.linear(time).inverse().multVecMatrix(wsP, csP);
576  // Interpolate near and far plane at current time
577  double near = m_nearCurve.linear(time);
578  double far = m_farCurve.linear(time);
579  // Use perspective-space X/Y and normalized depth for Z.
580  lsP = V3d(lpsP.x, lpsP.y, FIELD3D_LERPFACTOR(-csP.z, near, far));
581  break;
582  }
584  default:
585  {
586  m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsP, lsP);
587  break;
588  }
589  }
590 }
591 
592 //----------------------------------------------------------------------------//
593 
594 void FrustumFieldMapping::localToWorld(const V3d &lsP, V3d &wsP) const
595 {
596  localToWorld(lsP, wsP, 0.0);
597 }
598 
599 //----------------------------------------------------------------------------//
600 
601 void FrustumFieldMapping::localToWorld(const V3d &lsP, V3d &wsP, float time) const
602 {
603  switch (m_zDistribution) {
604  case UniformDistribution:
605  {
606  // Interpolate near and far plane at current time
607  double near = m_nearCurve.linear(time);
608  double far = m_farCurve.linear(time);
609  // In this case, local space is -not- equal to local perspective space
610  // Determine distance from camera
611  double wsDepthFromCam = FIELD3D_LERP(near, far, lsP.z);
612  // Transform point right in front of camera, X units away into world space
613  V3d lpsCenterP, wsCenterP, csCenterP(0.0, 0.0, -wsDepthFromCam);
614  m_csToWsCurve.linear(time).multVecMatrix(csCenterP, wsCenterP);
615  // Transform center point into screen space so we know what depth
616  // (in screen space) the voxel would live at -if- it were in local
617  // perspective space.
618  m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsCenterP, lpsCenterP);
619  // Now we create a local perspective coordinate that can be transformed
620  // using m_lpsToWsCurve
621  V3d lpsP(lsP.x, lsP.y, lpsCenterP.z);
622  // Now we can use m_lpsToWsCurve to transform the actual voxel location
623  m_lpsToWsCurve.linear(time).multVecMatrix(lpsP, wsP);
624  break;
625  }
627  default:
628  {
629  // In this case, local space and local perspective space are the same.
630  m_lpsToWsCurve.linear(time).multVecMatrix(lsP, wsP);
631  break;
632  }
633  }
634 }
635 
636 //----------------------------------------------------------------------------//
637 
639 {
640  return std::string(staticClassType());
641 }
642 
643 //----------------------------------------------------------------------------//
644 
646  double tolerance) const
647 {
649 
650  if (other->className() != k_frustumMappingName) {
651  return false;
652  } else {
653 
655  FIELD_DYNAMIC_CAST<FrustumFieldMapping>(other);
656 
657  if (fm) {
658 
659  const SampleVec lpsToWs1 = m_lpsToWsCurve.samples();
660  const SampleVec lpsToWs2 = fm->m_lpsToWsCurve.samples();
661  const SampleVec csToWs1 = m_csToWsCurve.samples();
662  const SampleVec csToWs2 = fm->m_csToWsCurve.samples();
663 
664  size_t numSamples = lpsToWs1.size();
665 
666  // Check that slice distributions match
667  if (m_zDistribution != fm->m_zDistribution) {
668  return false;
669  }
670 
671  // First check if time sample counts differ
672  // lpsToWs and csToWs are guaranteed to have same sample count.
673  if (lpsToWs1.size() != lpsToWs2.size()) {
674  return false;
675  }
676 
677  // Then check if all time samples match, then check localToWorld
678  // and voxelToWorld matrices
679  for (size_t i = 0; i < numSamples; ++i) {
680  if (lpsToWs1[i].first != lpsToWs2[i].first) {
681  return false;
682  }
683  if (!checkMatricesIdentical(lpsToWs1[i].second, lpsToWs2[i].second,
684  tolerance)) {
685  return false;
686  }
687  if (!checkMatricesIdentical(csToWs1[i].second, csToWs2[i].second,
688  tolerance)) {
689  return false;
690  }
691  }
692 
693  return true;
694 
695  } else {
696  return false;
697  }
698  }
699  return false;
700 }
701 
702 //----------------------------------------------------------------------------//
703 
704 V3d FrustumFieldMapping::wsVoxelSize(int /*i*/, int /*j*/, int k) const
705 {
706  k = std::min(std::max(k, static_cast<int>(m_origin.z)),
707  static_cast<int>(m_origin.z + m_res.z - 1));
708  return m_wsVoxelSize[k - static_cast<int>(m_origin.z)];
709 }
710 
711 //----------------------------------------------------------------------------//
712 
714 {
715  // Precompute the voxel size ---
716 
717  m_wsVoxelSize.resize(static_cast<int>(m_res.z),V3d(0.0));
718 
719  int i = static_cast<int>(m_origin.x + m_res.x / 2);
720  int j = static_cast<int>(m_origin.y + m_res.y / 2);
721 
722  // Do all z slices except last
723  int zMin = static_cast<int>(m_origin.z);
724  int zMax = static_cast<int>(m_origin.z + m_res.z - 1);
725 
726  for (int k = zMin, idx = 0; k < zMax; ++k, ++idx) {
727  V3d wsP, wsPx, wsPy, wsPz;
728  V3d vsP = discToCont(V3i(i, j, k));
729  V3d vsPx = discToCont(V3i(i + 1, j, k));
730  V3d vsPy = discToCont(V3i(i, j + 1, k));
731  V3d vsPz = discToCont(V3i(i, j, k + 1));
732  voxelToWorld(vsP, wsP);
733  voxelToWorld(vsPx, wsPx);
734  voxelToWorld(vsPy, wsPy);
735  voxelToWorld(vsPz, wsPz);
736  m_wsVoxelSize[idx] = V3d((wsPx - wsP).length(),
737  (wsPy - wsP).length(),
738  (wsPz - wsP).length());
739  }
740 
741  // Duplicate last value since there are no further slices to differentiate
742  // against
743  if (m_res.z >= 2) {
744  m_wsVoxelSize[static_cast<int>(m_res.z - 1)] = m_wsVoxelSize[static_cast<int>(m_res.z - 2)];
745  }
746 
747 }
748 
749 //----------------------------------------------------------------------------//
750 
752 {
753  // Local to voxel is a scale by the resolution of the field, offset
754  // to the origin of the extents
755  M44d scaling, translation;
756  scaling.setScale(m_res);
757  translation.setTranslation(m_origin);
758  result = scaling * translation;
759 }
760 
761 //----------------------------------------------------------------------------//
762 
764 {
767  m_nearCurve.clear();
768  m_farCurve.clear();
769 }
770 
771 //----------------------------------------------------------------------------//
772 
774 {
775  return Ptr(new FrustumFieldMapping(*this));
776 }
777 
778 //----------------------------------------------------------------------------//
779 
781 
782 //----------------------------------------------------------------------------//
Trivial class, world space is equal to local space, i.e. the field is contained in the unit cube [0...
Definition: FieldMapping.h:229
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:713
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:492
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
static const char * staticClassType()
Definition: FieldMapping.h:99
MatrixCurve m_vsToWsCurve
Time-varying voxel to world space transform.
Definition: FieldMapping.h:500
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:498
M44d m_lsToWs
Local space to world space.
Definition: FieldMapping.h:486
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
static const char * staticClassType()
Definition: FieldMapping.h:578
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
MatrixCurve m_lpsToWsCurve
Time-varying local perspective to world space transform. Computed from m_ssToWsCurve.
Definition: FieldMapping.h:709
std::vector< V3d > m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency...
Definition: FieldMapping.h:717
virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const =0
Transform from world space position into voxel space.
Imath::Box3d Box3d
Definition: SpiMathLib.h:79
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...
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 &#39;default&#39; state. This is needed because the class has a d...
Definition: FieldMapping.h:723
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:704
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.
static const char * staticClassType()
Definition: FieldMapping.h:343
#define FIELD3D_EXTRACT_SHRT
Definition: SpiMathLib.h:93
FloatCurve m_nearCurve
Time-varying near plane. Computed from m_lpsToWsCurve.
Definition: FieldMapping.h:711
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:706
bool m_isTimeVarying
Stores whether the curve has more than one time sample.
Definition: FieldMapping.h:504
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:699
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:508
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:334
M44d m_wsToLs
World space to local space.
Definition: FieldMapping.h:489
bool checkMatricesIdentical(const Matrix_T &m1, const Matrix_T &m2, double tolerance)
boost::intrusive_ptr< FrustumFieldMapping > Ptr
Convenience typedef.
Definition: FieldMapping.h:554
const string k_frustumMappingName("FrustumFieldMapping")
M44d m_wsToVs
World space to voxel space.
Definition: FieldMapping.h:495
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel...
Definition: Field.h:1075
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