Ejemplo n.º 1
0
bool ViewControl::ConvertToPinholeCameraParameters(
        PinholeCameraIntrinsic &intrinsic, Eigen::Matrix4d &extrinsic)
{
    if (window_height_ <= 0 || window_width_ <= 0) {
        PrintWarning("[ViewControl] ConvertToPinholeCameraParameters() failed because window height and width are not set.\n");
        return false;
    }
    if (GetProjectionType() == ProjectionType::Orthogonal) {
        PrintWarning("[ViewControl] ConvertToPinholeCameraParameters() failed because orthogonal view cannot be translated to a pinhole camera.\n");
        return false;
    }
    SetProjectionParameters();
    intrinsic.width_ = window_width_;
    intrinsic.height_ = window_height_;
    intrinsic.intrinsic_matrix_.setIdentity();
    double fov_rad = field_of_view_ / 180.0 * M_PI;
    double tan_half_fov = std::tan(fov_rad / 2.0);
    intrinsic.intrinsic_matrix_(0, 0) = intrinsic.intrinsic_matrix_(1, 1) =
            (double)window_height_ / tan_half_fov / 2.0;
    intrinsic.intrinsic_matrix_(0, 2) = (double)window_width_ / 2.0 - 0.5;
    intrinsic.intrinsic_matrix_(1, 2) = (double)window_height_ / 2.0 - 0.5;
    extrinsic.setZero();
    Eigen::Vector3d front_dir = front_.normalized();
    Eigen::Vector3d up_dir = up_.normalized();
    Eigen::Vector3d right_dir = right_.normalized();
    extrinsic.block<1, 3>(0, 0) = right_dir.transpose();
    extrinsic.block<1, 3>(1, 0) = -up_dir.transpose();
    extrinsic.block<1, 3>(2, 0) = -front_dir.transpose();
    extrinsic(0, 3) = -right_dir.dot(eye_);
    extrinsic(1, 3) = up_dir.dot(eye_);
    extrinsic(2, 3) = front_dir.dot(eye_);
    extrinsic(3, 3) = 1.0;
    return true;
}
Ejemplo n.º 2
0
void ViewControl::SetProjectionParameters()
{
    front_ = front_.normalized();
    right_ = up_.cross(front_).normalized();
    up_ = front_.cross(right_).normalized();
    if (GetProjectionType() == ProjectionType::Perspective) {
        view_ratio_ = zoom_ * bounding_box_.GetSize();
        distance_ = view_ratio_ /
                std::tan(field_of_view_ * 0.5 / 180.0 * M_PI);
        eye_ = lookat_ + front_ * distance_;
    } else {
        view_ratio_ = zoom_ * bounding_box_.GetSize();
        distance_ = view_ratio_ /
                std::tan(FIELD_OF_VIEW_STEP * 0.5 / 180.0 * M_PI);
        eye_ = lookat_ + front_ * distance_;
    }
}
Ejemplo n.º 3
0
bool ViewControl::ConvertFromPinholeCameraParameters(
        const PinholeCameraIntrinsic &intrinsic,
        const Eigen::Matrix4d &extrinsic)
{
    if (window_height_ <= 0 || window_width_ <= 0 ||
            window_height_ != intrinsic.height_ ||
            window_width_ != intrinsic.width_ ||
            intrinsic.intrinsic_matrix_(0, 2) !=
            (double)window_width_ / 2.0 - 0.5 ||
            intrinsic.intrinsic_matrix_(1, 2) !=
            (double)window_height_ / 2.0 - 0.5) {
        PrintWarning("[ViewControl] ConvertFromPinholeCameraParameters() failed because window height and width do not match.\n");
        return false;
    }
    double tan_half_fov =
            (double)window_height_ / (intrinsic.intrinsic_matrix_(1, 1) * 2.0);
    double fov_rad = std::atan(tan_half_fov) * 2.0;
    double old_fov = field_of_view_;
    field_of_view_ = std::max(std::min(fov_rad * 180.0 / M_PI,
            FIELD_OF_VIEW_MAX), FIELD_OF_VIEW_MIN);
    if (GetProjectionType() == ProjectionType::Orthogonal) {
        field_of_view_ = old_fov;
        PrintWarning("[ViewControl] ConvertFromPinholeCameraParameters() failed because field of view is impossible.\n");
        return false;
    }
    right_ = extrinsic.block<1, 3>(0, 0).transpose();
    up_ = -extrinsic.block<1, 3>(1, 0).transpose();
    front_ = -extrinsic.block<1, 3>(2, 0).transpose();
    eye_ = extrinsic.block<3, 3>(0, 0).inverse() *
            (extrinsic.block<3, 1>(0, 3) * -1.0);
    double ideal_distance = (eye_ - bounding_box_.GetCenter()).dot(front_);
    double ideal_zoom = ideal_distance *
            std::tan(field_of_view_ * 0.5 / 180.0 * M_PI) /
            bounding_box_.GetSize();
    zoom_ = std::max(std::min(ideal_zoom, ZOOM_MAX), ZOOM_MIN);
    view_ratio_ = zoom_ * bounding_box_.GetSize();
    distance_ = view_ratio_ /
            std::tan(field_of_view_ * 0.5 / 180.0 * M_PI);
    lookat_ = eye_ - front_ * distance_;
    return true;
}
Ejemplo n.º 4
0
void ViewControl::SetViewMatrices(
        const Eigen::Matrix4d &model_matrix/* = Eigen::Matrix4d::Identity()*/)
{
    if (window_height_ <= 0 || window_width_ <= 0) {
        PrintWarning("[ViewControl] SetViewPoint() failed because window height and width are not set.");
        return;
    }
    glViewport(0, 0, window_width_, window_height_);
    if (GetProjectionType() == ProjectionType::Perspective)
    {
        // Perspective projection
        z_near_ = std::max(0.01 * bounding_box_.GetSize(),
                distance_ - 3.0 * bounding_box_.GetSize());
        z_far_ = distance_ + 3.0 * bounding_box_.GetSize();
        projection_matrix_ = GLHelper::Perspective(field_of_view_, aspect_,
                z_near_, z_far_);
    } else {
        // Orthogonal projection
        // We use some black magic to support distance_ in orthogonal view
        z_near_ = distance_ - 3.0 * bounding_box_.GetSize();
        z_far_ = distance_ + 3.0 * bounding_box_.GetSize();
        projection_matrix_ = GLHelper::Ortho(
                -aspect_ * view_ratio_,    aspect_ * view_ratio_,
                -view_ratio_, view_ratio_, z_near_, z_far_);
    }
    view_matrix_ = GLHelper::LookAt(eye_, lookat_, up_ );
    model_matrix_ = model_matrix.cast<GLfloat>();
    MVP_matrix_ = projection_matrix_ * view_matrix_ * model_matrix_;

    // uncomment to use the deprecated functions of legacy OpenGL
    //glMatrixMode(GL_PROJECTION);
    //glLoadIdentity();
    //glMatrixMode(GL_MODELVIEW);
    //glLoadIdentity();
    //glMultMatrixf(MVP_matrix_.data());
}
bool MoertelT::MOERTEL_TEMPLATE_CLASS(InterfaceT)::Project()
{
  bool ok = false;

  //-------------------------------------------------------------------
  // interface needs to be complete
  if (!IsComplete()) {
    if (gcomm_->getRank() == 0)
      std::cout << "***ERR*** MoertelT::Interface::Project:\n"
                << "***ERR*** Complete() not called on interface " << Id_
                << "\n"
                << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__
                << "\n";
    return false;
  }

  //-------------------------------------------------------------------
  // send all procs not member of this interface's intra-comm out of here
  if (lcomm_ == Teuchos::null) return true;

  //-------------------------------------------------------------------
  // interface segments need to have at least one function on each side
  std::map<int, Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)>>::
      iterator curr;
  for (int side = 0; side < 2; ++side)
    for (curr = rseg_[side].begin(); curr != rseg_[side].end(); ++curr)
      if (curr->second->Nfunctions() < 1) {
        std::cout << "***ERR*** MoertelT::Interface::Project:\n"
                  << "***ERR*** interface " << Id_ << ", mortar side\n"
                  << "***ERR*** segment " << curr->second->Id()
                  << " needs at least 1 function set\n"
                  << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__
                  << "\n";
        return false;
      }

  //-------------------------------------------------------------------
  // build nodal normals on both sides
  std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator
      ncurr;
  for (int side = 0; side < 2; ++side)
    for (ncurr = rnode_[side].begin(); ncurr != rnode_[side].end(); ++ncurr) {
#if 0
      std::cout << "side " << side << ": " << *(ncurr->second);
#endif
      ncurr->second->BuildAveragedNormal();
#if 0
      std::cout << "side " << side << ": " << *(ncurr->second);
#endif
    }

  //-------------------------------------------------------------------
  // check the type of projection to be used and project nodes
  // projection along the normal field:
  // uses the slave side's interpolated normal field to
  // project slave nodes onto the master surfaces.
  // Then projects master nodes along the same normal field on slave
  // surfaces. Overrides the normals in the master nodes by the negative
  // of the normal field of their projection point
  if (GetProjectionType() ==
      MoertelT::MOERTEL_TEMPLATE_CLASS(InterfaceT)::proj_continousnormalfield) {
    ok = ProjectNodes_NormalField();
    if (!ok) return false;
  } else if (
      GetProjectionType() ==
      MoertelT::MOERTEL_TEMPLATE_CLASS(InterfaceT)::proj_orthogonal) {
    ok = ProjectNodes_Orthogonal();
    if (!ok) return false;
  } else {
    std::cout << "***ERR*** MoertelT::Interface::Project:\n"
              << "***ERR*** interface " << Id() << "\n"
              << "***ERR*** unknown type of nodal projection\n"
              << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
    return false;
  }
  return true;
}