Field3D
FieldMapping.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------//
00002 
00003 /*
00004  * Copyright (c) 2009 Sony Pictures Imageworks Inc
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  *
00012  * Redistributions of source code must retain the above copyright
00013  * notice, this list of conditions and the following disclaimer.
00014  * Redistributions in binary form must reproduce the above copyright
00015  * notice, this list of conditions and the following disclaimer in the
00016  * documentation and/or other materials provided with the
00017  * distribution.  Neither the name of Sony Pictures Imageworks nor the
00018  * names of its contributors may be used to endorse or promote
00019  * products derived from this software without specific prior written
00020  * permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
00026  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00029  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00031  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00033  * OF THE POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 //----------------------------------------------------------------------------//
00037 
00044 //----------------------------------------------------------------------------//
00045 
00046 #ifndef _INCLUDED_Field3D_FieldMapping_H_
00047 #define _INCLUDED_Field3D_FieldMapping_H_
00048 
00049 #include <vector>
00050 #include <algorithm>
00051 
00052 #include "Curve.h"
00053 #include "Exception.h"
00054 #include "RefCount.h"
00055 #include "Types.h"
00056 
00057 //----------------------------------------------------------------------------//
00058 
00059 #include "ns.h"
00060 
00061 FIELD3D_NAMESPACE_OPEN
00062 
00063 //----------------------------------------------------------------------------//
00064 // FieldMapping
00065 //----------------------------------------------------------------------------//
00066 
00084 //----------------------------------------------------------------------------//
00085 
00086 class FieldMapping : public RefBase
00087 {
00088  public:
00089 
00090   // Typedefs ------------------------------------------------------------------
00091 
00092   typedef boost::intrusive_ptr<FieldMapping> Ptr;
00093 
00094   // RTTI replacement ----------------------------------------------------------
00095 
00096   typedef FieldMapping class_type;
00097   DEFINE_FIELD_RTTI_ABSTRACT_CLASS;
00098   
00099   static const char* classType()
00100   {
00101     return "FieldMapping";
00102   }
00103 
00104   // Ctors, dtor ---------------------------------------------------------------
00105 
00108 
00110   FieldMapping();
00112   FieldMapping(const Box3i &extents);
00114   virtual ~FieldMapping();
00115 
00117 
00118   // Main methods --------------------------------------------------------------
00119 
00125   void setExtents(const Box3i &extents);
00126 
00128   const V3d& origin() const
00129   { return m_origin; }
00131   const V3d& resolution() const
00132   { return m_res; }
00133   
00134   // To be implemented by subclasses -------------------------------------------
00135 
00138 
00141   virtual Ptr clone() const = 0;
00142 
00144   virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const = 0;
00145   virtual void worldToVoxel(const V3d &wsP, V3d &vsP, float time) const = 0;
00147   virtual void voxelToWorld(const V3d &vsP, V3d &wsP) const = 0;
00148   virtual void voxelToWorld(const V3d &vsP, V3d &wsP, float time) const = 0;
00150   virtual void worldToLocal(const V3d &wsP, V3d &lsP) const = 0;
00151   virtual void worldToLocal(const V3d &wsP, V3d &lsP, float time) const = 0;
00153   virtual void localToWorld(const V3d &lsP, V3d &wsP) const = 0;
00154   virtual void localToWorld(const V3d &lsP, V3d &wsP, float time) const = 0;
00155 
00157   virtual V3d wsVoxelSize(int i, int j, int k) const = 0;
00158 
00161   virtual void extentsChanged()
00162   { /* Empty */ }
00163   
00165   virtual std::string className() const = 0;
00166 
00168   virtual bool isIdentical(FieldMapping::Ptr other, 
00169                            double tolerance = 0.0) const = 0;
00170 
00172 
00173   // Transform calls -----------------------------------------------------------
00174 
00177 
00180   void localToVoxel(const V3d &lsP, V3d &vsP) const;
00182   void voxelToLocal(const V3d &vsP, V3d &lsP) const;
00183 
00185   
00186 protected:
00187 
00190   V3d m_origin;
00193   V3d m_res;
00194 
00195 private:
00196 
00197   // Typedefs ------------------------------------------------------------------
00198 
00200   typedef RefBase base;  
00201 
00202 };
00203 
00204 //----------------------------------------------------------------------------//
00205 // NullFieldMapping
00206 //----------------------------------------------------------------------------//
00207 
00216 //----------------------------------------------------------------------------//
00217 
00218 class NullFieldMapping : public FieldMapping
00219 {
00220 public:
00221 
00222   // Typedefs ------------------------------------------------------------------
00223 
00225   typedef boost::intrusive_ptr<NullFieldMapping> Ptr;
00226 
00227   // RTTI replacement ----------------------------------------------------------
00228 
00229   typedef NullFieldMapping class_type;
00230   DEFINE_FIELD_RTTI_CONCRETE_CLASS;
00231   
00232   static const char* classType()
00233   {
00234     return "NullFieldMapping";
00235   }
00236 
00237   // Ctors, dtor ---------------------------------------------------------------
00238 
00241 
00242   NullFieldMapping()
00243     : FieldMapping()
00244   { /* Empty */ }
00245   NullFieldMapping(const Box3i &extents)
00246     : FieldMapping(extents)
00247   { /* Empty */ }
00248 
00250 
00251   // From FieldMapping ---------------------------------------------------------
00252 
00255 
00256   virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const 
00257   { localToVoxel(wsP, vsP); }
00258   virtual void worldToVoxel(const V3d &wsP, V3d &vsP, float /*time*/) const 
00259   { localToVoxel(wsP, vsP); }
00260 
00261   virtual void voxelToWorld(const V3d &vsP, V3d &wsP) const 
00262   { voxelToLocal(vsP, wsP); }
00263   virtual void voxelToWorld(const V3d &vsP, V3d &wsP, float /*time*/) const 
00264   { voxelToLocal(vsP, wsP); }
00265 
00266   virtual void worldToLocal(const V3d &wsP, V3d &lsP) const 
00267   { lsP = wsP; }
00268   virtual void worldToLocal(const V3d &wsP, V3d &lsP, float /*time*/) const 
00269   { lsP = wsP; }
00270 
00271   virtual void localToWorld(const V3d &lsP, V3d &wsP) const 
00272   { wsP = lsP; }
00273   virtual void localToWorld(const V3d &lsP, V3d &wsP, float /*time*/) const 
00274   { wsP = lsP; }
00275 
00276   virtual std::string className() const;
00277 
00278   virtual bool isIdentical(FieldMapping::Ptr other, 
00279                            double tolerance = 0.0) const;
00280 
00281   virtual V3d wsVoxelSize(int /*i*/, int /*j*/, int /*k*/) const
00282   { return V3d(1.0 / m_res.x, 1.0 / m_res.y, 1.0 / m_res.z); }
00283 
00284   virtual FieldMapping::Ptr clone() const;
00285 
00287   
00288 private:
00289 
00290   // Typedefs ------------------------------------------------------------------
00291 
00293   typedef FieldMapping base;  
00294 
00295 };
00296 
00297 //----------------------------------------------------------------------------//
00298 // MatrixFieldMapping
00299 //----------------------------------------------------------------------------//
00300 
00314 //----------------------------------------------------------------------------//
00315 
00316 class MatrixFieldMapping : public FieldMapping
00317 {
00318 public:
00319 
00320   // Typedefs ------------------------------------------------------------------
00321 
00323   typedef boost::intrusive_ptr<MatrixFieldMapping> Ptr;
00325   typedef Curve<Imath::M44d> MatrixCurve;
00326 
00327   // RTTI replacement ----------------------------------------------------------
00328 
00329   typedef MatrixFieldMapping class_type;
00330   DEFINE_FIELD_RTTI_CONCRETE_CLASS;
00331   
00332   static const char* classType ()
00333   {
00334     return "MatrixFieldMapping";
00335   }
00336 
00337   // Ctors, dtor ---------------------------------------------------------------
00338 
00341 
00342   MatrixFieldMapping();
00343   MatrixFieldMapping(const Box3i &extents);
00344 
00346 
00347   // Main methods --------------------------------------------------------------
00348   
00352   void setLocalToWorld(const M44d &lsToWs);
00354   void setLocalToWorld(float t, const M44d &lsToWs);
00355 
00358   const M44d& localToWorld() const
00359   { return m_lsToWs; }
00360 
00363   const M44d& worldToVoxel() const
00364   { return m_wsToVs; }
00365 
00368   const M44d& voxelToWorld() const
00369   { return m_vsToWs; }
00370 
00372   const MatrixCurve::SampleVec& localToWorldSamples() const
00373   { return m_lsToWsCurve.samples(); } 
00374 
00377   void makeIdentity();
00378 
00379   // From FieldMapping ---------------------------------------------------------
00380 
00383 
00384   virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const 
00385   { m_wsToVs.multVecMatrix(wsP, vsP); }
00386   virtual void worldToVoxel(const V3d &wsP, V3d &vsP, float time) const 
00387   { 
00388     if (!m_isTimeVarying) {
00389       m_wsToVs.multVecMatrix(wsP, vsP);
00390     } else {
00391       M44d wsToVs = m_vsToWsCurve.linear(time).inverse();
00392       wsToVs.multVecMatrix(wsP, vsP);
00393     }
00394   }
00395 
00396   virtual void voxelToWorld(const V3d &vsP, V3d &wsP) const 
00397   { m_vsToWs.multVecMatrix(vsP, wsP); }
00398   virtual void voxelToWorld(const V3d &vsP, V3d &wsP, float time) const 
00399   { 
00400     if (!m_isTimeVarying) {
00401       m_vsToWs.multVecMatrix(vsP, wsP); 
00402     } else {
00403       M44d vsToWs = m_vsToWsCurve.linear(time);
00404       vsToWs.multVecMatrix(vsP, wsP);
00405     }
00406   }
00407 
00408   virtual void worldToLocal(const V3d &wsP, V3d &lsP) const 
00409   { m_wsToLs.multVecMatrix(wsP, lsP); }
00410   virtual void worldToLocal(const V3d &wsP, V3d &lsP,
00411                             float time) const 
00412   { 
00413     if (!m_isTimeVarying) {
00414       m_wsToLs.multVecMatrix(wsP, lsP); 
00415     } else {
00416       M44d wsToLs = m_lsToWsCurve.linear(time).inverse();
00417       wsToLs.multVecMatrix(wsP, lsP);
00418     }
00419   }
00420 
00421   virtual void localToWorld(const V3d &lsP, V3d &wsP) const 
00422   { m_lsToWs.multVecMatrix(lsP, wsP); }
00423   virtual void localToWorld(const V3d &lsP, V3d &wsP, float time) const 
00424   { 
00425     if (!m_isTimeVarying) {
00426       m_lsToWs.multVecMatrix(lsP, wsP); 
00427     } else {
00428       M44d lsToWs = m_lsToWsCurve.linear(time);
00429       lsToWs.multVecMatrix(lsP, wsP);
00430     }
00431   }
00432 
00434   void worldToVoxelDir(const V3d &wsV, V3d &vsV) const 
00435   { m_wsToVs.multDirMatrix(wsV, vsV); }
00436 
00438   void voxelToWorldDir(const V3d &vsV, V3d &wsV) const 
00439   { m_vsToWs.multDirMatrix(vsV, wsV); }
00440 
00442   void worldToLocalDir(const V3d &wsV, V3d &lsV) const 
00443   { m_wsToLs.multDirMatrix(wsV, lsV); }
00444 
00446   void localToWorldDir(const V3d &lsV, V3d &wsV) const 
00447   { m_lsToWs.multDirMatrix(lsV, wsV); }
00448 
00449   virtual void extentsChanged();
00450 
00451   virtual std::string className() const;
00452 
00453   virtual bool isIdentical(FieldMapping::Ptr other, 
00454                            double tolerance = 0.0) const;
00455 
00456   virtual V3d wsVoxelSize(int /*i*/, int /*j*/, int /*k*/) const
00457   { return m_wsVoxelSize; }
00458 
00459   virtual FieldMapping::Ptr clone() const;
00460 
00462   
00463 private:
00464 
00466   void updateTransform();
00467 
00469   void getLocalToVoxelMatrix(M44d &result);
00470 
00471   // Data members -------------------------------------------------------------
00472 
00475   M44d m_lsToWs;
00478   M44d m_wsToLs;
00481   M44d m_vsToWs;
00484   M44d m_wsToVs;
00485 
00487   MatrixCurve m_lsToWsCurve;
00489   MatrixCurve m_vsToWsCurve;
00490 
00493   bool m_isTimeVarying;
00494 
00497   V3d m_wsVoxelSize;
00498 
00499   // Typedefs ------------------------------------------------------------------
00500 
00502   typedef FieldMapping base;  
00503 };
00504 
00505 //----------------------------------------------------------------------------//
00506 // FrustumFieldMapping
00507 //----------------------------------------------------------------------------//
00508 
00534 //----------------------------------------------------------------------------//
00535 
00536 class FrustumFieldMapping : public FieldMapping
00537 {
00538 public:
00539 
00540   // Typedefs ------------------------------------------------------------------
00541 
00543   typedef boost::intrusive_ptr<FrustumFieldMapping> Ptr;
00545   typedef Curve<Imath::M44d> MatrixCurve;
00547   typedef Curve<double> FloatCurve;
00548 
00549   // Exceptions ----------------------------------------------------------------
00550 
00551   DECLARE_FIELD3D_GENERIC_EXCEPTION(BadPerspectiveMatrix, Exc::Exception)
00552 
00553   // Enums ---------------------------------------------------------------------
00554 
00555   
00556 
00557   enum ZDistribution {
00558     PerspectiveDistribution,
00559     UniformDistribution
00560   };
00561 
00562   // RTTI replacement ----------------------------------------------------------
00563 
00564   typedef FrustumFieldMapping class_type;
00565   DEFINE_FIELD_RTTI_CONCRETE_CLASS;
00566   
00567   static const char* classType ()
00568   {
00569     return "FrustumFieldMapping";
00570   }
00571 
00572   // Ctors, dtor ---------------------------------------------------------------
00573 
00576 
00577   FrustumFieldMapping();
00578   FrustumFieldMapping(const Box3i &extents);
00579 
00581 
00582   // Main methods --------------------------------------------------------------
00583   
00590   void setTransforms(const M44d &ssToWs, const M44d &csToWs);
00595   void setTransforms(float t, const M44d &ssToWs, const M44d &csToWs);
00596 
00598   void setZDistribution(ZDistribution dist)
00599   { m_zDistribution = dist; }
00601   ZDistribution zDistribution() const
00602   { return m_zDistribution; }
00603 
00606   const M44d screenToWorld() const
00607   { return m_ssToWsCurve.linear(0.0); }
00608 
00611   const M44d cameraToWorld() const
00612   { return m_csToWsCurve.linear(0.0); }
00613 
00615   const MatrixCurve::SampleVec& screenToWorldSamples() const
00616   { return m_ssToWsCurve.samples(); } 
00617 
00619   const MatrixCurve::SampleVec& cameraToWorldSamples() const
00620   { return m_csToWsCurve.samples(); } 
00621 
00623   const FloatCurve::SampleVec& nearPlaneSamples() const
00624   { return m_nearCurve.samples(); } 
00625 
00627   const FloatCurve::SampleVec& farPlaneSamples() const
00628   { return m_farCurve.samples(); } 
00629 
00631   double nearPlane() const 
00632   { return m_nearCurve.linear(0.0); }
00633 
00635   double farPlane() const
00636   { return m_farCurve.linear(0.0); }
00637 
00641   void reset();
00642 
00643   // From FieldMapping ---------------------------------------------------------
00644 
00647 
00648   virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const;
00649   virtual void worldToVoxel(const V3d &wsP, V3d &vsP, float time) const;
00650 
00651   virtual void voxelToWorld(const V3d &vsP, V3d &wsP) const;
00652   virtual void voxelToWorld(const V3d &vsP, V3d &wsP, float time) const;
00653 
00654   virtual void worldToLocal(const V3d &wsP, V3d &lsP) const;
00655   virtual void worldToLocal(const V3d &wsP, V3d &lsP, float time) const;
00656 
00657   virtual void localToWorld(const V3d &lsP, V3d &wsP) const;
00658   virtual void localToWorld(const V3d &lsP, V3d &wsP, float time) const;
00659 
00660   virtual void extentsChanged();
00661 
00662   virtual std::string className() const;
00663 
00664   virtual bool isIdentical(FieldMapping::Ptr other, 
00665                            double tolerance = 0.0) const;
00666 
00667   virtual V3d wsVoxelSize(int i, int j, int k) const;
00668 
00669   virtual FieldMapping::Ptr clone() const;
00670 
00672   
00673 private:
00674 
00676   void computeVoxelSize();
00677 
00679   void getLocalToVoxelMatrix(M44d &result);
00680 
00683   void clearCurves();
00684 
00685   // Data members -------------------------------------------------------------
00686 
00688   ZDistribution m_zDistribution;
00689 
00693   MatrixCurve m_ssToWsCurve;
00695   MatrixCurve m_csToWsCurve;
00698   MatrixCurve m_lpsToWsCurve;
00700   FloatCurve m_nearCurve;
00702   FloatCurve m_farCurve;
00703 
00706   std::vector<V3d> m_wsVoxelSize;
00707 
00712   bool m_defaultState;
00713 
00714   // Typedefs ------------------------------------------------------------------
00715 
00717   typedef FieldMapping base;
00718 
00719 };
00720 
00721 //----------------------------------------------------------------------------//
00722 
00723 FIELD3D_NAMESPACE_HEADER_CLOSE
00724 
00725 //----------------------------------------------------------------------------//
00726 
00727 #endif // Include guard