FieldMapping.cpp
Go to the documentation of this file.
//----------------------------------------------------------------------------//
/*
* Copyright (c) 2009 Sony Pictures Imageworks Inc
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution. Neither the name of Sony Pictures Imageworks nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
#include <iostream>
#include <vector>
#include "Field.h"
#include "FieldMapping.h"
#include "Types.h"
#ifdef WIN32
#define isnan(__x__) _isnan(__x__)
#endif
//----------------------------------------------------------------------------//
using namespace boost;
using namespace std;
//----------------------------------------------------------------------------//
FIELD3D_NAMESPACE_OPEN
//----------------------------------------------------------------------------//
// Field3D namespaces
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// Local namespace
//----------------------------------------------------------------------------//
namespace {
// Strings ---
const string k_mappingName("FieldMapping");
const string k_nullMappingName("NullFieldMapping");
const string k_matrixMappingName("MatrixFieldMapping");
const string k_frustumMappingName("FrustumFieldMapping");
// Functions ---
template <class Matrix_T>
bool checkMatricesIdentical(const Matrix_T &m1, const Matrix_T &m2,
double tolerance)
{
if (m1.equalWithRelError(m2, tolerance)) {
return true;
}
V3d s1, r1, t1, sh1, s2, r2, t2, sh2;
if (!FIELD3D_EXTRACT_SHRT(m1, s1, sh1, r1, t1, false)) {
return false;
}
if (!FIELD3D_EXTRACT_SHRT(m2, s2, sh2, r2, t2, false)) {
return false;
}
if (!s1.equalWithRelError(s2, tolerance) ||
!r1.equalWithAbsError(r2, tolerance) ||
!t1.equalWithRelError(t2, tolerance)) {
return false;
}
return true;
}
}
//----------------------------------------------------------------------------//
// FieldMapping
//----------------------------------------------------------------------------//
FieldMapping::FieldMapping()
: RefBase(),
m_origin(V3i(0)),
m_res(V3i(1))
{
/* Empty */
}
//----------------------------------------------------------------------------//
FieldMapping::FieldMapping(const Box3i &extents)
: RefBase()
{
setExtents(extents);
}
//----------------------------------------------------------------------------//
FieldMapping::~FieldMapping()
{
/* Empty */
}
//----------------------------------------------------------------------------//
std::string FieldMapping::className() const
{
return std::string(staticClassType());
}
//----------------------------------------------------------------------------//
void FieldMapping::setExtents(const Box3i &extents)
{
m_origin = extents.min;
m_res = extents.max - extents.min + V3i(1);
extentsChanged();
}
//----------------------------------------------------------------------------//
void FieldMapping::localToVoxel(const V3d &lsP, V3d &vsP) const
{
vsP = m_origin + lsP * m_res;
}
//----------------------------------------------------------------------------//
void FieldMapping::voxelToLocal(const V3d &vsP, V3d &lsP) const
{
lsP.x = FIELD3D_LERPFACTOR(vsP.x, m_origin.x, m_origin.x + m_res.x);
lsP.y = FIELD3D_LERPFACTOR(vsP.y, m_origin.y, m_origin.y + m_res.y);
lsP.z = FIELD3D_LERPFACTOR(vsP.z, m_origin.z, m_origin.z + m_res.z);
}
//----------------------------------------------------------------------------//
// Utilities
//----------------------------------------------------------------------------//
void worldToVoxel(const Field3D::FieldMapping* mapping,
const Box3d &wsBounds,
Box3d &vsBounds)
{
V3d test1, test2;
mapping->worldToVoxel(test1, test2);
V3d wsVerts[] = {
V3d(wsBounds.min.x, wsBounds.min.y, wsBounds.min.z),
V3d(wsBounds.max.x, wsBounds.min.y, wsBounds.min.z),
V3d(wsBounds.min.x, wsBounds.max.y, wsBounds.min.z),
V3d(wsBounds.max.x, wsBounds.max.y, wsBounds.min.z),
V3d(wsBounds.min.x, wsBounds.min.y, wsBounds.max.z),
V3d(wsBounds.max.x, wsBounds.min.y, wsBounds.max.z),
V3d(wsBounds.min.x, wsBounds.max.y, wsBounds.max.z),
V3d(wsBounds.max.x, wsBounds.max.y, wsBounds.max.z)
};
vsBounds.makeEmpty();
V3d vsP;
for (int i = 0; i < 8; i++) {
mapping->worldToVoxel(wsVerts[i], vsP);
vsBounds.extendBy(vsP);
}
}
//----------------------------------------------------------------------------//
void transformBounds(const M44d &mtx,
const Box3d &fromBounds,
Box3d &toBounds)
{
V3d verts[] = {
V3d(fromBounds.min.x, fromBounds.min.y, fromBounds.min.z),
V3d(fromBounds.max.x, fromBounds.min.y, fromBounds.min.z),
V3d(fromBounds.min.x, fromBounds.max.y, fromBounds.min.z),
V3d(fromBounds.max.x, fromBounds.max.y, fromBounds.min.z),
V3d(fromBounds.min.x, fromBounds.min.y, fromBounds.max.z),
V3d(fromBounds.max.x, fromBounds.min.y, fromBounds.max.z),
V3d(fromBounds.min.x, fromBounds.max.y, fromBounds.max.z),
V3d(fromBounds.max.x, fromBounds.max.y, fromBounds.max.z)
};
toBounds.makeEmpty();
V3d toP;
for (int i = 0; i < 8; i++) {
mtx.multVecMatrix(verts[i], toP);
toBounds.extendBy(toP);
}
}
//----------------------------------------------------------------------------//
// NullFieldMapping
//----------------------------------------------------------------------------//
std::string NullFieldMapping::className() const
{
return std::string(staticClassType());
}
//----------------------------------------------------------------------------//
bool NullFieldMapping::isIdentical(FieldMapping::Ptr other,
double /* tolerance */) const
{
// For null mappings it's simple - if the other one is also a null mapping
// then true, otherwise it's false.
return other->className() == k_nullMappingName;
}
//----------------------------------------------------------------------------//
FieldMapping::Ptr NullFieldMapping::clone() const
{
return Ptr(new NullFieldMapping(*this));
}
//----------------------------------------------------------------------------//
// MatrixFieldMapping
//----------------------------------------------------------------------------//
MatrixFieldMapping::MatrixFieldMapping()
: FieldMapping()
{
makeIdentity();
}
//----------------------------------------------------------------------------//
MatrixFieldMapping::MatrixFieldMapping(const Box3i &extents)
: FieldMapping(extents)
{
makeIdentity();
}
//----------------------------------------------------------------------------//
void MatrixFieldMapping::setLocalToWorld(const M44d &lsToWs)
{
if (m_lsToWsCurve.numSamples() > 0) {
makeIdentity();
}
setLocalToWorld(0.0f, lsToWs);
}
//----------------------------------------------------------------------------//
void MatrixFieldMapping::setLocalToWorld(float t, const M44d &lsToWs)
{
m_lsToWsCurve.addSample(t, lsToWs);
updateTransform();
}
//----------------------------------------------------------------------------//
void MatrixFieldMapping::makeIdentity()
{
m_lsToWsCurve.clear();
updateTransform();
}
//----------------------------------------------------------------------------//
void MatrixFieldMapping::extentsChanged()
{
updateTransform();
}
//----------------------------------------------------------------------------//
std::string MatrixFieldMapping::className() const
{
return std::string(staticClassType());
}
//----------------------------------------------------------------------------//
bool MatrixFieldMapping::isIdentical(FieldMapping::Ptr other,
double tolerance) const
{
typedef MatrixFieldMapping::MatrixCurve::SampleVec SampleVec;
if (other->className() != k_matrixMappingName) {
return false;
} else {
MatrixFieldMapping::Ptr mm =
FIELD_DYNAMIC_CAST<MatrixFieldMapping>(other);
if (mm) {
const SampleVec lsToWs1 = m_lsToWsCurve.samples();
const SampleVec lsToWs2 = mm->m_lsToWsCurve.samples();
const SampleVec vsToWs1 = m_vsToWsCurve.samples();
const SampleVec vsToWs2 = mm->m_vsToWsCurve.samples();
size_t numSamples = lsToWs1.size();
// First check if time sample counts differ
// lsToWs and vsToWs are guaranteed to have same sample count.
if (lsToWs1.size() != lsToWs2.size()) {
return false;
}
// Then check if all time samples match, then check localToWorld
// and voxelToWorld matrices
for (size_t i = 0; i < numSamples; ++i) {
if (lsToWs1[i].first != lsToWs2[i].first) {
return false;
}
if (!checkMatricesIdentical(lsToWs1[i].second, lsToWs2[i].second,
tolerance)) {
return false;
}
if (!checkMatricesIdentical(vsToWs1[i].second, vsToWs2[i].second,
tolerance)) {
return false;
}
}
return true;
} else {
return false;
}
}
return false;
}
//----------------------------------------------------------------------------//
void MatrixFieldMapping::updateTransform()
{
typedef MatrixCurve::SampleVec::const_iterator SampleIter;
// Build the voxel to world space transforms ---
M44d lsToVs;
getLocalToVoxelMatrix(lsToVs);
M44d vsToLs = lsToVs.inverse();
// Loop over all samples in lsToWs, append vsToLs and create new curve
// Also handle the special case where lsToWs has no samples. In that
// case m_vsToWsCurve still has to have one sample.
const MatrixCurve::SampleVec &lsToWs = m_lsToWsCurve.samples();
m_vsToWsCurve.clear();
for (SampleIter i = lsToWs.begin(), end = lsToWs.end(); i != end; i++) {
m_vsToWsCurve.addSample(i->first, vsToLs * i->second);
}
// See if the curve has more than just a single sample
m_isTimeVarying = m_lsToWsCurve.numSamples() > 1;
// Sample the time-varying transforms at time=0.0
m_lsToWs = m_lsToWsCurve.linear(0.0);
m_wsToLs = m_lsToWs.inverse();
m_vsToWs = vsToLs * m_lsToWs;
m_wsToVs = m_vsToWs.inverse();
// Precompute the voxel size
V3d voxelOrigin, nextVoxel;
m_vsToWs.multVecMatrix(V3d(0, 0, 0), voxelOrigin);
m_vsToWs.multVecMatrix(V3d(1, 0, 0), nextVoxel);
m_wsVoxelSize.x = (nextVoxel - voxelOrigin).length();
m_vsToWs.multVecMatrix(V3d(0, 1, 0), nextVoxel);
m_wsVoxelSize.y = (nextVoxel - voxelOrigin).length();
m_vsToWs.multVecMatrix(V3d(0, 0, 1), nextVoxel);
m_wsVoxelSize.z = (nextVoxel - voxelOrigin).length();
}
//----------------------------------------------------------------------------//
void MatrixFieldMapping::getLocalToVoxelMatrix(M44d &result)
{
// Local to voxel is a scale by the resolution of the field, offset
// to the origin of the extents
M44d scaling, translation;
scaling.setScale(m_res);
translation.setTranslation(m_origin);
result = scaling * translation;
}
//----------------------------------------------------------------------------//
FieldMapping::Ptr MatrixFieldMapping::clone() const
{
return Ptr(new MatrixFieldMapping(*this));
}
//----------------------------------------------------------------------------//
// FrustumFieldMapping
//----------------------------------------------------------------------------//
FrustumFieldMapping::FrustumFieldMapping()
: FieldMapping(),
m_zDistribution(PerspectiveDistribution),
m_defaultState(true)
{
reset();
}
//----------------------------------------------------------------------------//
FrustumFieldMapping::FrustumFieldMapping(const Box3i &extents)
: FieldMapping(extents)
{
reset();
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::setTransforms(const M44d &ssToWs, const M44d &csToWs)
{
setTransforms(0.0, ssToWs, csToWs);
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::setTransforms(float t,
const M44d &ssToWs, const M44d &csToWs)
{
if (m_defaultState) {
clearCurves();
m_defaultState = false;
}
// Construct local-to-world transform from ssToWs
M44d lsToSs, scale, translation;
scale.setScale(V3d(2.0, 2.0, 1.0));
translation.setTranslation(V3d(-1.0, -1.0, 0.0));
lsToSs = scale * translation;
M44d lpsToWs = lsToSs * ssToWs;
// Add samples to Curves
m_ssToWsCurve.addSample(t, ssToWs);
m_lpsToWsCurve.addSample(t, lpsToWs);
m_csToWsCurve.addSample(t, csToWs);
// Compute near and far planes ---
// Because the frustum may be skewed we can't just measure distance from
// the apex of the frustum to the world-space center point of the frustum.
// Instead, we transform into camera space and measure z depth there.
V3d lsNearP(0.5, 0.5, 0.0), lsFarP(0.5, 0.5, 1.0);
V3d wsNearP, wsFarP, csNearP, csFarP;
lpsToWs.multVecMatrix(lsNearP, wsNearP);
lpsToWs.multVecMatrix(lsFarP, wsFarP);
M44d wsToCs = csToWs.inverse();
wsToCs.multVecMatrix(wsNearP, csNearP);
wsToCs.multVecMatrix(wsFarP, csFarP);
double near = -csNearP.z;
double far = -csFarP.z;
// Catch NaN here
if (std::isnan(near) || std::isnan(far)) {
throw BadPerspectiveMatrix("FrustumFieldMapping::setTransforms "
"received bad screen-to-world matrix");
}
m_nearCurve.addSample(t, near);
m_farCurve.addSample(t, far);
computeVoxelSize();
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::reset()
{
// Default camera to world ---
M44d csToWs;
csToWs.makeIdentity();
// Default screen to world ---
double near = 1;
double far = 2;
double fovRadians = 45.0 * M_PI / 180.0;
double invTan = 1.0 / std::tan(fovRadians / 2.0);
double imageAspectRatio = 1.0;
M44d perspective(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, (far) / (far - near), 1,
0, 0, (- far * near) / (far - near), 0);
M44d fov;
fov.setScale(V3d(invTan / imageAspectRatio, invTan, 1.0));
M44d flipZ;
flipZ.setScale(V3d(1.0, 1.0, -1.0));
M44d csToSs = flipZ * perspective * fov;
M44d standardSsToWs = csToSs.inverse() * csToWs;
// Set default state ---
clearCurves();
setTransforms(standardSsToWs, csToWs);
m_defaultState = true;
computeVoxelSize();
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::extentsChanged()
{
computeVoxelSize();
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::worldToVoxel(const V3d &wsP, V3d &vsP) const
{
worldToVoxel(wsP, vsP, 0.0);
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::worldToVoxel(const V3d &wsP, V3d &vsP, float time) const
{
V3d lsP;
worldToLocal(wsP, lsP, time);
localToVoxel(lsP, vsP);
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::voxelToWorld(const V3d &vsP, V3d &wsP) const
{
voxelToWorld(vsP, wsP, 0.0);
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::voxelToWorld(const V3d &vsP, V3d &wsP, float time) const
{
V3d lsP;
voxelToLocal(vsP, lsP);
localToWorld(lsP, wsP, time);
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::worldToLocal(const V3d &wsP, V3d &lsP) const
{
worldToLocal(wsP, lsP, 0.0);
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::worldToLocal(const V3d &wsP, V3d &lsP, float time) const
{
switch (m_zDistribution) {
case UniformDistribution:
{
// First transform to local perspective space
V3d lpsP;
m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsP, lpsP);
// Also transform to camera space
V3d csP;
m_csToWsCurve.linear(time).inverse().multVecMatrix(wsP, csP);
// Interpolate near and far plane at current time
double near = m_nearCurve.linear(time);
double far = m_farCurve.linear(time);
// Use perspective-space X/Y and normalized depth for Z.
lsP = V3d(lpsP.x, lpsP.y, FIELD3D_LERPFACTOR(-csP.z, near, far));
break;
}
case PerspectiveDistribution:
default:
{
m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsP, lsP);
break;
}
}
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::localToWorld(const V3d &lsP, V3d &wsP) const
{
localToWorld(lsP, wsP, 0.0);
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::localToWorld(const V3d &lsP, V3d &wsP, float time) const
{
switch (m_zDistribution) {
case UniformDistribution:
{
// Interpolate near and far plane at current time
double near = m_nearCurve.linear(time);
double far = m_farCurve.linear(time);
// In this case, local space is -not- equal to local perspective space
// Determine distance from camera
double wsDepthFromCam = FIELD3D_LERP(near, far, lsP.z);
// Transform point right in front of camera, X units away into world space
V3d lpsCenterP, wsCenterP, csCenterP(0.0, 0.0, -wsDepthFromCam);
m_csToWsCurve.linear(time).multVecMatrix(csCenterP, wsCenterP);
// Transform center point into screen space so we know what depth
// (in screen space) the voxel would live at -if- it were in local
// perspective space.
m_lpsToWsCurve.linear(time).inverse().multVecMatrix(wsCenterP, lpsCenterP);
// Now we create a local perspective coordinate that can be transformed
// using m_lpsToWsCurve
V3d lpsP(lsP.x, lsP.y, lpsCenterP.z);
// Now we can use m_lpsToWsCurve to transform the actual voxel location
m_lpsToWsCurve.linear(time).multVecMatrix(lpsP, wsP);
break;
}
case PerspectiveDistribution:
default:
{
// In this case, local space and local perspective space are the same.
m_lpsToWsCurve.linear(time).multVecMatrix(lsP, wsP);
break;
}
}
}
//----------------------------------------------------------------------------//
std::string FrustumFieldMapping::className() const
{
return std::string(staticClassType());
}
//----------------------------------------------------------------------------//
bool FrustumFieldMapping::isIdentical(FieldMapping::Ptr other,
double tolerance) const
{
typedef MatrixFieldMapping::MatrixCurve::SampleVec SampleVec;
if (other->className() != k_frustumMappingName) {
return false;
} else {
FrustumFieldMapping::Ptr fm =
FIELD_DYNAMIC_CAST<FrustumFieldMapping>(other);
if (fm) {
const SampleVec lpsToWs1 = m_lpsToWsCurve.samples();
const SampleVec lpsToWs2 = fm->m_lpsToWsCurve.samples();
const SampleVec csToWs1 = m_csToWsCurve.samples();
const SampleVec csToWs2 = fm->m_csToWsCurve.samples();
size_t numSamples = lpsToWs1.size();
// Check that slice distributions match
if (m_zDistribution != fm->m_zDistribution) {
return false;
}
// First check if time sample counts differ
// lpsToWs and csToWs are guaranteed to have same sample count.
if (lpsToWs1.size() != lpsToWs2.size()) {
return false;
}
// Then check if all time samples match, then check localToWorld
// and voxelToWorld matrices
for (size_t i = 0; i < numSamples; ++i) {
if (lpsToWs1[i].first != lpsToWs2[i].first) {
return false;
}
if (!checkMatricesIdentical(lpsToWs1[i].second, lpsToWs2[i].second,
tolerance)) {
return false;
}
if (!checkMatricesIdentical(csToWs1[i].second, csToWs2[i].second,
tolerance)) {
return false;
}
}
return true;
} else {
return false;
}
}
return false;
}
//----------------------------------------------------------------------------//
V3d FrustumFieldMapping::wsVoxelSize(int /*i*/, int /*j*/, int k) const
{
k = std::min(std::max(k, static_cast<int>(m_origin.z)),
static_cast<int>(m_origin.z + m_res.z - 1));
return m_wsVoxelSize[k - static_cast<int>(m_origin.z)];
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::computeVoxelSize()
{
// Precompute the voxel size ---
m_wsVoxelSize.resize(static_cast<int>(m_res.z),V3d(0.0));
int i = static_cast<int>(m_origin.x + m_res.x / 2);
int j = static_cast<int>(m_origin.y + m_res.y / 2);
// Do all z slices except last
int zMin = static_cast<int>(m_origin.z);
int zMax = static_cast<int>(m_origin.z + m_res.z - 1);
for (int k = zMin, idx = 0; k < zMax; ++k, ++idx) {
V3d wsP, wsPx, wsPy, wsPz;
V3d vsP = discToCont(V3i(i, j, k));
V3d vsPx = discToCont(V3i(i + 1, j, k));
V3d vsPy = discToCont(V3i(i, j + 1, k));
V3d vsPz = discToCont(V3i(i, j, k + 1));
voxelToWorld(vsP, wsP);
voxelToWorld(vsPx, wsPx);
voxelToWorld(vsPy, wsPy);
voxelToWorld(vsPz, wsPz);
m_wsVoxelSize[idx] = V3d((wsPx - wsP).length(),
(wsPy - wsP).length(),
(wsPz - wsP).length());
}
// Duplicate last value since there are no further slices to differentiate
// against
if (m_res.z >= 2) {
m_wsVoxelSize[static_cast<int>(m_res.z - 1)] = m_wsVoxelSize[static_cast<int>(m_res.z - 2)];
}
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::getLocalToVoxelMatrix(M44d &result)
{
// Local to voxel is a scale by the resolution of the field, offset
// to the origin of the extents
M44d scaling, translation;
scaling.setScale(m_res);
translation.setTranslation(m_origin);
result = scaling * translation;
}
//----------------------------------------------------------------------------//
void FrustumFieldMapping::clearCurves()
{
m_lpsToWsCurve.clear();
m_csToWsCurve.clear();
m_nearCurve.clear();
m_farCurve.clear();
}
//----------------------------------------------------------------------------//
FieldMapping::Ptr FrustumFieldMapping::clone() const
{
return Ptr(new FrustumFieldMapping(*this));
}
//----------------------------------------------------------------------------//
FIELD3D_NAMESPACE_SOURCE_CLOSE
//----------------------------------------------------------------------------//
worldToVoxel
void worldToVoxel(const Field3D::FieldMapping *mapping, const Box3d &wsBounds, Box3d &vsBounds)
Computes a voxel space bounds given a bounding box in world space. This is done by transforming each ...
Definition FieldMapping.cpp:173
transformBounds
void transformBounds(const M44d &mtx, const Box3d &fromBounds, Box3d &toBounds)
Transforms a bounding box by a 4x4 matrix This is done by transforming each corner vertex from world ...
Definition FieldMapping.cpp:200
FieldMapping.h
Contains the FieldMapping base class and the NullFieldMapping and MatrixFieldMapping subclasses.
Field.h
Contains Field, WritableField and ResizableField classes.
discToCont
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel.
Definition Field.h:1070
FIELD_DYNAMIC_CAST
#define FIELD_DYNAMIC_CAST
Definition RefCount.h:271
Box3d
Imath::Box3d Box3d
Definition SpiMathLib.h:79
V3i
Imath::V3i V3i
Definition SpiMathLib.h:71
V3d
Imath::V3d V3d
Definition SpiMathLib.h:74
FIELD3D_EXTRACT_SHRT
#define FIELD3D_EXTRACT_SHRT
Definition SpiMathLib.h:93
FIELD3D_LERP
#define FIELD3D_LERP
Definition SpiMathLib.h:91
Box3i
Imath::Box3i Box3i
Definition SpiMathLib.h:77
FIELD3D_LERPFACTOR
#define FIELD3D_LERPFACTOR
Definition SpiMathLib.h:92
M44d
Imath::M44d M44d
Definition SpiMathLib.h:82
Types.h
Contains typedefs for the commonly used types in Field3D.
Curve< Imath::M44d >::SampleVec
std::vector< Sample > SampleVec
Definition Curve.h:102
FieldMapping::m_origin
V3d m_origin
The integer voxel-space origin of the underlying Field object. Is equal to field.extents....
Definition FieldMapping.h:190
FieldMapping::~FieldMapping
virtual ~FieldMapping()
Destructor.
Definition FieldMapping.cpp:131
FieldMapping::className
virtual std::string className() const =0
Returns the FieldMapping type name. Used when writing/reading from disk.
Definition FieldMapping.cpp:139
FieldMapping::FieldMapping
FieldMapping()
Constructor.
Definition FieldMapping.cpp:113
FieldMapping::extentsChanged
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
Definition FieldMapping.h:161
FieldMapping::m_res
V3d m_res
The integer voxel-space resolution of the underlying Field object. Is equal to field....
Definition FieldMapping.h:193
FieldMapping::setExtents
void setExtents(const Box3i &extents)
This sets the field extents information to use for defining the local coordinate space.
Definition FieldMapping.cpp:146
FieldMapping::voxelToLocal
void voxelToLocal(const V3d &vsP, V3d &lsP) const
Inverse of localToVoxel.
Definition FieldMapping.cpp:162
FieldMapping::localToVoxel
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...
Definition FieldMapping.cpp:155
FieldMapping::staticClassType
static const char * staticClassType()
Definition FieldMapping.h:99
FieldMapping::Ptr
boost::intrusive_ptr< FieldMapping > Ptr
Definition FieldMapping.h:92
FrustumFieldMapping::PerspectiveDistribution
@ PerspectiveDistribution
Definition FieldMapping.h:586
FrustumFieldMapping::UniformDistribution
@ UniformDistribution
Definition FieldMapping.h:587
FrustumFieldMapping::m_lpsToWsCurve
MatrixCurve m_lpsToWsCurve
Time-varying local perspective to world space transform. Computed from m_ssToWsCurve.
Definition FieldMapping.h:726
FrustumFieldMapping::localToWorld
virtual void localToWorld(const V3d &lsP, V3d &wsP) const
Transform from local space position into world space.
Definition FieldMapping.cpp:618
FrustumFieldMapping::m_defaultState
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:740
FrustumFieldMapping::wsVoxelSize
virtual V3d wsVoxelSize(int i, int j, int k) const
Returns world-space size of a voxel at the specified coordinate.
Definition FieldMapping.cpp:728
FrustumFieldMapping::extentsChanged
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
Definition FieldMapping.cpp:543
FrustumFieldMapping::setTransforms
void setTransforms(const M44d &ssToWs, const M44d &csToWs)
Sets the screenToWorld and cameraToWorld transforms. All other internal matrices will be updated base...
Definition FieldMapping.cpp:441
FrustumFieldMapping::clearCurves
void clearCurves()
Clears all Curve data members. Used by setTransforms() to prepare for the first sample to be added.
Definition FieldMapping.cpp:787
FrustumFieldMapping::m_ssToWsCurve
MatrixCurve m_ssToWsCurve
Time-varying local perspective to world space transform This is not used in calculations,...
Definition FieldMapping.h:721
FrustumFieldMapping::getLocalToVoxelMatrix
void getLocalToVoxelMatrix(M44d &result)
Definition FieldMapping.cpp:775
FrustumFieldMapping::m_farCurve
FloatCurve m_farCurve
Time-varying far plane. Computed from m_lpsToWsCurve.
Definition FieldMapping.h:730
FrustumFieldMapping::m_wsVoxelSize
std::vector< V3d > m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency.
Definition FieldMapping.h:734
FrustumFieldMapping::reset
void reset()
Resets the transform. Makes a perspective transform at the origin, looking down the negative Z axis w...
Definition FieldMapping.cpp:501
FrustumFieldMapping::computeVoxelSize
void computeVoxelSize()
Updates the local to world transformation matrix.
Definition FieldMapping.cpp:737
FrustumFieldMapping::voxelToWorld
virtual void voxelToWorld(const V3d &vsP, V3d &wsP) const
Transform from voxel space position into world space.
Definition FieldMapping.cpp:566
FrustumFieldMapping::worldToLocal
virtual void worldToLocal(const V3d &wsP, V3d &lsP) const
Transform from world space position into local space.
Definition FieldMapping.cpp:582
FrustumFieldMapping::m_nearCurve
FloatCurve m_nearCurve
Time-varying near plane. Computed from m_lpsToWsCurve.
Definition FieldMapping.h:728
FrustumFieldMapping::Ptr
boost::intrusive_ptr< FrustumFieldMapping > Ptr
Convenience typedef.
Definition FieldMapping.h:571
FrustumFieldMapping::m_zDistribution
ZDistribution m_zDistribution
Slice distribution type.
Definition FieldMapping.h:716
FrustumFieldMapping::className
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
Definition FieldMapping.cpp:662
FrustumFieldMapping::worldToVoxel
virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const
Transform from world space position into voxel space.
Definition FieldMapping.cpp:550
FrustumFieldMapping::staticClassType
static const char * staticClassType()
Definition FieldMapping.h:595
FrustumFieldMapping::isIdentical
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
Definition FieldMapping.cpp:669
FrustumFieldMapping::FrustumFieldMapping
FrustumFieldMapping()
Definition FieldMapping.cpp:423
FrustumFieldMapping::clone
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
Definition FieldMapping.cpp:797
FrustumFieldMapping::m_csToWsCurve
MatrixCurve m_csToWsCurve
Time-varying camera to world space transform.
Definition FieldMapping.h:723
MatrixFieldMapping::m_vsToWsCurve
MatrixCurve m_vsToWsCurve
Time-varying voxel to world space transform.
Definition FieldMapping.h:517
MatrixFieldMapping::setLocalToWorld
void setLocalToWorld(const M44d &lsToWs)
Sets the local to world transform. All other matrices will be updated based on this.
Definition FieldMapping.cpp:269
MatrixFieldMapping::className
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
Definition FieldMapping.cpp:302
MatrixFieldMapping::staticClassType
static const char * staticClassType()
Definition FieldMapping.h:350
MatrixFieldMapping::MatrixFieldMapping
MatrixFieldMapping()
Definition FieldMapping.cpp:253
MatrixFieldMapping::Ptr
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
Definition FieldMapping.h:341
MatrixFieldMapping::clone
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
Definition FieldMapping.cpp:414
MatrixFieldMapping::isIdentical
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
Definition FieldMapping.cpp:309
MatrixFieldMapping::m_wsToVs
M44d m_wsToVs
World space to voxel space.
Definition FieldMapping.h:512
MatrixFieldMapping::m_wsToLs
M44d m_wsToLs
World space to local space.
Definition FieldMapping.h:506
MatrixFieldMapping::m_isTimeVarying
bool m_isTimeVarying
Stores whether the curve has more than one time sample.
Definition FieldMapping.h:521
MatrixFieldMapping::makeIdentity
void makeIdentity()
Sets the transform to identity. This makes it functionally equivalent to a NullFieldMapping.
Definition FieldMapping.cpp:287
MatrixFieldMapping::extentsChanged
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
Definition FieldMapping.cpp:295
MatrixFieldMapping::m_vsToWs
M44d m_vsToWs
Voxel space to world space.
Definition FieldMapping.h:509
MatrixFieldMapping::m_lsToWsCurve
MatrixCurve m_lsToWsCurve
Time-varying local to world space transform.
Definition FieldMapping.h:515
MatrixFieldMapping::m_wsVoxelSize
V3d m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency.
Definition FieldMapping.h:525
MatrixFieldMapping::updateTransform
void updateTransform()
Updates the local to world transformation matrix.
Definition FieldMapping.cpp:363
MatrixFieldMapping::m_lsToWs
M44d m_lsToWs
Local space to world space.
Definition FieldMapping.h:503
MatrixFieldMapping::getLocalToVoxelMatrix
void getLocalToVoxelMatrix(M44d &result)
Definition FieldMapping.cpp:402
NullFieldMapping::isIdentical
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
Definition FieldMapping.cpp:233
NullFieldMapping::className
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
Definition FieldMapping.cpp:226
NullFieldMapping::NullFieldMapping
NullFieldMapping()
Definition FieldMapping.h:260
NullFieldMapping::clone
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
Definition FieldMapping.cpp:244
NullFieldMapping::staticClassType
static const char * staticClassType()
Definition FieldMapping.h:250
NullFieldMapping::Ptr
boost::intrusive_ptr< NullFieldMapping > Ptr
Convenience typedef.
Definition FieldMapping.h:243
RefBase::RefBase
RefBase()
Definition RefCount.h:120
FIELD3D_NAMESPACE_OPEN
Definition FieldMapping.cpp:74
FIELD3D_NAMESPACE_OPEN::checkMatricesIdentical
bool checkMatricesIdentical(const Matrix_T &m1, const Matrix_T &m2, double tolerance)
Definition FieldMapping.cpp:86
FIELD3D_NAMESPACE_OPEN::k_mappingName
const string k_mappingName("FieldMapping")
FIELD3D_NAMESPACE_OPEN::k_nullMappingName
const string k_nullMappingName("NullFieldMapping")
FIELD3D_NAMESPACE_OPEN::k_matrixMappingName
const string k_matrixMappingName("MatrixFieldMapping")
FIELD3D_NAMESPACE_OPEN::k_frustumMappingName
const string k_frustumMappingName("FrustumFieldMapping")
FIELD3D_NAMESPACE_SOURCE_CLOSE
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition ns.h:60