53#define isnan(__x__) _isnan(__x__)
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);
201 const Box3d &fromBounds,
205 V3d(fromBounds.min.x, fromBounds.min.y, fromBounds.min.z),
206 V3d(fromBounds.max.x, fromBounds.min.y, fromBounds.min.z),
207 V3d(fromBounds.min.x, fromBounds.max.y, fromBounds.min.z),
208 V3d(fromBounds.max.x, fromBounds.max.y, fromBounds.min.z),
209 V3d(fromBounds.min.x, fromBounds.min.y, fromBounds.max.z),
210 V3d(fromBounds.max.x, fromBounds.min.y, fromBounds.max.z),
211 V3d(fromBounds.min.x, fromBounds.max.y, fromBounds.max.z),
212 V3d(fromBounds.max.x, fromBounds.max.y, fromBounds.max.z)
214 toBounds.makeEmpty();
216 for (
int i = 0; i < 8; i++) {
217 mtx.multVecMatrix(verts[i], toP);
218 toBounds.extendBy(toP);
239 return other->className() == k_nullMappingName;
310 double tolerance)
const
314 if (other->className() != k_matrixMappingName) {
324 const SampleVec lsToWs2 = mm->m_lsToWsCurve.samples();
326 const SampleVec vsToWs2 = mm->m_vsToWsCurve.samples();
328 size_t numSamples = lsToWs1.size();
332 if (lsToWs1.size() != lsToWs2.size()) {
338 for (
size_t i = 0; i < numSamples; ++i) {
339 if (lsToWs1[i].first != lsToWs2[i].first) {
342 if (!checkMatricesIdentical(lsToWs1[i].second, lsToWs2[i].second,
346 if (!checkMatricesIdentical(vsToWs1[i].second, vsToWs2[i].second,
365 typedef MatrixCurve::SampleVec::const_iterator SampleIter;
370 M44d vsToLs = lsToVs.inverse();
376 for (SampleIter i = lsToWs.begin(), end = lsToWs.end(); i != end; i++) {
390 V3d voxelOrigin, nextVoxel;
406 M44d scaling, translation;
407 scaling.setScale(
m_res);
408 translation.setTranslation(
m_origin);
409 result = scaling * translation;
425 m_zDistribution(PerspectiveDistribution),
449 const M44d &ssToWs,
const M44d &csToWs)
457 M44d lsToSs, scale, translation;
458 scale.setScale(
V3d(2.0, 2.0, 1.0));
459 translation.setTranslation(
V3d(-1.0, -1.0, 0.0));
460 lsToSs = scale * translation;
461 M44d lpsToWs = lsToSs * ssToWs;
474 V3d lsNearP(0.5, 0.5, 0.0), lsFarP(0.5, 0.5, 1.0);
475 V3d wsNearP, wsFarP, csNearP, csFarP;
477 lpsToWs.multVecMatrix(lsNearP, wsNearP);
478 lpsToWs.multVecMatrix(lsFarP, wsFarP);
480 M44d wsToCs = csToWs.inverse();
481 wsToCs.multVecMatrix(wsNearP, csNearP);
482 wsToCs.multVecMatrix(wsFarP, csFarP);
484 double near = -csNearP.z;
485 double far = -csFarP.z;
488 if (std::isnan(near) || std::isnan(far)) {
489 throw BadPerspectiveMatrix(
"FrustumFieldMapping::setTransforms "
490 "received bad screen-to-world matrix");
506 csToWs.makeIdentity();
512 double fovRadians = 45.0 * M_PI / 180.0;
513 double invTan = 1.0 / std::tan(fovRadians / 2.0);
514 double imageAspectRatio = 1.0;
516 M44d perspective(1, 0, 0, 0,
518 0, 0, (far) / (far - near), 1,
519 0, 0, (- far * near) / (far - near), 0);
522 fov.setScale(
V3d(invTan / imageAspectRatio, invTan, 1.0));
525 flipZ.setScale(
V3d(1.0, 1.0, -1.0));
527 M44d csToSs = flipZ * perspective * fov;
529 M44d standardSsToWs = csToSs.inverse() * csToWs;
637 V3d lpsCenterP, wsCenterP, csCenterP(0.0, 0.0, -wsDepthFromCam);
645 V3d lpsP(lsP.x, lsP.y, lpsCenterP.z);
670 double tolerance)
const
674 if (other->className() != k_frustumMappingName) {
684 const SampleVec lpsToWs2 = fm->m_lpsToWsCurve.samples();
686 const SampleVec csToWs2 = fm->m_csToWsCurve.samples();
688 size_t numSamples = lpsToWs1.size();
697 if (lpsToWs1.size() != lpsToWs2.size()) {
703 for (
size_t i = 0; i < numSamples; ++i) {
704 if (lpsToWs1[i].first != lpsToWs2[i].first) {
707 if (!checkMatricesIdentical(lpsToWs1[i].second, lpsToWs2[i].second,
711 if (!checkMatricesIdentical(csToWs1[i].second, csToWs2[i].second,
730 k = std::min(std::max(k,
static_cast<int>(
m_origin.z)),
747 int zMin =
static_cast<int>(
m_origin.z);
750 for (
int k = zMin, idx = 0; k < zMax; ++k, ++idx) {
751 V3d wsP, wsPx, wsPy, wsPz;
761 (wsPy - wsP).length(),
762 (wsPz - wsP).length());
779 M44d scaling, translation;
780 scaling.setScale(
m_res);
781 translation.setTranslation(
m_origin);
782 result = scaling * translation;
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 ...
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 ...
Contains the FieldMapping base class and the NullFieldMapping and MatrixFieldMapping subclasses.
Contains Field, WritableField and ResizableField classes.
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel.
#define FIELD_DYNAMIC_CAST
#define FIELD3D_EXTRACT_SHRT
#define FIELD3D_LERPFACTOR
Contains typedefs for the commonly used types in Field3D.
void addSample(const float t, const T &value)
Adds a sample point to the curve.
size_t numSamples() const
Returns the number of samples in the curve.
const SampleVec & samples() const
Returns a const reference to the samples in the curve.
void clear()
Clears all samples in curve.
T linear(const float t) const
Linearly interpolates a value from the curve.
std::vector< Sample > SampleVec
Base class for mapping between world-, local- and voxel coordinates.
V3d m_origin
The integer voxel-space origin of the underlying Field object. Is equal to field.extents....
virtual ~FieldMapping()
Destructor.
virtual std::string className() const =0
Returns the FieldMapping type name. Used when writing/reading from disk.
FieldMapping()
Constructor.
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
boost::intrusive_ptr< FieldMapping > Ptr
V3d m_res
The integer voxel-space resolution of the underlying Field object. Is equal to field....
void setExtents(const Box3i &extents)
This sets the field extents information to use for defining the local coordinate space.
void voxelToLocal(const V3d &vsP, V3d &lsP) const
Inverse of 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...
static const char * staticClassType()
@ PerspectiveDistribution
MatrixCurve m_lpsToWsCurve
Time-varying local perspective to world space transform. Computed from m_ssToWsCurve.
virtual void localToWorld(const V3d &lsP, V3d &wsP) const
Transform from local space position into world space.
bool m_defaultState
Boolean to tell us if the mapping is in its 'default' state. This is needed because the class has a d...
virtual V3d wsVoxelSize(int i, int j, int k) const
Returns world-space size of a voxel at the specified coordinate.
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
void setTransforms(const M44d &ssToWs, const M44d &csToWs)
Sets the screenToWorld and cameraToWorld transforms. All other internal matrices will be updated base...
void clearCurves()
Clears all Curve data members. Used by setTransforms() to prepare for the first sample to be added.
MatrixCurve m_ssToWsCurve
Time-varying local perspective to world space transform This is not used in calculations,...
void getLocalToVoxelMatrix(M44d &result)
FloatCurve m_farCurve
Time-varying far plane. Computed from m_lpsToWsCurve.
std::vector< V3d > m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency.
void reset()
Resets the transform. Makes a perspective transform at the origin, looking down the negative Z axis w...
void computeVoxelSize()
Updates the local to world transformation matrix.
virtual void voxelToWorld(const V3d &vsP, V3d &wsP) const
Transform from voxel space position into world space.
virtual void worldToLocal(const V3d &wsP, V3d &lsP) const
Transform from world space position into local space.
boost::intrusive_ptr< FrustumFieldMapping > Ptr
Convenience typedef.
FloatCurve m_nearCurve
Time-varying near plane. Computed from m_lpsToWsCurve.
ZDistribution m_zDistribution
Slice distribution type.
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const
Transform from world space position into voxel space.
static const char * staticClassType()
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
MatrixCurve m_csToWsCurve
Time-varying camera to world space transform.
MatrixCurve m_vsToWsCurve
Time-varying voxel to world space transform.
void setLocalToWorld(const M44d &lsToWs)
Sets the local to world transform. All other matrices will be updated based on this.
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
static const char * staticClassType()
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
M44d m_wsToVs
World space to voxel space.
M44d m_wsToLs
World space to local space.
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.
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
virtual void extentsChanged()
Implement this if the subclass needs to update itself when the resolution changes.
M44d m_vsToWs
Voxel space to world space.
MatrixCurve m_lsToWsCurve
Time-varying local to world space transform.
V3d m_wsVoxelSize
Precomputed world-space voxel size. Calculations may assume orthogonal transformation for efficiency.
void updateTransform()
Updates the local to world transformation matrix.
M44d m_lsToWs
Local space to world space.
void getLocalToVoxelMatrix(M44d &result)
virtual bool isIdentical(FieldMapping::Ptr other, double tolerance=0.0) const
Whether the mapping is identical to another mapping.
boost::intrusive_ptr< NullFieldMapping > Ptr
Convenience typedef.
virtual std::string className() const
Returns the FieldMapping type name. Used when writing/reading from disk.
virtual FieldMapping::Ptr clone() const
Returns a pointer to a copy of the mapping, pure virtual so ensure derived classes properly implement...
static const char * staticClassType()
bool checkMatricesIdentical(const Matrix_T &m1, const Matrix_T &m2, double tolerance)
const string k_mappingName("FieldMapping")
const string k_nullMappingName("NullFieldMapping")
const string k_matrixMappingName("MatrixFieldMapping")
const string k_frustumMappingName("FrustumFieldMapping")
#define FIELD3D_NAMESPACE_SOURCE_CLOSE