ImageProviderDynamicSimulation.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2013-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author Nikolaus Vahrenkamp
20  * @date 2014
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #include <exception>
26 
27 #include <Ice/Properties.h>
28 
32 
33 // VisionXCore
36 
37 // VisionXTools
41 
43 #include <Calibration/Calibration.h>
44 #include <Inventor/SoInteraction.h>
45 #include <Inventor/SoOffscreenRenderer.h>
46 #include <Inventor/nodes/SoDirectionalLight.h>
47 #include <Inventor/nodes/SoUnits.h>
48 #include <Math/Math3d.h>
49 
50 namespace armarx
51 {
52  void
54  {
55  // init SoDB / Coin3D
56  //SoDB::init();
57 
58  ARMARX_INFO << "1";
59 
60  VirtualRobot::init(this->getName());
61 
62  // needed for SoSelection
63  SoInteraction::init();
64 
65  // image format
66  setImageSyncMode(visionx::eFpsSynchronization);
67  frameRate = getProperty<float>("FrameRate").getValue();
68 
69  std::string calibrationFileName = getProperty<std::string>("CalibrationFile").getValue();
70  ARMARX_VERBOSE << "Camera calibration file: " << calibrationFileName;
71 
72  if (!calibrationFileName.empty())
73  {
74  std::string fullCalibrationFileName;
75 
76  if (!ArmarXDataPath::getAbsolutePath(calibrationFileName, fullCalibrationFileName))
77  {
78  ARMARX_ERROR << "Could not find camera calibration file in ArmarXDataPath: "
79  << calibrationFileName;
80  }
81 
82  setlocale(LC_NUMERIC, "C");
83 
84  CStereoCalibration ivtStereoCalibration;
85 
86  if (!ivtStereoCalibration.LoadCameraParameters(fullCalibrationFileName.c_str(), true))
87  {
88  ARMARX_ERROR << "Error loading camera calibration file: "
89  << fullCalibrationFileName;
90  }
91  stereoCalibration = visionx::tools::convert(ivtStereoCalibration);
92 
93  renderImg_width = stereoCalibration->calibrationLeft.cameraParam.width;
94  renderImg_height = stereoCalibration->calibrationLeft.cameraParam.height;
95 
96  ARMARX_CHECK_EQUAL(stereoCalibration->calibrationLeft.cameraParam.height,
98  ARMARX_CHECK_EQUAL(stereoCalibration->calibrationRight.cameraParam.height,
100  ARMARX_CHECK_EQUAL(stereoCalibration->calibrationLeft.cameraParam.width,
102  ARMARX_CHECK_EQUAL(stereoCalibration->calibrationRight.cameraParam.width,
104  }
105  else
106  {
107  const visionx::ImageDimension dimensions =
108  getProperty<visionx::ImageDimension>("ImageSize").getValue();
109 
110  renderImg_width = dimensions.width;
111  renderImg_height = dimensions.height;
112  }
113 
114  setImageFormat(visionx::ImageDimension{renderImg_width, renderImg_height}, visionx::eRgb);
115 
116  renderImg_bpp = 3;
117 
118 
119  setNumberImages(2);
120  images = new CByteImage*[getNumberImages()];
121 
122  for (int i = 0; i < getNumberImages(); i++)
123  {
124  images[i] = new CByteImage(renderImg_width, renderImg_height, CByteImage::eRGB24);
125  }
126 
127  resizedImages = new CByteImage*[getNumberImages()];
128 
129  for (int i = 0; i < getNumberImages(); i++)
130  {
131  resizedImages[i] =
133  }
134 
135 
136  std::stringstream svName;
137  svName << getName() << "_PhysicsWorldVisualization";
138  simVisu =
139  Component::create<ArmarXPhysicsWorldVisualization>(getIceProperties(), svName.str());
140  getArmarXManager()->addObject(simVisu);
141  }
142 
143  void
145  {
146  if (images != NULL)
147  {
148  for (int i = 0; i < getNumberImages(); i++)
149  {
150  delete images[i];
151  delete resizedImages[i];
152  }
153 
154  delete[] images;
155  delete[] resizedImages;
156 
157  images = NULL;
158  }
159 
160  rendererLeft.reset();
161  rendererRight.reset();
162 
163  if (simVisu)
164  {
165  simVisu->releaseResources();
166  getArmarXManager()->removeObjectBlocking(simVisu);
167  }
168 
169  simVisu = NULL;
170 
171  SoDB::finish();
172  }
173 
174  void
176  {
177  ARMARX_VERBOSE << "start capture";
178 
179  // check nodes
180  robotName = getProperty<std::string>("RobotName").getValue();
181  leftNodeName = getProperty<std::string>("RobotNodeLeftCamera").getValue();
182  rightNodeName = getProperty<std::string>("RobotNodeRightCamera").getValue();
183  focalLength = getProperty<float>("focalLength").getValue();
184 
185  // ensure that all data is loaded
186  if (simVisu)
187  {
188  simVisu->synchronizeVisualizationData();
189  }
190  while (!simVisu->getRobot(robotName))
191  {
192  usleep(100000);
193  simVisu->synchronizeVisualizationData();
194  ARMARX_INFO << deactivateSpam(3) << "Waiting for visu";
195  }
197  }
198 
199  bool
201  const std::string& cameraSensorNameLeft,
202  const std::string& cameraSensorNameRight)
203  {
204  std::unique_lock lock(captureMutex);
205  auto l = simVisu->getScopedLock();
206 
207  rendererLeft.reset(VirtualRobot::CoinVisualizationFactory::createOffscreenRenderer(
209  rendererRight.reset(VirtualRobot::CoinVisualizationFactory::createOffscreenRenderer(
211 
212  // some checks...
213  if (!simVisu || !simVisu->getVisualization())
214  {
215  ARMARX_ERROR << "No physics visualization scene";
216  return false;
217  }
218 
219  return true;
220  }
221 
222  static void
223  copyRenderBufferToByteImage(CByteImage* image, std::uint8_t* renderBuffer)
224  {
225  int height = image->height;
226  int width = image->width;
227  std::uint8_t* pixelsRow = image->pixels;
228  std::uint8_t* renderBufferEndOfRow = renderBuffer + 3 * (width - 1);
229  for (int y = 0; y < height; y++)
230  {
231  for (int x = 0; x < width; x++)
232  {
233  pixelsRow[x * 3 + 0] = renderBufferEndOfRow[-x * 3 + 0];
234  pixelsRow[x * 3 + 1] = renderBufferEndOfRow[-x * 3 + 1];
235  pixelsRow[x * 3 + 2] = renderBufferEndOfRow[-x * 3 + 2];
236  }
237  pixelsRow += width * 3;
238  renderBufferEndOfRow += width * 3;
239  }
240  }
241 
242  bool
244  {
245  auto l = simVisu->getScopedLock();
246 
247  if (!simVisu || !simVisu->getRobot(robotName))
248  {
249  ARMARX_WARNING << deactivateSpam() << " no visu or no robot";
250  usleep(100000);
251  return false;
252  }
253 
254  unsigned char* renderBuffer = NULL;
255  bool renderOK = false;
256 
257 
258  cameraNodeL = simVisu->getRobot(robotName)->getRobotNode(leftNodeName);
259  cameraNodeR = simVisu->getRobot(robotName)->getRobotNode(rightNodeName);
260 
261  if (!rendererLeft || !cameraNodeL)
262  {
263  ARMARX_ERROR << deactivateSpam() << "No renderer Left, node:" << leftNodeName;
264  return false;
265  }
266 
267  if (!rendererRight || !cameraNodeR)
268  {
269  ARMARX_ERROR << deactivateSpam() << "No renderer Right, node: " << rightNodeName;
270  return false;
271  }
272 
273 
274  if (not stereoCalibration.has_value())
275  {
276  initStereoCalib();
277  }
278 
279  float fovLeft =
280  2.0 * std::atan(renderImg_height /
281  (2.0 * stereoCalibration->calibrationLeft.cameraParam.focalLength[1]));
282  float fovRight =
283  2.0 * std::atan(renderImg_height /
284  (2.0 * stereoCalibration->calibrationRight.cameraParam.focalLength[1]));
285  // ARMARX_LOG << "fov left: " << (fovLeft / M_PI * 180.0) << " fov right: " << (fovRight / M_PI * 180.0);
286 
287 
288  // render Left Camera
289 #if 1
290  renderOK =
291  VirtualRobot::CoinVisualizationFactory::renderOffscreen(rendererLeft.get(),
292  cameraNodeL,
293  simVisu->getVisualization(),
294  &renderBuffer,
295  100.0f,
296  100000.0f,
297  fovLeft);
298 #else
299  //////////////// optional: we render by our own
300  SoPerspectiveCamera* cam = new SoPerspectiveCamera();
301  cam->ref();
302  // set camera position and orientation
303  Eigen::Matrix4f camPose = cameraNodeL->getGlobalPose();
304  Eigen::Vector3f camPos = MathTools::getTranslation(camPose);
305  float sc = 0.001f; // to m
306  cam->position.setValue(camPos[0] * sc, camPos[1] * sc, camPos[2] * sc);
307 
308  SbRotation align(
309  SbVec3f(1, 0, 0),
310  (float)(M_PI)); // first align from default direction -z to +z by rotating with 180 degree around x axis
311  SbRotation align2(
312  SbVec3f(0, 0, 1),
313  (float)(-M_PI / 2.0)); // align up vector by rotating with -90 degree around z axis
314  SbRotation trans(
315  CoinVisualizationFactory::getSbMatrix(camPose)); // get rotation from global pose
316  cam->orientation.setValue(align2 * align * trans); // perform total transformation
317 
318  // 10cm to 100m
319  cam->nearDistance.setValue(0.01f);
320  cam->farDistance.setValue(10000.0f);
321 
322  // add all to a inventor scene graph
323  SoSeparator* root = new SoSeparator();
324  root->ref();
325  SoDirectionalLight* light = new SoDirectionalLight;
326  root->addChild(light);
327 
328  // easy light model, no shadows or something
329  //SoLightModel *lightModel = new SoLightModel();
330  //lightModel->model = SoLightModel::BASE_COLOR;
331  //root->addChild(lightModel);
332 
333  root->addChild(cam);
334  root->addChild(simVisu->getVisualization());
335 
336  renderOK = rendererLeft.get()->render(root) == TRUE ? true : false;
337  root->unref();
338 
339  // get render buffer pointer
340  renderBuffer = rendererLeft.get()->getBuffer();
341  cam->unref();
342 
343 #endif
344 
345 
346  if (renderOK && renderBuffer != NULL)
347  {
348  copyRenderBufferToByteImage(images[0], renderBuffer);
349  }
350 
351 
352  // render Right Camera
353  renderOK =
354  VirtualRobot::CoinVisualizationFactory::renderOffscreen(rendererRight.get(),
355  cameraNodeR,
356  simVisu->getVisualization(),
357  &renderBuffer,
358  100.0f,
359  100000.0f,
360  fovRight);
361 
362  if (renderOK && renderBuffer != NULL)
363  {
364  copyRenderBufferToByteImage(images[1], renderBuffer);
365  }
366 
367  return true;
368  }
369 
370  void
372  {
373  ARMARX_VERBOSE << "stop capture";
374  }
375 
376  bool
378  {
379  bool succeeded = true;
380 
381  try
382  {
383  simVisu->synchronizeVisualizationData();
384 
385  {
386  std::unique_lock lock(captureMutex);
387  succeeded = updateCameraRendering();
388  }
389  }
390  catch (...)
391  {
393  }
394 
395  if (succeeded)
396  {
397  try
398  {
400  {
401  ARMARX_WARNING << "Shared memory provider is null (possibly shutting down)";
402  return false;
403  }
405 
406  for (int i = 0; i < getNumberImages(); i++)
407  {
408  ::ImageProcessor::Resize(images[i], resizedImages[i]);
409 
410  memcpy(ppImageBuffers[i],
411  resizedImages[i]->pixels,
412  getImageFormat().dimension.width * getImageFormat().dimension.height *
413  getImageFormat().bytesPerPixel);
414  }
415  }
416  catch (...)
417  {
419  }
420  }
421 
422 
423  return succeeded;
424  }
425 
426  void
428  {
429 
430 
431  CCalibration leftCalibration;
432  leftCalibration.SetCameraParameters(focalLength,
433  focalLength,
434  renderImg_width / 2,
435  renderImg_height / 2,
436  0,
437  0,
438  0,
439  0,
440  Math3d::unit_mat,
441  Math3d::zero_vec,
444 
446  while (!simVisu->getRobot(robotName))
447  {
448  usleep(100000);
449  simVisu->synchronizeVisualizationData();
450  ARMARX_INFO << deactivateSpam(3) << "Waiting for visu";
451  }
452 
453  ARMARX_CHECK(simVisu->synchronizeVisualizationData());
454  auto robot = simVisu->getRobot(robotName);
455  ARMARX_CHECK_NOT_NULL(robot);
456 
457  cameraNodeL = robot->getRobotNode(leftNodeName);
458  cameraNodeR = robot->getRobotNode(rightNodeName);
459 
462 
463  const Eigen::Vector3f left_P_right = cameraNodeR->getPositionInFrame(cameraNodeL);
464  ARMARX_IMPORTANT << VAROUT(left_P_right);
465 
466  CCalibration rightCalibration;
467  Vec3d transRight{-left_P_right.x(), 0, 0};
468  rightCalibration.SetCameraParameters(focalLength,
469  focalLength,
470  renderImg_width / 2,
471  renderImg_height / 2,
472  0,
473  0,
474  0,
475  0,
476  Math3d::unit_mat,
477  transRight,
480 
481  CStereoCalibration ivtStereoCalibration;
482  ivtStereoCalibration.SetSingleCalibrations(leftCalibration, rightCalibration);
483  stereoCalibration = visionx::tools::convert(ivtStereoCalibration);
484  }
485 
486  visionx::StereoCalibration
488  {
489  if (not stereoCalibration.has_value())
490  {
491  initStereoCalib();
492  }
493 
494  return stereoCalibration.value();
495  }
496 
497  bool
499  {
500  return true;
501  }
502 
503  std::string
505  {
506  return getProperty<std::string>("ReferenceFrame").getValue();
507  }
508 
509 } // namespace armarx
armarx::ImageProviderDynamicSimulation::renderImg_bpp
int renderImg_bpp
Definition: ImageProviderDynamicSimulation.h:178
StartingCaptureFailedException.h
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::ImageProviderDynamicSimulation::initStereoCalib
void initStereoCalib()
Definition: ImageProviderDynamicSimulation.cpp:427
armarx::ImageProviderDynamicSimulation::onStartCapture
void onStartCapture(float frameRate) override
Definition: ImageProviderDynamicSimulation.cpp:175
GfxTL::Vec3d
VectorXD< 3, double > Vec3d
Definition: VectorXD.h:737
armarx::ImageProviderDynamicSimulation::simVisu
ArmarXPhysicsWorldVisualizationPtr simVisu
Definition: ImageProviderDynamicSimulation.h:184
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
visionx::CapturingImageProvider::frameRate
float frameRate
Required frame rate.
Definition: CapturingImageProvider.h:201
armarx::ImageProviderDynamicSimulation::images
CByteImage ** images
Definition: ImageProviderDynamicSimulation.h:170
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:360
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
visionx::ImageProvider::getNumberImages
int getNumberImages(const Ice::Current &c=Ice::emptyCurrent) override
Retrieve number of images handled by this provider.
Definition: ImageProvider.cpp:82
armarx::SharedMemoryScopedWriteLockPtr
std::shared_ptr< SharedMemoryScopedWriteLock > SharedMemoryScopedWriteLockPtr
Definition: SharedMemoryProvider.h:47
visionx::ImageProvider::setImageFormat
void setImageFormat(ImageDimension imageDimension, ImageType imageType, BayerPatternType bayerPatternType=visionx::eBayerPatternRg)
Sets the image basic format data.
Definition: ImageProvider.cpp:305
armarx::ImageProviderDynamicSimulation::cameraNodeL
VirtualRobot::RobotNodePtr cameraNodeL
Definition: ImageProviderDynamicSimulation.h:198
visionx::ImageProvider::getImageFormat
ImageFormatInfo getImageFormat(const Ice::Current &c=Ice::emptyCurrent) override
Returns the entire image format info struct via Ice.
Definition: ImageProvider.cpp:76
armarx::ImageProviderDynamicSimulation::resizedImages
CByteImage ** resizedImages
Definition: ImageProviderDynamicSimulation.h:171
armarx::ImageProviderDynamicSimulation::onInitCapturingImageProvider
void onInitCapturingImageProvider() override
Definition: ImageProviderDynamicSimulation.cpp:53
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
visionx::tools::createByteImage
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
armarx::ImageProviderDynamicSimulation::renderImg_height
int renderImg_height
Definition: ImageProviderDynamicSimulation.h:180
visionx::ImageProvider::sharedMemoryProvider
armarx::IceSharedMemoryProvider< unsigned char >::pointer_type sharedMemoryProvider
shared memory provider
Definition: ImageProvider.h:286
armarx::ImageProviderDynamicSimulation::rendererLeft
std::shared_ptr< SoOffscreenRenderer > rendererLeft
Definition: ImageProviderDynamicSimulation.h:192
std::align
void * align(size_t alignment, size_t bytes, void *&bufferPlace, size_t &bufferSpace) noexcept
Definition: HeterogenousContinuousContainer.h:37
visionx::tools::convert
CByteImage::ImageType convert(const ImageType visionxImageType)
Converts a VisionX image type into an image type of IVT's ByteImage.
Definition: TypeMapping.cpp:97
armarx::ImageProviderDynamicSimulation::updateCameraRendering
bool updateCameraRendering()
Definition: ImageProviderDynamicSimulation.cpp:243
M_PI
#define M_PI
Definition: MathTools.h:17
visionx::CapturingImageProvider::capture
virtual void capture()
Definition: CapturingImageProvider.cpp:109
FrameRateNotSupportedException.h
armarx::ImageProviderDynamicSimulation::renderImg_width
int renderImg_width
Definition: ImageProviderDynamicSimulation.h:179
InvalidFrameRateException.h
armarx::ImageProviderDynamicSimulation::leftNodeName
std::string leftNodeName
Definition: ImageProviderDynamicSimulation.h:196
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::ImageProviderDynamicSimulation::setupCameraRendering
bool setupCameraRendering(const std::string &robotName, const std::string &cameraSensorNameLeft, const std::string &cameraSensorNameRight)
Definition: ImageProviderDynamicSimulation.cpp:200
armarx::ImageProviderDynamicSimulation::stereoCalibration
std::optional< visionx::StereoCalibration > stereoCalibration
Definition: ImageProviderDynamicSimulation.h:203
visionx::ImageProvider::setNumberImages
void setNumberImages(int numberImages)
Sets the number of images on each capture.
Definition: ImageProvider.cpp:344
ExpressionException.h
armarx::ImageProviderDynamicSimulation::getImagesAreUndistorted
bool getImagesAreUndistorted(const Ice::Current &c=Ice::emptyCurrent) override
Returns whether images are undistorted.
Definition: ImageProviderDynamicSimulation.cpp:498
armarx::ImageProviderDynamicSimulation::focalLength
float focalLength
Definition: ImageProviderDynamicSimulation.h:201
visionx::CapturingImageProvider::setImageSyncMode
void setImageSyncMode(ImageSyncMode imageSyncMode)
Sets the image synchronization mode.
Definition: CapturingImageProvider.cpp:175
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::ImageProviderDynamicSimulation::getStereoCalibration
visionx::StereoCalibration getStereoCalibration(const Ice::Current &c=Ice::emptyCurrent) override
Returns the StereoCalibration as provided in configuration.
Definition: ImageProviderDynamicSimulation.cpp:487
armarx::ImageProviderDynamicSimulation::onExitCapturingImageProvider
void onExitCapturingImageProvider() override
Definition: ImageProviderDynamicSimulation.cpp:144
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
armarx::ImageProviderDynamicSimulation::getReferenceFrame
std::string getReferenceFrame(const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ImageProviderDynamicSimulation.cpp:504
armarx::ImageProviderDynamicSimulation::onStopCapture
void onStopCapture() override
Definition: ImageProviderDynamicSimulation.cpp:371
ImageUtil.h
armarx::ImageProviderDynamicSimulation::rightNodeName
std::string rightNodeName
Definition: ImageProviderDynamicSimulation.h:197
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:99
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:108
TypeMapping.h
armarx::ArmarXDataPath::getAbsolutePath
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
Definition: ArmarXDataPath.cpp:109
armarx::PropertyUser::getIceProperties
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
Definition: PropertyUser.cpp:221
Logging.h
armarx::ImageProviderDynamicSimulation::cameraNodeR
VirtualRobot::RobotNodePtr cameraNodeR
Definition: ImageProviderDynamicSimulation.h:199
armarx::ImageProviderDynamicSimulation::robotName
std::string robotName
Definition: ImageProviderDynamicSimulation.h:195
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:157
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
ImageProviderDynamicSimulation.h
ArmarXDataPath.h
armarx::ImageProviderDynamicSimulation::captureMutex
std::mutex captureMutex
Definition: ImageProviderDynamicSimulation.h:173
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
visionx::CapturingImageProvider::getScopedWriteLock
armarx::SharedMemoryScopedWriteLockPtr getScopedWriteLock()
Retrieve scoped lock for writing to the memory.
Definition: CapturingImageProvider.h:155
armarx::ImageProviderDynamicSimulation::rendererRight
std::shared_ptr< SoOffscreenRenderer > rendererRight
Definition: ImageProviderDynamicSimulation.h:193