Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
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 "graphicsOutput.h"
38#include "graphicsEngine.h"
39#include "windowFramework.h"
40#include "load_prc_file.h"
41
43
45 : vpPanda3DRendererSet(renderParameters), m_enableCrop(true), m_shouldComputeBBPoints(true)
46{
47 m_renderParameters = renderParameters;
48}
49
51{
52 if (m_shouldComputeBBPoints) {
54 m_shouldComputeBBPoints = false;
55 }
56 m_bb = computeBoundingBox();
57
58 double delta = 3.0;
59 m_bb.setTop(std::max(m_bb.getTop() - delta, 0.0));
60 m_bb.setLeft(std::max(m_bb.getLeft() - delta, 0.0));
61 m_bb.setBottom(std::min(m_bb.getBottom() + delta, static_cast<double>(m_renderParameters.getImageHeight() - 1)));
62 m_bb.setRight(std::min(m_bb.getRight() + delta, static_cast<double>(m_renderParameters.getImageWidth() - 1)));
63
64 if (m_enableCrop) {
66
67 unsigned width = static_cast<unsigned int>(m_bb.getWidth());
68 unsigned height = static_cast<unsigned int>(m_bb.getHeight());
69 subParams.setImageResolution(height, width);
70 subParams.setClippingDistance(subParams.getNearClippingDistance(), subParams.getFarClippingDistance());
71 const vpCameraParameters cam = subParams.getCameraIntrinsics();
72 subParams.setCameraIntrinsics(vpCameraParameters(cam.get_px(), cam.get_py(), cam.get_u0() - m_bb.getLeft(), cam.get_v0() - m_bb.getTop()));
73 for (std::shared_ptr<vpPanda3DBaseRenderer> &subrenderer : m_subRenderers) {
74 subrenderer->setRenderParameters(subParams);
75 }
76 }
78}
79
81{
82 if (m_subRenderers.size() == 0) {
83 throw vpException(vpException::fatalError, "Cannot compute bounding box with no subrender");
84 }
85 std::shared_ptr<vpPanda3DBaseRenderer> subrenderer = m_subRenderers[0];
86 NodePath object = subrenderer->getRenderRoot().find(m_focusedObject);
87 if (object.is_empty()) {
88 throw vpException(vpException::badValue, "Focused node %s was not found", m_focusedObject.c_str());
89 }
90 m_bb3DPoints.clear();
91 LPoint3 minP, maxP;
92 object.calc_tight_bounds(minP, maxP);
93 const BoundingBox box(minP, maxP);
94
95 for (unsigned int i = 0; i < 8; ++i) {
96 const LPoint3 p = box.get_point(i);
97 m_bb3DPoints.push_back(vpColVector({ p.get_x(), -p.get_z(), p.get_y(), 1.0 }));
98 }
99}
100
101void vpObjectCentricRenderer::computeClipping(float &nearV, float &farV)
102{
103 if (m_subRenderers.size() == 0) {
104 throw vpException(vpException::fatalError, "Cannot compute clpping distances with no subrenderer");
105 }
106 std::shared_ptr<vpPanda3DBaseRenderer> subrenderer = m_subRenderers[0];
107 NodePath object = subrenderer->getRenderRoot().find(m_focusedObject);
108 if (object.is_empty()) {
109 throw vpException(vpException::badValue, "Node %s was not found", m_focusedObject.c_str());
110 }
111 if (m_shouldComputeBBPoints) {
113 m_shouldComputeBBPoints = false;
114 }
115 const vpHomogeneousMatrix wTcam = getCameraPose();
116 const vpHomogeneousMatrix wTobj = getNodePose(m_focusedObject) * vpPanda3DBaseRenderer::vispToPanda();
117 const vpHomogeneousMatrix camTobj = wTcam.inverse() * wTobj;
118 float minZ = std::numeric_limits<float>::max(), maxZ = 0.f;
119 for (unsigned int i = 0; i < m_bb3DPoints.size(); ++i) {
120 vpColVector cpV = camTobj * m_bb3DPoints[i];
121 cpV /= cpV[3];
122 float Z = cpV[2];
123 if (Z > maxZ) {
124 maxZ = Z;
125 }
126 if (Z < minZ) {
127 minZ = Z;
128 }
129 }
130 nearV = minZ;
131 farV = maxZ;
132}
133
135{
136 if (m_subRenderers.size() == 0) {
137 throw vpException(vpException::fatalError, "Cannot compute bounding box with no subrenderer");
138 }
139 std::shared_ptr<vpPanda3DBaseRenderer> subrenderer = m_subRenderers[0];
140 NodePath object = subrenderer->getRenderRoot().find(m_focusedObject);
141 if (object.is_empty()) {
142 throw vpException(vpException::badValue, "Node %s was not found", m_focusedObject.c_str());
143 }
144 if (m_shouldComputeBBPoints) {
146 m_shouldComputeBBPoints = false;
147 }
148 const auto pointToPixel = [this](const vpHomogeneousMatrix &camTobj, const vpColVector &point) -> vpImagePoint {
149 vpColVector cpV = camTobj * point;
150 cpV /= cpV[3];
151 double x = cpV[0] / cpV[2];
152 double y = cpV[1] / cpV[2];
153 vpImagePoint ip;
154 vpMeterPixelConversion::convertPoint(m_renderParameters.getCameraIntrinsics(), x, y, ip);
155 ip.set_j(vpMath::clamp(ip.get_j(), 0.0, m_renderParameters.getImageWidth() - 1.0));
156 ip.set_i(vpMath::clamp(ip.get_i(), 0.0, m_renderParameters.getImageHeight() - 1.0));
157 return ip;
158 };
159
160 const vpHomogeneousMatrix wTcam = getCameraPose();
161 const vpHomogeneousMatrix wTobj = getNodePose(m_focusedObject) * vpPanda3DBaseRenderer::vispToPanda();
162 const vpHomogeneousMatrix camTobj = wTcam.inverse() * wTobj;
163
164 double minu = m_renderParameters.getImageWidth(), maxu = 0.0, minv = m_renderParameters.getImageHeight(), maxv = 0.0;
165 for (unsigned int i = 0; i < m_bb3DPoints.size(); ++i) {
166 const vpImagePoint ip = pointToPixel(camTobj, m_bb3DPoints[i]);
167 double u = ip.get_u(), v = ip.get_v();
168 if (u < minu) {
169 minu = u;
170 }
171 if (u > maxu) {
172 maxu = u;
173 }
174 if (v < minv) {
175 minv = v;
176 }
177 if (v > maxv) {
178 maxv = v;
179 }
180 }
181 return vpRect(vpImagePoint(minv, minu), vpImagePoint(maxv, maxu));
182}
183
184END_VISP_NAMESPACE
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
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 ...
void set_j(double jj)
double get_j() const
void set_i(double ii)
double get_u() const
double get_i() const
double get_v() const
static T clamp(const T &v, const T &lower, const T &upper)
Definition vpMath.h:219
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)
static const vpHomogeneousMatrix & vispToPanda()
vpPanda3DRenderParameters m_renderParameters
Pointer to owning window, which can create buffers etc. It is not necessarily visible.
Rendering parameters for a panda3D simulation.
void setClippingDistance(double nearV, double farV)
Set the clipping distance. When a panda camera uses these render parameters, objects that are closer ...
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...
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.
virtual void beforeFrameRendered() VP_OVERRIDE
Defines a rectangle in the plane.
Definition vpRect.h:79