A bug in SetClipDist() in rendering::WideAngleCamera

Issue #2493 new
Huang Fan created an issue

In this function, only env cameras were set with the near & clip distances, while the base camera remain the old values. Despite wide angle camera rendering images only use the 6 env cameras, I think it's still necessary to initialize the clip distances of base camera, because some other functions like isVisible() are still using the base camera. If we don't initialize the clip distances of base camera, some issue that a Visual is visible in a Camera whereas invisible in a wide angle camera with the same frustum will probably be happen(already happened in my project)

void WideAngleCamera::SetClipDist()
{
  std::lock_guard<std::mutex> lock(this->dataPtr->dataMutex);

  // <clip> element presence is already checked
  // in Camera::SetClipDist(float,float)
  sdf::ElementPtr clipElem = this->sdf->GetElement("clip");

  for (int i = 0; i < 6; ++i)
  {
    if (this->dataPtr->envCameras[i])
    {
      this->dataPtr->envCameras[i]->setNearClipDistance(
          clipElem->Get<double>("near"));
      this->dataPtr->envCameras[i]->setFarClipDistance(
          clipElem->Get<double>("far"));
      this->dataPtr->envCameras[i]->setRenderingDistance(
          clipElem->Get<double>("far"));
    }
    else
    {
      gzerr << "Setting clip distances failed - no camera yet" << std::endl;

      break;
    }
  }
}

Comments (11)

  1. Huang Fan reporter

    Hi, Ian, thank you for your reply, but this function accept a Vector param (ignition::math::Vector3d), while I got a Visual to pass. How can I convert a Visual to Vector3d?

  2. Ian Chen

    you can use the visual position in the world for checking it's visibility, e.g. for gazebo9 it would be: visual->WorldPose().Pos()

  3. Huang Fan reporter

    Hi, Ian. I think this position is a kind of "center" position of the object(either geometric center or gravity center), if I use the projection of this center position vector to check visibility, another exception would raise that a corner(or part) of the object is actually visible in the frustum of camera, in spite of the center is out of it, we can't ensure the consistency of the visibility of all the corners & center.

    Currently I use the pointer of Ogre::Camera to set the near & far clip distances to make it work normally, some pseudocode as below:

    Ogre::Camera* o_camera = wide_angle_camera_ptr->OgreCamera();
    
    o_camera->setNearClipDistance(near_clip_dist);
    o_camera->setFarClipDistance(far_clip_dist);
    

    what's your concern? thank you.

  4. Ian Chen

    the concern is that there could be inconsistency between the base camera frustum and a wide angle camera frustum with the same FOV. This page gives a nice illustration. The difference becomes more apparent at large FOVs.

  5. Huang Fan reporter

    Hi, Ian. I read this page, I agree it's better to use projection of

    visual->WorldPose().Pos()
    

    but as I said in last comment, how to eliminate the inconsistency between the visibility of center and all the corners? thank you.

  6. Huang Fan reporter

    Thank you Ian, currently I will check all corners to get the correct visibility, but for long term I expect gazebo dev team would override the IsVisible() function in WideAngleCamera class, to be a natural & official solution.

  7. Huang Fan reporter

    Hi, Ian. I find that rendering::Scene::VisualAt() not work for WideAngleCamera, maybe we need to use the env cameras for the _camera parameter, is there any workaround? thank you

  8. Ian Chen

    ya VisualAt currently doesn't support wide angle cameras. This will be quite tricky to implement or find a workaround. We will need to first solve the problem of identifying which env camera sees the input mouse point and the corresponding image location in that env camera before passing them to Scene::VisualAt. It's kind of an inverse problem which the Project3d function is solving. Unfortunately, I cannot think of a quick workaround for now.

  9. Log in to comment