Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
vpPanda3DRendererSet.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/ar/vpPanda3DRendererSet.h>
32 
33 #if defined(VISP_HAVE_PANDA3D)
34 
35 #include "load_prc_file.h"
36 
37 BEGIN_VISP_NAMESPACE
39 {
40  m_renderParameters = renderParameters;
41  load_prc_file_data("", "textures-power-2 none");
42  load_prc_file_data("", "gl-version 3 2");
43  load_prc_file_data("", "no-singular-invert");
44 }
45 
47 {
48  if (m_framework.use_count() > 0) {
49  throw vpException(vpException::notImplementedError, "Panda3D renderer: Reinitializing is not supported!");
50  }
51  m_framework = std::shared_ptr<PandaFramework>(new PandaFramework());
52 
53  m_framework->open_framework();
54  WindowProperties winProps;
55  winProps.set_size(LVecBase2i(m_renderParameters.getImageWidth(), m_renderParameters.getImageHeight()));
56  int flags = GraphicsPipe::BF_refuse_window;
57  m_window = m_framework->open_window(winProps, flags);
58  if (m_window == nullptr) {
59  winProps.set_minimized(true);
60  m_window = m_framework->open_window(winProps, 0);
61  }
62  if (m_window == nullptr) {
63  throw vpException(vpException::fatalError, "Could not open Panda3D window (hidden or visible)");
64  }
65 
66  m_window->set_background_type(WindowFramework::BackgroundType::BT_black);
67  for (std::shared_ptr<vpPanda3DBaseRenderer> &renderer: m_subRenderers) {
68  renderer->initFromParent(m_framework, m_window);
69  }
70 }
71 
72 void vpPanda3DRendererSet::initFromParent(std::shared_ptr<PandaFramework> framework, PointerTo<WindowFramework> window)
73 {
74  vpPanda3DBaseRenderer::initFromParent(framework, window);
75  for (std::shared_ptr<vpPanda3DBaseRenderer> &renderer: m_subRenderers) {
76  renderer->initFromParent(m_framework, m_window);
77  }
78 }
79 
81 {
83  for (std::shared_ptr<vpPanda3DBaseRenderer> &renderer: m_subRenderers) {
84  renderer->initFromParent(*this);
85  }
86 }
87 
89 {
90  for (std::shared_ptr<vpPanda3DBaseRenderer> &renderer: m_subRenderers) {
91  if (renderer->isRendering3DScene()) {
92  renderer->setCameraPose(wTc);
93  }
94  }
95 }
96 
98 {
99  if (m_subRenderers.size() == 0) {
100  throw vpException(vpException::fatalError, "cannot get the pose of an object if no subrenderer is present");
101  }
102  if (!m_subRenderers[0]->isRendering3DScene()) {
103  throw vpException(vpException::fatalError, "This renderer set only contains a non-3D renderer.");
104  }
105  return m_subRenderers[0]->getCameraPose();
106 }
107 
108 void vpPanda3DRendererSet::setNodePose(const std::string &name, const vpHomogeneousMatrix &wTo)
109 {
110  for (std::shared_ptr<vpPanda3DBaseRenderer> &renderer: m_subRenderers) {
111  if (renderer->isRendering3DScene()) {
112  renderer->setNodePose(name, wTo);
113  }
114  }
115 }
116 
118 {
119  throw vpException(vpException::badValue, "NodePath setNodePose is not supported in renderer set, prefer the string version");
120 }
121 
123 {
124  if (m_subRenderers.size() == 0) {
125  throw vpException(vpException::fatalError, "cannot get the pose of an object if no subrenderer is present");
126  }
127  if (!m_subRenderers[0]->isRendering3DScene()) {
128  throw vpException(vpException::fatalError, "This renderer set only contains a non-3D renderer.");
129  }
130  return m_subRenderers[0]->getNodePose(name);
131 }
132 
134 {
135  throw vpException(vpException::badValue, "NodePath getNodePose is not supported in renderer set, prefer the string version");
136 }
137 
138 void vpPanda3DRendererSet::addNodeToScene(const NodePath &object)
139 {
140  for (std::shared_ptr<vpPanda3DBaseRenderer> &renderer: m_subRenderers) {
141  if (renderer->isRendering3DScene()) {
142  renderer->addNodeToScene(object);
143  }
144  }
145 }
146 
148 {
149  m_renderParameters = params;
150  for (std::shared_ptr<vpPanda3DBaseRenderer> &renderer: m_subRenderers) {
151  renderer->setRenderParameters(m_renderParameters);
152  }
153 }
154 
156 {
157  for (std::shared_ptr<vpPanda3DBaseRenderer> &renderer: m_subRenderers) {
158  vpPanda3DLightable *lightable = dynamic_cast<vpPanda3DLightable *>(renderer.get());
159  if (lightable != nullptr) {
160  lightable->addLight(light);
161  }
162  }
163 }
164 
165 void vpPanda3DRendererSet::addSubRenderer(std::shared_ptr<vpPanda3DBaseRenderer> renderer)
166 {
167  for (std::shared_ptr<vpPanda3DBaseRenderer> &otherRenderer: m_subRenderers) {
168  if (renderer->getName() == otherRenderer->getName()) {
169  throw vpException(vpException::badValue, "Cannot have two subrenderers with the same name");
170  }
171  }
172  std::vector<std::shared_ptr<vpPanda3DBaseRenderer>>::const_iterator it = m_subRenderers.begin();
173  while (it != m_subRenderers.end()) {
174  if ((*it)->getRenderOrder() > renderer->getRenderOrder()) {
175  break;
176  }
177  ++it;
178  }
179  m_subRenderers.insert(it, renderer);
180 
181  renderer->setRenderParameters(m_renderParameters);
182  if (m_framework != nullptr) {
183  renderer->initFromParent(m_framework, m_window);
184  renderer->setCameraPose(getCameraPose());
185  }
186 }
187 
189 {
190  for (std::shared_ptr<vpPanda3DBaseRenderer> &subRenderer: m_subRenderers) {
191  if (subRenderer.get() != &sourceBuffer) {
192  subRenderer->enableSharedDepthBuffer(sourceBuffer);
193  }
194  }
195 }
196 
197 #elif !defined(VISP_BUILD_SHARED_LIBS)
198 // Work around to avoid warning: libvisp_ar.a(vpPanda3DRendererSet.cpp.o) has no symbols
199 void dummy_vpPanda3DRendererSet() { };
200 
201 #endif
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
@ notImplementedError
Not implemented.
Definition: vpException.h:69
@ fatalError
Fatal error.
Definition: vpException.h:72
Implementation of an homogeneous matrix and operations on such kind of matrices.
Base class for a panda3D renderer. This class handles basic functionalities, such as loading object,...
std::shared_ptr< PandaFramework > m_framework
Rendering priority for this renderer and its buffers. A lower value will be rendered first....
virtual bool isRendering3DScene() const
Returns true if this renderer process 3D data and its scene root can be interacted with.
virtual void initFromParent(std::shared_ptr< PandaFramework > framework, PointerTo< WindowFramework > window)
PointerTo< WindowFramework > m_window
Pointer to the active panda framework.
vpPanda3DRenderParameters m_renderParameters
Pointer to owning window, which can create buffers etc. It is not necessarily visible.
Base class for a Light that can be added to a Panda3D scene.
Interface for objects, scenes or other Panda3D related data that can be lit by a vpPanda3DLight.
virtual void addLight(const vpPanda3DLight &light)=0
Light this lightable object with a new light.
Rendering parameters for a panda3D simulation.
vpPanda3DRendererSet(const vpPanda3DRenderParameters &renderParameters)
void addNodeToScene(const NodePath &object) VP_OVERRIDE
void initFramework() VP_OVERRIDE
Initialize the framework and propagate the created panda3D framework to the subrenderers.
virtual void setRenderParameters(const vpPanda3DRenderParameters &params) VP_OVERRIDE
Set new rendering parameters. If the scene has already been initialized, the renderer camera is updat...
void addSubRenderer(std::shared_ptr< vpPanda3DBaseRenderer > renderer)
Add a new subrenderer: This subrenderer should have a unique name, not present in the set.
std::vector< std::shared_ptr< vpPanda3DBaseRenderer > > m_subRenderers
void enableSharedDepthBuffer(vpPanda3DBaseRenderer &sourceBuffer) VP_OVERRIDE
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.
void initFromParent(std::shared_ptr< PandaFramework > framework, PointerTo< WindowFramework > window) VP_OVERRIDE
void setNodePose(const std::string &name, const vpHomogeneousMatrix &wTo) VP_OVERRIDE
Set the pose of an object for all the subrenderers. The pose is specified using the ViSP convention T...
void addLight(const vpPanda3DLight &light) VP_OVERRIDE
Light this lightable object with a new light.
void setCameraPose(const vpHomogeneousMatrix &wTc) VP_OVERRIDE
Set the pose of the camera, using the ViSP convention. This change is propagated to all subrenderers.