Gazebo Rendering

API Reference

7.4.2
gz/rendering/base/BaseCamera.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #ifndef GZ_RENDERING_BASE_BASECAMERA_HH_
18 #define GZ_RENDERING_BASE_BASECAMERA_HH_
19 
20 #include <string>
21 
22 #include <gz/math/Matrix3.hh>
23 #include <gz/math/Pose3.hh>
24 
25 #include <gz/common/Event.hh>
26 #include <gz/common/Console.hh>
27 #include <gz/utils/SuppressWarning.hh>
28 
29 #include "gz/rendering/Camera.hh"
30 #include "gz/rendering/Image.hh"
32 #include "gz/rendering/Scene.hh"
34 
35 namespace gz
36 {
37  namespace rendering
38  {
39  inline namespace GZ_RENDERING_VERSION_NAMESPACE {
40  template <class T>
42 
43  template <class T>
44  class BaseCamera :
45  public virtual Camera,
46  public virtual T
47  {
48  protected: BaseCamera();
49 
50  public: virtual ~BaseCamera();
51 
52  public: virtual unsigned int ImageWidth() const override;
53 
54  public: virtual void SetImageWidth(const unsigned int _width) override;
55 
56  public: virtual unsigned int ImageHeight() const override;
57 
58  public: virtual void SetImageHeight(const unsigned int _height) override;
59 
60  public: virtual PixelFormat ImageFormat() const override;
61 
62  public: virtual unsigned int ImageMemorySize() const override;
63 
64  public: virtual void SetImageFormat(PixelFormat _format) override;
65 
66  public: virtual math::Angle HFOV() const override;
67 
68  public: virtual void SetHFOV(const math::Angle &_hfov) override;
69 
70  public: virtual double AspectRatio() const override;
71 
72  public: virtual void SetAspectRatio(const double _ratio) override;
73 
74  public: virtual unsigned int AntiAliasing() const override;
75 
76  public: virtual void SetAntiAliasing(const unsigned int _aa) override;
77 
78  public: virtual double FarClipPlane() const override;
79 
80  public: virtual void SetFarClipPlane(const double _far) override;
81 
82  public: virtual double NearClipPlane() const override;
83 
84  public: virtual void SetNearClipPlane(const double _near) override;
85 
86  // Documentation inherited.
87  public: virtual void PreRender() override;
88 
89  // Documentation inherited.
90  public: virtual void PostRender() override;
91 
92  public: virtual void Update() override;
93 
94  public: virtual Image CreateImage() const override;
95 
96  public: virtual void Capture(Image &_image) override;
97 
98  public: virtual void Copy(Image &_image) const override;
99 
100  public: virtual bool SaveFrame(const std::string &_name) override;
101 
102  public: virtual common::ConnectionPtr ConnectNewImageFrame(
103  Camera::NewFrameListener _listener) override;
104 
105  public: virtual RenderWindowPtr CreateRenderWindow() override;
106 
107  // Documentation inherited.
108  public: virtual VisualPtr VisualAt(const gz::math::Vector2i
109  &_mousePos) override;
110 
111  // Documentation inherited.
112  public: virtual math::Matrix4d ProjectionMatrix() const override;
113 
114  // Documentation inherited.
115  public: virtual math::Matrix4d ViewMatrix() const override;
116 
117  // Documentation inherited.
118  public: virtual void SetProjectionMatrix(const math::Matrix4d &_matrix)
119  override;
120 
121  // Documentation inherited.
122  public: virtual CameraProjectionType ProjectionType() const override;
123 
124  // Documentation inherited.
125  public: virtual void SetProjectionType(
126  CameraProjectionType _type) override;
127 
128  // Documentation inherited.
129  public: virtual math::Vector2i Project(const math::Vector3d &_pt) const
130  override;
131 
132  // Documentation inherited.
133  // \sa Camera::SetMaterial(const MaterialPtr &) override;
134  public: virtual void SetMaterial(const MaterialPtr &_material)
135  override;
136 
137  // Documentation inherited.
138  public: virtual void SetTrackTarget(const NodePtr &_target,
139  const math::Vector3d &_offset,
140  const bool _worldFrame) override;
141 
142  // Documentation inherited.
143  public: virtual NodePtr TrackTarget() const override;
144 
145  // Documentation inherited.
146  public: virtual void SetTrackOffset(const math::Vector3d &_offset)
147  override;
148 
149  // Documentation inherited.
150  public: virtual math::Vector3d TrackOffset() const override;
151 
152  // Documentation inherited.
153  public: virtual void SetTrackPGain(const double _pGain) override;
154 
155  // Documentation inherited.
156  public: virtual double TrackPGain() const override;
157 
158  // Documentation inherited.
159  public: virtual void SetFollowTarget(const NodePtr &_target,
160  const math::Vector3d &_Offset, const bool _worldFrame)
161  override;
162 
163  // Documentation inherited.
164  public: virtual NodePtr FollowTarget() const override;
165 
166  // Documentation inherited.
167  public: virtual void SetFollowOffset(const math::Vector3d &_offset)
168  override;
169 
170  // Documentation inherited.
171  public: virtual math::Vector3d FollowOffset() const override;
172 
173  // Documentation inherited.
174  public: virtual void SetFollowPGain(const double _pGain) override;
175 
176  // Documentation inherited.
177  public: virtual double FollowPGain() const override;
178 
179  // Documentation inherited.
180  public: virtual unsigned int RenderTextureGLId() const override;
181 
182  // Documentation inherited.
183  public: virtual void RenderTextureMetalId(void *_textureIdPtr)
184  const override;
185 
186  // Documentation inherited.
187  public: virtual void AddRenderPass(const RenderPassPtr &_pass) override;
188 
189  // Documentation inherited.
190  public: virtual void RemoveRenderPass(const RenderPassPtr &_pass)
191  override;
192 
193  // Documentation inherited.
194  public: virtual unsigned int RenderPassCount() const override;
195 
196  // Documentation inherited.
197  public: virtual RenderPassPtr RenderPassByIndex(unsigned int _index)
198  const override;
199 
200  // Documentation inherited.
201  public: virtual void SetShadowsDirty() override;
202 
203  protected: virtual void *CreateImageBuffer() const;
204 
205  protected: virtual void Load() override;
206 
207  protected: virtual void Reset();
208 
209  protected: virtual RenderTargetPtr RenderTarget() const = 0;
210 
211  GZ_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING
212  protected: common::EventT<void(const void *, unsigned int, unsigned int,
213  unsigned int, const std::string &)> newFrameEvent;
214 
215  protected: ImagePtr imageBuffer;
216 
218  protected: double nearClip = 0.01;
219 
221  protected: double farClip = 1000.0;
222 
224  protected: double aspect = 1.3333333;
225 
227  protected: math::Angle hfov;
228 
230  protected: unsigned int antiAliasing = 0u;
231 
233  protected: NodePtr trackNode;
234 
236  protected: bool trackWorldFrame = false;
237 
241 
244  protected: double trackPGain = 1.0;
245 
247  protected: NodePtr followNode;
248  GZ_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING
249 
251  protected: bool followWorldFrame = false;
252 
255  protected: double followPGain = 1.0;
256 
259 
262 
264  protected: CameraProjectionType projectionType = CPT_PERSPECTIVE;
265 
266  friend class BaseDepthCamera<T>;
267  };
268 
270  template <class T>
272  {
273  }
274 
276  template <class T>
278  {
279  }
280 
282  template <class T>
283  unsigned int BaseCamera<T>::ImageWidth() const
284  {
285  return this->RenderTarget()->Width();
286  }
287 
289  template <class T>
290  void BaseCamera<T>::SetImageWidth(const unsigned int _width)
291  {
292  this->RenderTarget()->SetWidth(_width);
293  this->SetAspectRatio(
294  static_cast<double>(_width) / static_cast<double>(this->ImageHeight()));
295  }
296 
298  template <class T>
299  unsigned int BaseCamera<T>::ImageHeight() const
300  {
301  return this->RenderTarget()->Height();
302  }
303 
305  template <class T>
306  void BaseCamera<T>::SetImageHeight(const unsigned int _height)
307  {
308  this->RenderTarget()->SetHeight(_height);
309  this->SetAspectRatio(
310  static_cast<double>(this->ImageWidth()) / static_cast<double>(_height));
311  }
312 
314  template <class T>
315  unsigned int BaseCamera<T>::ImageMemorySize() const
316  {
317  PixelFormat format = this->ImageFormat();
318  unsigned int width = this->ImageWidth();
319  unsigned int height = this->ImageHeight();
320  return PixelUtil::MemorySize(format, width, height);
321  }
322 
324  template <class T>
326  {
327  return this->RenderTarget()->Format();
328  }
329 
331  template <class T>
333  {
334  this->RenderTarget()->SetFormat(_format);
335  }
336 
338  template <class T>
340  {
341  T::PreRender();
342 
343  this->RenderTarget()->PreRender();
344 
345  // camera following
346  if (this->followNode)
347  {
348  // tether camera fixed in world frame
349  if (this->followWorldFrame)
350  {
351  math::Vector3d targetCamPos =
352  this->followNode->WorldPosition() + this->followOffset;
353  math::Vector3d pos = this->WorldPosition() +
354  (targetCamPos - this->WorldPosition()) * this->followPGain;
355  this->SetWorldPosition(pos);
356  }
357  // tether camera fixed in target's local frame
358  else
359  {
360  math::Pose3d targetCamPose = math::Pose3d(this->followOffset,
361  this->WorldRotation());
362  targetCamPose = this->followNode->WorldPose() * targetCamPose;
363 
364  math::Vector3d pos = this->WorldPosition() +
365  (targetCamPose.Pos() - this->WorldPosition()) * this->followPGain;
366  this->SetWorldPosition(pos);
367  }
368  }
369 
370  // camera tracking
371  if (this->trackNode)
372  {
373  math::Vector3d eye = this->WorldPosition();
374  math::Pose3d targetPose = math::Pose3d(this->trackOffset,
376  if (this->trackWorldFrame)
377  {
378  targetPose.Pos() += this->trackNode->WorldPosition();
379  }
380  else
381  {
382  targetPose = this->trackNode->WorldPose() * targetPose;
383  }
384 
385  math::Pose3d p =
386  math::Matrix4d::LookAt(eye, targetPose.Pos()).Pose();
387 
388  math::Quaterniond q = p.Rot();
389  // skip slerp if we don't need it
390  if (!math::equal(this->trackPGain, 1.0))
391  {
393  this->trackPGain, this->WorldRotation(), p.Rot(), true);
394  }
395  this->SetWorldRotation(q);
396  }
397  }
398 
400  template <class T>
402  {
403  this->RenderTarget()->PostRender();
404  }
405 
407  template <class T>
409  {
410  PixelFormat format = this->ImageFormat();
411  unsigned int width = this->ImageWidth();
412  unsigned int height = this->ImageHeight();
413  return Image(width, height, format);
414  }
415 
417  template <class T>
419  {
420  this->Scene()->PreRender();
421  this->Render();
422  this->PostRender();
423  if (!this->Scene()->LegacyAutoGpuFlush())
424  {
425  this->Scene()->PostRender();
426  }
427  }
428 
430  template <class T>
432  {
433  this->Update();
434  this->Copy(_image);
435  }
436 
438  template <class T>
439  void BaseCamera<T>::Copy(Image &_image) const
440  {
441  this->RenderTarget()->Copy(_image);
442  }
443 
445  template <class T>
446  bool BaseCamera<T>::SaveFrame(const std::string &/*_name*/)
447  {
448  return false;
449  }
450 
452  template <class T>
454  Camera::NewFrameListener _listener)
455  {
456  return newFrameEvent.Connect(_listener);
457  }
458 
460  template <class T>
462  {
463  // TODO(anyone): determine proper type
464  unsigned int size = this->ImageMemorySize();
465  return new unsigned char *[size];
466  }
467 
469  template <class T>
471  {
472  T::Load();
473  }
474 
476  template <class T>
478  {
479  math::Angle fov;
480  fov.SetDegree(60);
481  this->SetImageWidth(1);
482  this->SetImageHeight(1);
483  this->SetImageFormat(PF_R8G8B8);
484  this->SetAspectRatio(0.0);
485  this->SetAntiAliasing(0u);
486  this->SetHFOV(fov);
487  this->SetNearClipPlane(0.01);
488  this->SetFarClipPlane(1000);
489  }
490 
492  template <class T>
494  {
495  // Does nothing by default
496  gzerr << "Render window not supported for render engine: " <<
497  this->Scene()->Engine()->Name() << std::endl;
498  return RenderWindowPtr();
499  }
500 
502  template <class T>
504  {
505  math::Matrix4d result = this->projectionMatrix;
506  if (this->projectionType == CPT_PERSPECTIVE)
507  {
508  double ratio = this->AspectRatio();
509  double fov = this->HFOV().Radian();
510  double vfov = 2.0 * std::atan(std::tan(fov / 2.0) / ratio);
511  double f = 1.0;
512  double _near = this->NearClipPlane();
513  double _far = this->FarClipPlane();
514  double top = _near * std::tan(0.5*vfov) / f;
515  double height = 2 * top;
516  double width = ratio * height;
517  double left = -0.5 * width;
518  double right = left + width;
519  double bottom = top - height;
520 
521  double invw = 1.0 / (right - left);
522  double invh = 1.0 / (top - bottom);
523  double invd = 1.0 / (_far - _near);
524  double x = 2 * _near * invw;
525  double y = 2 * _near * invh;
526  double a = (right + left) * invw;
527  double b = (top + bottom) * invh;
528  double c = -(_far + _near) * invd;
529  double d = -2 * _far * _near * invd;
530  result(0, 0) = x;
531  result(0, 2) = a;
532  result(1, 1) = y;
533  result(1, 2) = b;
534  result(2, 2) = c;
535  result(2, 3) = d;
536  result(3, 2) = -1;
537  }
538  else if (this->projectionType == CPT_ORTHOGRAPHIC)
539  {
540  double width = this->ImageWidth();
541  double height = this->ImageHeight();
542  double left = -width * 0.5;
543  double right = -left;
544  double top = height * 0.5;
545  double bottom = -top;
546  double _near = this->NearClipPlane();
547  double _far = this->FarClipPlane();
548 
549  double invw = 1.0 / (right - left);
550  double invh = 1.0 / (top - bottom);
551  double invd = 1.0 / (_far - _near);
552 
553  result(0, 0) = 2.0 * invw;
554  result(0, 3) = -(right + left) * invw;
555  result(1, 1) = 2.0 * invh;
556  result(1, 3) = -(top + bottom) * invh;
557  result(2, 2) = -2.0 * invd;
558  result(2, 3) = -(_far + _near) * invd;
559  result(3, 3) = 1.0;
560  }
561  else
562  {
563  gzerr << "Unknown camera projection type: " << this->projectionType
564  << std::endl;
565  }
566 
567  return result;
568  }
569 
571  template <class T>
573  {
574  this->projectionMatrix = _matrix;
575  }
576 
578  template <class T>
580  {
581  math::Matrix3d r(this->WorldPose().Rot());
582  // transform from y up to z up
583  math::Matrix3d tf(0, 0, -1,
584  -1, 0, 0,
585  0, 1, 0);
586  r = r * tf;
587  r.Transpose();
588  math::Vector3d t = r * this->WorldPose().Pos() * -1;
589  math::Matrix4d result;
590  result = r;
591  result.SetTranslation(t);
592  result(3, 3) = 1.0;
593  return result;
594  }
595 
597  template <class T>
599  {
600  this->projectionType = _type;
601  }
602 
604  template <class T>
606  {
607  return this->projectionType;
608  }
609 
611  template <class T>
613  {
614  math::Vector2i screenPos;
615  math::Matrix4d m = this->ProjectionMatrix() * this->ViewMatrix();
616  math::Vector3d pos = m * _pt;
617  double w = m(3, 0) * _pt.X() + m(3, 1) * _pt.Y() + m(3, 2) * _pt.Z()
618  + m(3, 3);
619  pos.X() = pos.X() / w;
620  pos.Y() = pos.Y() / w;
621 
622  screenPos.X() = static_cast<int>(
623  ((pos.X() / 2.0) + 0.5) * this->ImageWidth());
624  screenPos.Y() = static_cast<int>(
625  (1 - ((pos.Y() / 2.0) + 0.5)) * this->ImageHeight());
626  return screenPos;
627  }
628 
630  template <class T>
632  {
633  return this->hfov;
634  }
635 
637  template <class T>
639  &/*_mousePos*/)
640  {
641  gzerr << "VisualAt not implemented for the render engine" << std::endl;
642  return VisualPtr();
643  }
644 
646  template <class T>
648  {
649  this->hfov = _hfov;
650  }
651 
653  template <class T>
655  {
656  // Invalid AR values fallback to auto aspect ratio to maintain
657  // ABI compatibility.
658  // See https://github.com/gazebosim/gz-rendering/issues/763
659  if (this->aspect <= 0.0)
660  {
661  return static_cast<double>(this->ImageWidth()) /
662  static_cast<double>(this->ImageHeight());
663  }
664  return this->aspect;
665  }
666 
668  template <class T>
669  void BaseCamera<T>::SetAspectRatio(const double _aspect)
670  {
671  this->aspect = _aspect;
672  }
673 
675  template <class T>
676  unsigned int BaseCamera<T>::AntiAliasing() const
677  {
678  return this->antiAliasing;
679  }
680 
682  template <class T>
683  void BaseCamera<T>::SetAntiAliasing(const unsigned int _aa)
684  {
685  this->antiAliasing = _aa;
686  }
687 
689  template <class T>
691  {
692  return this->farClip;
693  }
694 
696  template <class T>
697  void BaseCamera<T>::SetFarClipPlane(const double _far)
698  {
699  this->farClip = _far;
700  }
701 
703  template <class T>
705  {
706  return this->nearClip;
707  }
708 
710  template <class T>
711  void BaseCamera<T>::SetNearClipPlane(const double _near)
712  {
713  this->nearClip = _near;
714  }
715 
717  template <class T>
719  const math::Vector3d &_offset, const bool _worldFrame)
720  {
721  this->trackNode = _target;
722  this->trackWorldFrame = _worldFrame;
723  this->trackOffset = _offset;
724  }
725 
727  template <class T>
729  {
730  return this->trackNode;
731  }
732 
734  template <class T>
736  {
737  return this->trackOffset;
738  }
739 
741  template <class T>
743  {
744  this->trackOffset = _offset;
745  }
746 
748  template <class T>
749  void BaseCamera<T>::SetTrackPGain(const double _pGain)
750  {
751  this->trackPGain = math::clamp(_pGain, 0.0, 1.0);
752  }
753 
755  template <class T>
757  {
758  return this->trackPGain;
759  }
760 
762  template <class T>
764  const math::Vector3d &_offset, const bool _worldFrame)
765  {
766  this->followNode = _target;
767  this->followWorldFrame = _worldFrame;
768  this->followOffset = _offset;
769  }
770 
772  template <class T>
774  {
775  return this->followNode;
776  }
777 
779  template <class T>
781  {
782  return this->followOffset;
783  }
784 
786  template <class T>
788  {
789  this->followOffset = _offset;
790  }
791 
793  template <class T>
794  void BaseCamera<T>::SetFollowPGain(const double _pGain)
795  {
796  this->followPGain = math::clamp(_pGain, 0.0, 1.0);
797  }
798 
800  template <class T>
802  {
803  return this->followPGain;
804  }
805 
807  template <class T>
808  void BaseCamera<T>::SetMaterial(const MaterialPtr &/*_material*/)
809  {
810  gzerr << "SetMaterial not implemented for current render"
811  << " engine" << std::endl;
812  }
813 
815  template <class T>
816  unsigned int BaseCamera<T>::RenderTextureGLId() const
817  {
818  gzerr << "RenderTextureGLId is not supported by current render"
819  << " engine" << std::endl;
820  return 0u;
821  }
822 
824  template <class T>
826  {
827  gzerr << "RenderTextureMetalId is not supported by current render"
828  << " engine" << std::endl;
829  }
830 
832  template <class T>
834  {
835  this->RenderTarget()->AddRenderPass(_pass);
836  }
837 
839  template <class T>
841  {
842  this->RenderTarget()->RemoveRenderPass(_pass);
843  }
844 
846  template <class T>
847  unsigned int BaseCamera<T>::RenderPassCount() const
848  {
849  return this->RenderTarget()->RenderPassCount();
850  }
851 
853  template <class T>
855  {
856  return this->RenderTarget()->RenderPassByIndex(_index);
857  }
858 
860  template <class T>
862  {
863  // no op
864  }
865  }
866  }
867 }
868 #endif