Field3D
|
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 00043 //----------------------------------------------------------------------------// 00044 00045 #include <iostream> 00046 #include <vector> 00047 00048 #include "FieldMapping.h" 00049 #include "Types.h" 00050 00051 //----------------------------------------------------------------------------// 00052 00053 using namespace boost; 00054 using namespace std; 00055 00056 //----------------------------------------------------------------------------// 00057 00058 FIELD3D_NAMESPACE_OPEN 00059 00060 //----------------------------------------------------------------------------// 00061 // Field3D namespaces 00062 //----------------------------------------------------------------------------// 00063 00064 00065 //----------------------------------------------------------------------------// 00066 // Local namespace 00067 //----------------------------------------------------------------------------// 00068 00069 namespace { 00070 const string k_nullMappingName("NullFieldMapping"); 00071 const string k_matrixMappingName("MatrixFieldMapping"); 00072 const string k_frustumMappingName("FrustumFieldMapping"); 00073 } 00074 00075 //----------------------------------------------------------------------------// 00076 // FieldMapping 00077 //----------------------------------------------------------------------------// 00078 00079 FieldMapping::FieldMapping() 00080 : RefBase(), 00081 m_origin(V3i(0)), 00082 m_res(V3i(1)) 00083 { 00084 /* Empty */ 00085 } 00086 00087 //----------------------------------------------------------------------------// 00088 00089 FieldMapping::FieldMapping(const Box3i &extents) 00090 : RefBase() 00091 { 00092 setExtents(extents); 00093 } 00094 00095 //----------------------------------------------------------------------------// 00096 00097 FieldMapping::~FieldMapping() 00098 { 00099 /* Empty */ 00100 } 00101 00102 //----------------------------------------------------------------------------// 00103 00104 void FieldMapping::setExtents(const Box3i &extents) 00105 { 00106 m_origin = extents.min; 00107 m_res = extents.max - extents.min + V3i(1); 00108 extentsChanged(); 00109 } 00110 00111 //----------------------------------------------------------------------------// 00112 00113 void FieldMapping::localToVoxel(const V3d &lsP, V3d &vsP) const 00114 { 00115 vsP = m_origin + lsP * m_res; 00116 } 00117 00118 //----------------------------------------------------------------------------// 00119 00120 void FieldMapping::localToVoxel(const V3d &lsP, V3d &vsP, 00121 float /*time*/) const 00122 { 00123 vsP = m_origin + lsP * m_res; 00124 } 00125 00126 //----------------------------------------------------------------------------// 00127 00128 void FieldMapping::localToVoxel(std::vector<V3d>::const_iterator lsP, 00129 std::vector<V3d>::const_iterator end, 00130 std::vector<V3d>::iterator vsP) const 00131 { 00132 for (; lsP != end; ++lsP, ++vsP) { 00133 *vsP = m_origin + *lsP * m_res; 00134 } 00135 } 00136 //----------------------------------------------------------------------------// 00137 00138 void FieldMapping::voxelToLocal(const V3d &vsP, V3d &lsP) const 00139 { 00140 lsP.x = FIELD3D_LERPFACTOR(vsP.x, m_origin.x, m_origin.x + m_res.x); 00141 lsP.y = FIELD3D_LERPFACTOR(vsP.y, m_origin.y, m_origin.y + m_res.y); 00142 lsP.z = FIELD3D_LERPFACTOR(vsP.z, m_origin.z, m_origin.z + m_res.z); 00143 } 00144 00145 //----------------------------------------------------------------------------// 00146 // NullFieldMapping 00147 //----------------------------------------------------------------------------// 00148 00149 std::string NullFieldMapping::className() const 00150 { 00151 return k_nullMappingName; 00152 } 00153 00154 //----------------------------------------------------------------------------// 00155 00156 bool NullFieldMapping::isIdentical(FieldMapping::Ptr other, 00157 double tolerance) const 00158 { 00159 // For null mappings it's simple - if the other one is also a null mapping 00160 // then true, otherwise it's false. 00161 00162 return other->className() == k_nullMappingName; 00163 } 00164 00165 //----------------------------------------------------------------------------// 00166 00167 FieldMapping::Ptr NullFieldMapping::clone() const 00168 { 00169 return Ptr(new NullFieldMapping(*this)); 00170 } 00171 00172 //----------------------------------------------------------------------------// 00173 // MatrixFieldMapping 00174 //----------------------------------------------------------------------------// 00175 00176 MatrixFieldMapping::MatrixFieldMapping() 00177 : FieldMapping() 00178 { 00179 makeIndentity(); 00180 } 00181 00182 //----------------------------------------------------------------------------// 00183 00184 MatrixFieldMapping::MatrixFieldMapping(const Box3i &extents) 00185 : FieldMapping(extents) 00186 { 00187 makeIndentity(); 00188 } 00189 00190 //----------------------------------------------------------------------------// 00191 00192 void MatrixFieldMapping::setLocalToWorld(const M44d &lsToWs) 00193 { 00194 m_lsToWs = lsToWs; 00195 updateTransform(); 00196 } 00197 00198 //----------------------------------------------------------------------------// 00199 00200 void MatrixFieldMapping::makeIndentity() 00201 { 00202 m_lsToWs.makeIdentity(); 00203 updateTransform(); 00204 } 00205 00206 //----------------------------------------------------------------------------// 00207 00208 void MatrixFieldMapping::extentsChanged() 00209 { 00210 updateTransform(); 00211 } 00212 00213 //----------------------------------------------------------------------------// 00214 00215 std::string MatrixFieldMapping::className() const 00216 { 00217 return k_matrixMappingName; 00218 } 00219 00220 //----------------------------------------------------------------------------// 00221 00222 bool MatrixFieldMapping::isIdentical(FieldMapping::Ptr other, 00223 double tolerance) const 00224 { 00225 if (other->className() != k_matrixMappingName) { 00226 return false; 00227 } else { 00228 MatrixFieldMapping::Ptr mm = 00229 dynamic_pointer_cast<MatrixFieldMapping>(other); 00230 if (mm) { 00231 // first preserve the same test as before: 00232 if (mm->m_lsToWs.equalWithRelError(m_lsToWs, tolerance) && 00233 mm->m_wsToVs.equalWithRelError(m_wsToVs, tolerance)) { 00234 return true; 00235 } 00236 00237 // In case of precision problems, do a more robust test by 00238 // decomposing the matrices and comparing the components 00239 00240 V3d s1, r1, t1, sh1; 00241 V3d s2, r2, t2, sh2; 00242 00243 // Compare local-to-world matrices 00244 if (!FIELD3D_EXTRACT_SHRT(m_lsToWs, s1, sh1, r1, t1, false)) { 00245 return false; 00246 } 00247 if (!FIELD3D_EXTRACT_SHRT(mm->m_lsToWs, s2, sh2, r2, t2, false)) { 00248 return false; 00249 } 00250 if (!s1.equalWithRelError(s2, tolerance) || 00251 !r1.equalWithAbsError(r2, tolerance) || 00252 !t1.equalWithRelError(t2, tolerance)) { 00253 return false; 00254 } 00255 00256 // Compare world-to-voxel matrices 00257 if (!FIELD3D_EXTRACT_SHRT(m_wsToVs, s1, sh1, r1, t1, false)) { 00258 return false; 00259 } 00260 if (!FIELD3D_EXTRACT_SHRT(mm->m_wsToVs, s2, sh2, r2, t2, false)) { 00261 return false; 00262 } 00263 if (!s1.equalWithRelError(s2, tolerance) || 00264 !r1.equalWithAbsError(r2, tolerance) || 00265 !t1.equalWithRelError(t2, tolerance)) { 00266 return false; 00267 } 00268 return true; 00269 } else { 00270 return false; 00271 } 00272 } 00273 return false; 00274 } 00275 00276 //----------------------------------------------------------------------------// 00277 00278 void MatrixFieldMapping::updateTransform() 00279 { 00280 m_wsToLs = m_lsToWs.inverse(); 00281 M44d lsToVs; 00282 getLocalToVoxelMatrix(lsToVs); 00283 m_wsToVs = m_wsToLs * lsToVs; 00284 m_vsToWs = m_wsToVs.inverse(); 00285 00286 // Precompute the voxel size 00287 V3d voxelOrigin, nextVoxel; 00288 m_vsToWs.multVecMatrix(V3d(0, 0, 0), voxelOrigin); 00289 m_vsToWs.multVecMatrix(V3d(1, 0, 0), nextVoxel); 00290 m_wsVoxelSize.x = (nextVoxel - voxelOrigin).length(); 00291 m_vsToWs.multVecMatrix(V3d(0, 1, 0), nextVoxel); 00292 m_wsVoxelSize.y = (nextVoxel - voxelOrigin).length(); 00293 m_vsToWs.multVecMatrix(V3d(0, 0, 1), nextVoxel); 00294 m_wsVoxelSize.z = (nextVoxel - voxelOrigin).length(); 00295 } 00296 00297 //----------------------------------------------------------------------------// 00298 00299 void MatrixFieldMapping::getLocalToVoxelMatrix(M44d &result) 00300 { 00301 // Local to voxel is a scale by the resolution of the field, offset 00302 // to the origin of the extents 00303 M44d scaling, translation; 00304 scaling.setScale(m_res); 00305 translation.setTranslation(m_origin); 00306 result = scaling * translation; 00307 } 00308 00309 //----------------------------------------------------------------------------// 00310 00311 FieldMapping::Ptr MatrixFieldMapping::clone() const 00312 { 00313 return Ptr(new MatrixFieldMapping(*this)); 00314 } 00315 00316 //----------------------------------------------------------------------------// 00317 00318 FIELD3D_NAMESPACE_SOURCE_CLOSE 00319 00320 //----------------------------------------------------------------------------//