53 #define isnan(__x__) _isnan(__x__) 58 using namespace boost;
85 template <
class Matrix_T>
89 if (m1.equalWithRelError(m2, tolerance)) {
92 V3d s1, r1, t1, sh1, s2, r2, t2, sh2;
99 if (!s1.equalWithRelError(s2, tolerance) ||
100 !r1.equalWithAbsError(r2, tolerance) ||
101 !t1.equalWithRelError(t2, tolerance)) {
149 m_res = extents.max - extents.min +
V3i(1);
174 const Box3d &wsBounds,
178 mapping->worldToVoxel(test1, test2);
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)
190 vsBounds.makeEmpty();
192 for (
int i = 0; i < 8; i++) {
193 mapping->worldToVoxel(wsVerts[i], vsP);
194 vsBounds.extendBy(vsP);
286 double tolerance)
const 295 FIELD_DYNAMIC_CAST<MatrixFieldMapping>(other);
300 const SampleVec lsToWs2 = mm->m_lsToWsCurve.samples();
302 const SampleVec vsToWs2 = mm->m_vsToWsCurve.samples();
304 size_t numSamples = lsToWs1.size();
308 if (lsToWs1.size() != lsToWs2.size()) {
314 for (
size_t i = 0; i < numSamples; ++i) {
315 if (lsToWs1[i].first != lsToWs2[i].first) {
341 typedef MatrixCurve::SampleVec::const_iterator SampleIter;
346 M44d vsToLs = lsToVs.inverse();
352 for (SampleIter i = lsToWs.begin(), end = lsToWs.end(); i != end; i++) {
366 V3d voxelOrigin, nextVoxel;
382 M44d scaling, translation;
383 scaling.setScale(
m_res);
384 translation.setTranslation(
m_origin);
385 result = scaling * translation;
401 m_zDistribution(PerspectiveDistribution),
425 const M44d &ssToWs,
const M44d &csToWs)
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;
450 V3d lsNearP(0.5, 0.5, 0.0), lsFarP(0.5, 0.5, 1.0);
451 V3d wsNearP, wsFarP, csNearP, csFarP;
453 lpsToWs.multVecMatrix(lsNearP, wsNearP);
454 lpsToWs.multVecMatrix(lsFarP, wsFarP);
456 M44d wsToCs = csToWs.inverse();
457 wsToCs.multVecMatrix(wsNearP, csNearP);
458 wsToCs.multVecMatrix(wsFarP, csFarP);
460 double near = -csNearP.z;
461 double far = -csFarP.z;
464 if (isnan(near) || isnan(far)) {
465 throw BadPerspectiveMatrix(
"FrustumFieldMapping::setTransforms " 466 "received bad screen-to-world matrix");
482 csToWs.makeIdentity();
488 double fovRadians = 45.0 * M_PI / 180.0;
489 double invTan = 1.0 / std::tan(fovRadians / 2.0);
490 double imageAspectRatio = 1.0;
492 M44d perspective(1, 0, 0, 0,
494 0, 0, (far) / (far - near), 1,
495 0, 0, (- far * near) / (far - near), 0);
498 fov.setScale(
V3d(invTan / imageAspectRatio, invTan, 1.0));
501 flipZ.setScale(
V3d(1.0, 1.0, -1.0));
503 M44d csToSs = flipZ * perspective * fov;
505 M44d standardSsToWs = csToSs.inverse() * csToWs;
613 V3d lpsCenterP, wsCenterP, csCenterP(0.0, 0.0, -wsDepthFromCam);
621 V3d lpsP(lsP.x, lsP.y, lpsCenterP.z);
646 double tolerance)
const 655 FIELD_DYNAMIC_CAST<FrustumFieldMapping>(other);
660 const SampleVec lpsToWs2 = fm->m_lpsToWsCurve.samples();
662 const SampleVec csToWs2 = fm->m_csToWsCurve.samples();
664 size_t numSamples = lpsToWs1.size();
673 if (lpsToWs1.size() != lpsToWs2.size()) {
679 for (
size_t i = 0; i < numSamples; ++i) {
680 if (lpsToWs1[i].first != lpsToWs2[i].first) {
706 k = std::min(std::max(k, static_cast<int>(
m_origin.z)),
723 int zMin =
static_cast<int>(
m_origin.z);
726 for (
int k = zMin, idx = 0; k < zMax; ++k, ++idx) {
727 V3d wsP, wsPx, wsPy, wsPz;
737 (wsPy - wsP).length(),
738 (wsPz - wsP).length());
755 M44d scaling, translation;
756 scaling.setScale(
m_res);
757 translation.setTranslation(
m_origin);
758 result = scaling * translation;
Trivial class, world space is equal to local space, i.e. the field is contained in the unit cube [0...
Contains typedefs for the commonly used types in Field3D.
size_t numSamples() const
Returns the number of samples in the curve.
V3d m_origin
The integer voxel-space origin of the underlying Field object. Is equal to field.extents.min.
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
const string k_matrixMappingName("MatrixFieldMapping")
FloatCurve m_farCurve
Time-varying far plane. Computed from m_lpsToWsCurve.
void clearCurves()
Clears all Curve data members. Used by setTransforms() to prepare for the first sample to be added...
M44d m_vsToWs
Voxel space to world space.
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
static const char * staticClassType()
MatrixCurve m_vsToWsCurve
Time-varying voxel to world space transform.
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.
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.
void voxelToLocal(const V3d &vsP, V3d &lsP) const
Inverse of localToVoxel.
MatrixCurve m_lsToWsCurve
Time-varying local to world space transform.
M44d m_lsToWs
Local space to world space.
V3d m_res
The integer voxel-space resolution of the underlying Field object. Is equal to field.extents.max - field.extents.min + 1.
static const char * staticClassType()
void localToVoxel(const V3d &lsP, V3d &vsP) const
Transform from local space to voxel space. This is just a multiplication by the resolution of the Fie...
virtual void 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
void addSample(const float t, const T &value)
Adds a sample point to the curve.
MatrixCurve m_lpsToWsCurve
Time-varying local perspective to world space transform. Computed from m_ssToWsCurve.
std::vector< V3d > m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency...
virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const =0
Transform from world space position into voxel space.
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 'default' state. This is needed because the class has a d...
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.
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.
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()
#define FIELD3D_EXTRACT_SHRT
FloatCurve m_nearCurve
Time-varying near plane. Computed from m_lpsToWsCurve.
Contains Field, WritableField and ResizableField classes.
T linear(const float t) const
Linearly interpolates a value from the curve.
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.
bool m_isTimeVarying
Stores whether the curve has more than one time sample.
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
ZDistribution m_zDistribution
Slice distribution type.
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...
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.
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
M44d m_wsToLs
World space to local space.
bool checkMatricesIdentical(const Matrix_T &m1, const Matrix_T &m2, double tolerance)
boost::intrusive_ptr< FrustumFieldMapping > Ptr
Convenience typedef.
const string k_frustumMappingName("FrustumFieldMapping")
M44d m_wsToVs
World space to voxel space.
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel...
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