Visual Servoing Platform  version 3.6.1 under development (2025-01-11)
vpObjectCentricRenderer.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  */
30 
31 #include <visp3/rbt/vpObjectCentricRenderer.h>
32 
33 #include <visp3/core/vpRect.h>
34 
35 #include "boundingSphere.h"
36 #include "boundingBox.h"
37 #include "load_prc_file.h"
38 
39 BEGIN_VISP_NAMESPACE
40 
42  : vpPanda3DRendererSet(renderParameters), m_enableCrop(true), m_shouldComputeBBPoints(true)
43 {
44  m_renderParameters = renderParameters;
45  load_prc_file_data("", "textures-power-2 none\n"
46  "back-buffers 0\n"
47  "auto-flip 1\n"
48  // "pstats-gpu-timing 1\n"
49  // "gl-finish 1\n"
50  // "texture-minfilter mipmap\n"
51  "load-file-type p3assimp\n"
52  "audio-library-name null\n"
53  "model-cache-dir\n");
54 }
55 
57 {
58  if (m_shouldComputeBBPoints) {
60  m_shouldComputeBBPoints = false;
61  }
62  m_bb = computeBoundingBox();
63 
64  double delta = 0.0;
65  m_bb.setTop(std::max(m_bb.getTop() - delta, 0.0));
66  m_bb.setLeft(std::max(m_bb.getLeft() - delta, 0.0));
67  m_bb.setBottom(std::min(m_bb.getBottom() + delta, (double)m_renderParameters.getImageHeight()));
68  m_bb.setRight(std::min(m_bb.getRight() + delta, (double)m_renderParameters.getImageWidth()));
69 
70  if (m_enableCrop) {
72 
73  unsigned width = (unsigned)(m_bb.getWidth());
74  unsigned height = (unsigned)(m_bb.getHeight());
75 
76  subParams.setImageResolution(height, width);
77 
78  const vpCameraParameters cam = subParams.getCameraIntrinsics();
79  subParams.setCameraIntrinsics(vpCameraParameters(cam.get_px(), cam.get_py(), cam.get_u0() - m_bb.getLeft(), cam.get_v0() - m_bb.getTop()));
80  for (std::shared_ptr<vpPanda3DBaseRenderer> &subrenderer : m_subRenderers) {
81  subrenderer->setRenderParameters(subParams);
82  }
83  }
84 }
85 
87 {
88  if (m_subRenderers.size() == 0) {
89  throw vpException(vpException::fatalError, "Cannot compute bounding box with no subrender");
90  }
91  std::shared_ptr<vpPanda3DBaseRenderer> subrenderer = m_subRenderers[0];
92  NodePath object = subrenderer->getRenderRoot().find(m_focusedObject);
93  if (object.is_empty()) {
94  throw vpException(vpException::badValue, "Focused node %s was not found", m_focusedObject.c_str());
95  }
96  m_bb3DPoints.clear();
97  LPoint3 minP, maxP;
98  object.calc_tight_bounds(minP, maxP);
99  const BoundingBox box(minP, maxP);
100 
101  for (unsigned int i = 0; i < 8; ++i) {
102  const LPoint3 p = box.get_point(i);
103  m_bb3DPoints.push_back(vpColVector({ p.get_x(), -p.get_z(), p.get_y(), 1.0 }));
104  }
105 }
106 
107 void vpObjectCentricRenderer::computeClipping(float &nearV, float &farV)
108 {
109  if (m_subRenderers.size() == 0) {
110  throw vpException(vpException::fatalError, "Cannot compute clpping distances with no subrenderer");
111  }
112  std::shared_ptr<vpPanda3DBaseRenderer> subrenderer = m_subRenderers[0];
113  NodePath object = subrenderer->getRenderRoot().find(m_focusedObject);
114  if (object.is_empty()) {
115  throw vpException(vpException::badValue, "Node %s was not found", m_focusedObject.c_str());
116  }
117  if (m_shouldComputeBBPoints) {
119  m_shouldComputeBBPoints = false;
120  }
121  const vpHomogeneousMatrix wTcam = getCameraPose();
123  const vpHomogeneousMatrix camTobj = wTcam.inverse() * wTobj;
124  float minZ = std::numeric_limits<float>::max(), maxZ = 0.f;
125  for (unsigned int i = 0; i < m_bb3DPoints.size(); ++i) {
126  vpColVector cpV = camTobj * m_bb3DPoints[i];
127  cpV /= cpV[3];
128  float Z = cpV[2];
129  if (Z > maxZ) {
130  maxZ = Z;
131  }
132  if (Z < minZ) {
133  minZ = Z;
134  }
135  }
136 
137  nearV = minZ;
138  farV = maxZ;
139 }
140 
142 {
143  if (m_subRenderers.size() == 0) {
144  throw vpException(vpException::fatalError, "Cannot compute bounding box with no subrenderer");
145  }
146  std::shared_ptr<vpPanda3DBaseRenderer> subrenderer = m_subRenderers[0];
147  NodePath object = subrenderer->getRenderRoot().find(m_focusedObject);
148  if (object.is_empty()) {
149  throw vpException(vpException::badValue, "Node %s was not found", m_focusedObject.c_str());
150  }
151  if (m_shouldComputeBBPoints) {
153  m_shouldComputeBBPoints = false;
154  }
155  const auto pointToPixel = [this](const vpHomogeneousMatrix &camTobj, const vpColVector &point) -> vpImagePoint {
156  vpColVector cpV = camTobj * point;
157  cpV /= cpV[3];
158  double x = cpV[0] / cpV[2];
159  double y = cpV[1] / cpV[2];
160  vpImagePoint ip;
162  ip.set_j(vpMath::clamp(ip.get_j(), 0.0, m_renderParameters.getImageWidth() - 1.0));
164  return ip;
165  };
166 
167  const vpHomogeneousMatrix wTcam = getCameraPose();
169  const vpHomogeneousMatrix camTobj = wTcam.inverse() * wTobj;
170 
171  double minu = m_renderParameters.getImageWidth(), maxu = 0.0, minv = m_renderParameters.getImageHeight(), maxv = 0.0;
172  for (unsigned int i = 0; i < m_bb3DPoints.size(); ++i) {
173  const vpImagePoint ip = pointToPixel(camTobj, m_bb3DPoints[i]);
174  double u = ip.get_u(), v = ip.get_v();
175  if (u < minu) {
176  minu = u;
177  }
178  if (u > maxu) {
179  maxu = u;
180  }
181  if (v < minv) {
182  minv = v;
183  }
184  if (v > maxv) {
185  maxv = v;
186  }
187  }
188  return vpRect(vpImagePoint(minv, minu), vpImagePoint(maxv, maxu));
189 }
190 
191 END_VISP_NAMESPACE
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:73
@ fatalError
Fatal error.
Definition: vpException.h:72
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
void set_j(double jj)
Definition: vpImagePoint.h:309
double get_j() const
Definition: vpImagePoint.h:125
void set_i(double ii)
Definition: vpImagePoint.h:298
double get_u() const
Definition: vpImagePoint.h:136
double get_i() const
Definition: vpImagePoint.h:114
double get_v() const
Definition: vpImagePoint.h:147
static T clamp(const T &v, const T &lower, const T &upper)
Definition: vpMath.h:218
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
void computeClipping(float &nearV, float &farV)
vpObjectCentricRenderer(const vpPanda3DRenderParameters &renderParameters)
void beforeFrameRendered() VP_OVERRIDE
static const vpHomogeneousMatrix PANDA_T_VISP
Homogeneous transformation matrix to convert from the Panda coordinate system (right-handed Z-up) to ...
vpPanda3DRenderParameters m_renderParameters
Pointer to owning window, which can create buffers etc. It is not necessarily visible.
Rendering parameters for a panda3D simulation.
void setCameraIntrinsics(const vpCameraParameters &cam)
set camera intrinsics. Only camera intrinsics for a lens without distortion are supported.
const vpCameraParameters & getCameraIntrinsics() const
Retrieve camera intrinsics.
void setImageResolution(unsigned int height, unsigned int width)
Set the image resolution. When this object is given to a vpPanda3DBaseRenderer, this will be the reso...
Class that renders multiple datatypes, in a single pass. A renderer set contains multiple subrenderer...
std::vector< std::shared_ptr< vpPanda3DBaseRenderer > > m_subRenderers
vpHomogeneousMatrix getCameraPose() VP_OVERRIDE
Retrieve the pose of the camera. As this renderer contains multiple other renderers.
vpHomogeneousMatrix getNodePose(const std::string &name) VP_OVERRIDE
Retrieve the pose of a scene node. The pose is in the world frame, using a ViSP convention.
Defines a rectangle in the plane.
Definition: vpRect.h:79
double getWidth() const
Definition: vpRect.h:227
void setTop(double pos)
Definition: vpRect.h:357
double getLeft() const
Definition: vpRect.h:173
void setLeft(double pos)
Definition: vpRect.h:321
void setRight(double pos)
Definition: vpRect.h:348
double getRight() const
Definition: vpRect.h:179
double getBottom() const
Definition: vpRect.h:97
double getHeight() const
Definition: vpRect.h:166
void setBottom(double pos)
Definition: vpRect.h:288
double getTop() const
Definition: vpRect.h:192