Пример #1
0
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 (isnan(near) || isnan(far)) {
    throw BadPerspectiveMatrix("FrustumFieldMapping::setTransforms "
                               "received bad screen-to-world matrix");
  }

  m_nearCurve.addSample(t, near);
  m_farCurve.addSample(t, far);

  computeVoxelSize();
}
Пример #2
0
/// Guess position in 3D corresponding to a 2D click
///
/// `clickPos` - 2D position in viewport, as from a mouse event.
Imath::V3d View3D::guessClickPosition(const QPoint& clickPos)
{
    // Get new point in the projected coordinate system using the click
    // position x,y and the z of a reference position.  Take the reference point
    // of interest to be between the camera rotation center and the camera
    // position, as a rough guess of the depth the user is interested in.
    //
    // This works pretty well, except when there are noise points intervening
    // between the reference position and the user's actual point of interest.
    V3d refPos = 0.3*m_camera.position() + 0.7*m_camera.center();
    M44d mat = m_camera.viewMatrix()*m_camera.projectionMatrix()*m_camera.viewportMatrix();
    double refZ = (refPos * mat).z;
    V3d newPointProj(clickPos.x(), clickPos.y(), refZ);
    // Map projected point back into model coordinates
    return newPointProj * mat.inverse();
}
Пример #3
0
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();
}
Пример #4
0
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();
}