Gazebo Rendering

API Reference

9.0.0
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 <cmath>
21#include <string>
22
23#include <gz/math/Matrix3.hh>
24#include <gz/math/Pose3.hh>
25
26#include <gz/common/Event.hh>
27#include <gz/common/Console.hh>
28#include <gz/utils/SuppressWarning.hh>
29
31#include "gz/rendering/Image.hh"
33#include "gz/rendering/Scene.hh"
35
36namespace gz
37{
38 namespace rendering
39 {
40 inline namespace GZ_RENDERING_VERSION_NAMESPACE {
41 template <class T>
42 class BaseDepthCamera;
43
44 template <class T>
45 class BaseCamera :
46 public virtual Camera,
47 public virtual T
48 {
49 protected: BaseCamera();
50
51 public: virtual ~BaseCamera();
52
53 public: virtual unsigned int ImageWidth() const override;
54
55 public: virtual void SetImageWidth(const unsigned int _width) override;
56
57 public: virtual unsigned int ImageHeight() const override;
58
59 public: virtual void SetImageHeight(const unsigned int _height) override;
60
61 public: virtual PixelFormat ImageFormat() const override;
62
63 public: virtual unsigned int ImageMemorySize() const override;
64
65 public: virtual void SetImageFormat(PixelFormat _format,
66 bool _reinterpretable = false)
67 override;
68
69 public: virtual math::Angle HFOV() const override;
70
71 public: virtual void SetHFOV(const math::Angle &_hfov) override;
72
73 public: virtual double AspectRatio() const override;
74
75 public: virtual void SetAspectRatio(const double _ratio) override;
76
77 public: virtual unsigned int AntiAliasing() const override;
78
79 public: virtual void SetAntiAliasing(const unsigned int _aa) override;
80
81 public: virtual double FarClipPlane() const override;
82
83 public: virtual void SetFarClipPlane(const double _far) override;
84
85 public: virtual double NearClipPlane() const override;
86
87 public: virtual void SetNearClipPlane(const double _near) override;
88
89 // Documentation inherited.
90 public: virtual void PreRender() override;
91
92 // Documentation inherited.
93 public: virtual void PostRender() override;
94
95 public: virtual void Update() override;
96
97 public: virtual Image CreateImage() const override;
98
99 public: virtual void Capture(Image &_image) override;
100
101 public: virtual void Copy(Image &_image) const override;
102
103 public: virtual bool SaveFrame(const std::string &_name) override;
104
106 Camera::NewFrameListener _listener) override;
107
108 public: virtual RenderWindowPtr CreateRenderWindow() override;
109
110 // Documentation inherited.
112 &_mousePos) override;
113
114 // Documentation inherited.
115 public: virtual math::Matrix4d ProjectionMatrix() const override;
116
117 // Documentation inherited.
118 public: virtual math::Matrix4d ViewMatrix() const override;
119
120 // Documentation inherited.
121 public: virtual void SetProjectionMatrix(const math::Matrix4d &_matrix)
122 override;
123
124 // Documentation inherited.
125 public: virtual CameraProjectionType ProjectionType() const override;
126
127 // Documentation inherited.
128 public: virtual void SetProjectionType(
129 CameraProjectionType _type) override;
130
131 // Documentation inherited.
132 public: virtual math::Vector2i Project(const math::Vector3d &_pt) const
133 override;
134
135 // Documentation inherited.
136 // \sa Camera::SetMaterial(const MaterialPtr &) override;
137 public: virtual void SetMaterial(const MaterialPtr &_material)
138 override;
139
140 // Documentation inherited.
141 public: virtual void SetTrackTarget(const NodePtr &_target,
142 const math::Vector3d &_offset,
143 const bool _worldFrame) override;
144
145 // Documentation inherited.
146 public: virtual NodePtr TrackTarget() const override;
147
148 // Documentation inherited.
149 public: virtual void SetTrackOffset(const math::Vector3d &_offset)
150 override;
151
152 // Documentation inherited.
153 public: virtual math::Vector3d TrackOffset() const override;
154
155 // Documentation inherited.
156 public: virtual void SetTrackPGain(const double _pGain) override;
157
158 // Documentation inherited.
159 public: virtual double TrackPGain() const override;
160
161 // Documentation inherited.
162 public: virtual void SetFollowTarget(const NodePtr &_target,
163 const math::Vector3d &_Offset, const bool _worldFrame)
164 override;
165
166 // Documentation inherited.
167 public: virtual NodePtr FollowTarget() const override;
168
169 // Documentation inherited.
170 public: virtual void SetFollowOffset(const math::Vector3d &_offset)
171 override;
172
173 // Documentation inherited.
174 public: virtual math::Vector3d FollowOffset() const override;
175
176 // Documentation inherited.
177 public: virtual void SetFollowPGain(const double _pGain) override;
178
179 // Documentation inherited.
180 public: virtual double FollowPGain() const override;
181
182 // Documentation inherited.
183 public: virtual unsigned int RenderTextureGLId() const override;
184
185 // Documentation inherited.
186 public: virtual void RenderTextureMetalId(void *_textureIdPtr)
187 const override;
188
189 // Documentation inherited.
190 public: virtual void PrepareForExternalSampling() override;
191
192 // Documentation inherited.
193 public: virtual void AddRenderPass(const RenderPassPtr &_pass) override;
194
195 // Documentation inherited.
196 public: virtual void RemoveRenderPass(const RenderPassPtr &_pass)
197 override;
198
199 // Documentation inherited.
200 public: void RemoveAllRenderPasses() override;
201
202 // Documentation inherited.
203 public: virtual unsigned int RenderPassCount() const override;
204
205 // Documentation inherited.
206 public: virtual RenderPassPtr RenderPassByIndex(unsigned int _index)
207 const override;
208
209 // Documentation inherited.
210 public: virtual void SetShadowsDirty() override;
211
212 protected: virtual void *CreateImageBuffer() const;
213
214 protected: virtual void Load() override;
215
216 protected: virtual void Reset();
217
218 protected: virtual RenderTargetPtr RenderTarget() const = 0;
219
220 GZ_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING
221 protected: common::EventT<void(const void *, unsigned int, unsigned int,
222 unsigned int, const std::string &)> newFrameEvent;
223
225
227 protected: double nearClip = 0.01;
228
230 protected: double farClip = 1000.0;
231
233 protected: double aspect = 1.3333333;
234
236 protected: math::Angle hfov;
237
239 protected: unsigned int antiAliasing = 0u;
240
242 protected: NodePtr trackNode;
243
245 protected: bool trackWorldFrame = false;
246
250
253 protected: double trackPGain = 1.0;
254
256 protected: NodePtr followNode;
257 GZ_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING
258
260 protected: bool followWorldFrame = false;
261
264 protected: double followPGain = 1.0;
265
268
271
273 protected: CameraProjectionType projectionType = CPT_PERSPECTIVE;
274
275 friend class BaseDepthCamera<T>;
276 };
277
279 template <class T>
283
285 template <class T>
289
291 template <class T>
292 unsigned int BaseCamera<T>::ImageWidth() const
293 {
294 return this->RenderTarget()->Width();
295 }
296
298 template <class T>
299 void BaseCamera<T>::SetImageWidth(const unsigned int _width)
300 {
301 this->RenderTarget()->SetWidth(_width);
302 this->SetAspectRatio(
303 static_cast<double>(_width) / static_cast<double>(this->ImageHeight()));
304 }
305
307 template <class T>
308 unsigned int BaseCamera<T>::ImageHeight() const
309 {
310 return this->RenderTarget()->Height();
311 }
312
314 template <class T>
315 void BaseCamera<T>::SetImageHeight(const unsigned int _height)
316 {
317 this->RenderTarget()->SetHeight(_height);
318 this->SetAspectRatio(
319 static_cast<double>(this->ImageWidth()) / static_cast<double>(_height));
320 }
321
323 template <class T>
325 {
326 PixelFormat format = this->ImageFormat();
327 unsigned int width = this->ImageWidth();
328 unsigned int height = this->ImageHeight();
329 return PixelUtil::MemorySize(format, width, height);
330 }
331
333 template <class T>
335 {
336 return this->RenderTarget()->Format();
337 }
338
340 template <class T>
342 bool _reinterpretable)
343 {
344 this->RenderTarget()->SetFormat(_format, _reinterpretable);
345 }
346
348 template <class T>
350 {
351 T::PreRender();
352
353 {
354 CameraPtr camera =
355 std::dynamic_pointer_cast<Camera>(this->shared_from_this());
356 this->RenderTarget()->PreRender(camera);
357 }
358
359 // camera following
360 if (this->followNode)
361 {
362 // tether camera fixed in world frame
363 if (this->followWorldFrame)
364 {
365 math::Vector3d targetCamPos =
366 this->followNode->WorldPosition() + this->followOffset;
367 math::Vector3d pos = this->WorldPosition() +
368 (targetCamPos - this->WorldPosition()) * this->followPGain;
369 this->SetWorldPosition(pos);
370 }
371 // tether camera fixed in target's local frame
372 else
373 {
374 math::Pose3d targetCamPose = math::Pose3d(this->followOffset,
375 this->WorldRotation());
376 targetCamPose = this->followNode->WorldPose() * targetCamPose;
377
378 math::Vector3d pos = this->WorldPosition() +
379 (targetCamPose.Pos() - this->WorldPosition()) * this->followPGain;
380 this->SetWorldPosition(pos);
381 }
382 }
383
384 // camera tracking
385 if (this->trackNode)
386 {
387 math::Vector3d eye = this->WorldPosition();
388 math::Pose3d targetPose = math::Pose3d(this->trackOffset,
390 if (this->trackWorldFrame)
391 {
392 targetPose.Pos() += this->trackNode->WorldPosition();
393 }
394 else
395 {
396 targetPose = this->trackNode->WorldPose() * targetPose;
397 }
398
399 math::Pose3d p =
400 math::Matrix4d::LookAt(eye, targetPose.Pos()).Pose();
401
402 math::Quaterniond q = p.Rot();
403 // skip slerp if we don't need it
404 if (!math::equal(this->trackPGain, 1.0))
405 {
407 this->trackPGain, this->WorldRotation(), p.Rot(), true);
408 }
409 this->SetWorldRotation(q);
410 }
411 }
412
414 template <class T>
416 {
417 this->RenderTarget()->PostRender();
418 }
419
421 template <class T>
423 {
424 PixelFormat format = this->ImageFormat();
425 unsigned int width = this->ImageWidth();
426 unsigned int height = this->ImageHeight();
427 return Image(width, height, format);
428 }
429
431 template <class T>
433 {
434 this->Scene()->PreRender();
435 this->Render();
436 this->PostRender();
437 if (!this->Scene()->LegacyAutoGpuFlush())
438 {
439 this->Scene()->PostRender();
440 }
441 }
442
444 template <class T>
446 {
447 this->Update();
448 this->Copy(_image);
449 }
450
452 template <class T>
453 void BaseCamera<T>::Copy(Image &_image) const
454 {
455 this->RenderTarget()->Copy(_image);
456 }
457
459 template <class T>
461 {
462 return false;
463 }
464
466 template <class T>
468 Camera::NewFrameListener _listener)
469 {
470 return newFrameEvent.Connect(_listener);
471 }
472
474 template <class T>
476 {
477 // TODO(anyone): determine proper type
478 unsigned int size = this->ImageMemorySize();
479 return new unsigned char *[size];
480 }
481
483 template <class T>
485 {
486 T::Load();
487 }
488
490 template <class T>
492 {
493 math::Angle fov;
494 fov.SetDegree(60);
495 this->SetImageWidth(1);
496 this->SetImageHeight(1);
497 this->SetImageFormat(PF_R8G8B8);
498 this->SetAspectRatio(0.0);
499 this->SetAntiAliasing(0u);
500 this->SetHFOV(fov);
501 this->SetNearClipPlane(0.01);
502 this->SetFarClipPlane(1000);
503 }
504
506 template <class T>
508 {
509 // Does nothing by default
510 gzerr << "Render window not supported for render engine: " <<
511 this->Scene()->Engine()->Name() << std::endl;
512 return RenderWindowPtr();
513 }
514
516 template <class T>
518 {
519 math::Matrix4d result = this->projectionMatrix;
520 if (this->projectionType == CPT_PERSPECTIVE)
521 {
522 double ratio = this->AspectRatio();
523 double fov = this->HFOV().Radian();
524 double vfov = 2.0 * std::atan(std::tan(fov / 2.0) / ratio);
525 double f = 1.0;
526 double _near = this->NearClipPlane();
527 double _far = this->FarClipPlane();
528 double top = _near * std::tan(0.5*vfov) / f;
529 double height = 2 * top;
530 double width = ratio * height;
531 double left = -0.5 * width;
532 double right = left + width;
533 double bottom = top - height;
534
535 double invw = 1.0 / (right - left);
536 double invh = 1.0 / (top - bottom);
537 double invd = 1.0 / (_far - _near);
538 double x = 2 * _near * invw;
539 double y = 2 * _near * invh;
540 double a = (right + left) * invw;
541 double b = (top + bottom) * invh;
542 double c = -(_far + _near) * invd;
543 double d = -2 * _far * _near * invd;
544 result(0, 0) = x;
545 result(0, 2) = a;
546 result(1, 1) = y;
547 result(1, 2) = b;
548 result(2, 2) = c;
549 result(2, 3) = d;
550 result(3, 2) = -1;
551 }
552 else if (this->projectionType == CPT_ORTHOGRAPHIC)
553 {
554 double width = this->ImageWidth();
555 double height = this->ImageHeight();
556 double left = -width * 0.5;
557 double right = -left;
558 double top = height * 0.5;
559 double bottom = -top;
560 double _near = this->NearClipPlane();
561 double _far = this->FarClipPlane();
562
563 double invw = 1.0 / (right - left);
564 double invh = 1.0 / (top - bottom);
565 double invd = 1.0 / (_far - _near);
566
567 result(0, 0) = 2.0 * invw;
568 result(0, 3) = -(right + left) * invw;
569 result(1, 1) = 2.0 * invh;
570 result(1, 3) = -(top + bottom) * invh;
571 result(2, 2) = -2.0 * invd;
572 result(2, 3) = -(_far + _near) * invd;
573 result(3, 3) = 1.0;
574 }
575 else
576 {
577 gzerr << "Unknown camera projection type: " << this->projectionType
578 << std::endl;
579 }
580
581 return result;
582 }
583
585 template <class T>
587 {
588 this->projectionMatrix = _matrix;
589 }
590
592 template <class T>
594 {
595 math::Matrix3d r(this->WorldPose().Rot());
596 // transform from y up to z up
597 math::Matrix3d tf(0, 0, -1,
598 -1, 0, 0,
599 0, 1, 0);
600 r = r * tf;
601 r.Transpose();
602 math::Vector3d t = r * this->WorldPose().Pos() * -1;
603 math::Matrix4d result;
604 result = r;
605 result.SetTranslation(t);
606 result(3, 3) = 1.0;
607 return result;
608 }
609
611 template <class T>
613 {
614 this->projectionType = _type;
615 }
616
618 template <class T>
620 {
621 return this->projectionType;
622 }
623
625 template <class T>
627 {
628 math::Vector2i screenPos;
629 math::Matrix4d m = this->ProjectionMatrix() * this->ViewMatrix();
630 math::Vector3d pos = m * _pt;
631 double w = m(3, 0) * _pt.X() + m(3, 1) * _pt.Y() + m(3, 2) * _pt.Z()
632 + m(3, 3);
633 pos.X() = pos.X() / w;
634 pos.Y() = pos.Y() / w;
635
636 screenPos.X() = static_cast<int>(
637 ((pos.X() / 2.0) + 0.5) * this->ImageWidth());
638 screenPos.Y() = static_cast<int>(
639 (1 - ((pos.Y() / 2.0) + 0.5)) * this->ImageHeight());
640 return screenPos;
641 }
642
644 template <class T>
646 {
647 return this->hfov;
648 }
649
651 template <class T>
653 &/*_mousePos*/)
654 {
655 gzerr << "VisualAt not implemented for the render engine" << std::endl;
656 return VisualPtr();
657 }
658
660 template <class T>
662 {
663 this->hfov = _hfov;
664 }
665
667 template <class T>
669 {
670 // Invalid AR values fallback to auto aspect ratio to maintain
671 // ABI compatibility.
672 // See https://github.com/gazebosim/gz-rendering/issues/763
673 if (this->aspect <= 0.0)
674 {
675 return static_cast<double>(this->ImageWidth()) /
676 static_cast<double>(this->ImageHeight());
677 }
678 return this->aspect;
679 }
680
682 template <class T>
683 void BaseCamera<T>::SetAspectRatio(const double _aspect)
684 {
685 this->aspect = _aspect;
686 }
687
689 template <class T>
690 unsigned int BaseCamera<T>::AntiAliasing() const
691 {
692 return this->antiAliasing;
693 }
694
696 template <class T>
697 void BaseCamera<T>::SetAntiAliasing(const unsigned int _aa)
698 {
699 this->antiAliasing = _aa;
700 }
701
703 template <class T>
705 {
706 return this->farClip;
707 }
708
710 template <class T>
711 void BaseCamera<T>::SetFarClipPlane(const double _far)
712 {
713 if (_far <= 0 || !std::isfinite(_far))
714 {
715 gzerr << "Far clip distance must be a finite number greater than 0."
716 << std::endl;
717 return;
718 }
719 this->farClip = _far;
720 }
721
723 template <class T>
725 {
726 return this->nearClip;
727 }
728
730 template <class T>
731 void BaseCamera<T>::SetNearClipPlane(const double _near)
732 {
733 if (_near <= 0 || !std::isfinite(_near))
734 {
735 gzerr << "Near clip distance must be a finite number greater than 0."
736 << std::endl;
737 return;
738 }
739 this->nearClip = _near;
740 }
741
743 template <class T>
745 const math::Vector3d &_offset, const bool _worldFrame)
746 {
747 this->trackNode = _target;
748 this->trackWorldFrame = _worldFrame;
749 this->trackOffset = _offset;
750 }
751
753 template <class T>
755 {
756 return this->trackNode;
757 }
758
760 template <class T>
762 {
763 return this->trackOffset;
764 }
765
767 template <class T>
769 {
770 this->trackOffset = _offset;
771 }
772
774 template <class T>
775 void BaseCamera<T>::SetTrackPGain(const double _pGain)
776 {
777 this->trackPGain = math::clamp(_pGain, 0.0, 1.0);
778 }
779
781 template <class T>
783 {
784 return this->trackPGain;
785 }
786
788 template <class T>
790 const math::Vector3d &_offset, const bool _worldFrame)
791 {
792 this->followNode = _target;
793 this->followWorldFrame = _worldFrame;
794 this->followOffset = _offset;
795 }
796
798 template <class T>
800 {
801 return this->followNode;
802 }
803
805 template <class T>
807 {
808 return this->followOffset;
809 }
810
812 template <class T>
814 {
815 this->followOffset = _offset;
816 }
817
819 template <class T>
820 void BaseCamera<T>::SetFollowPGain(const double _pGain)
821 {
822 this->followPGain = math::clamp(_pGain, 0.0, 1.0);
823 }
824
826 template <class T>
828 {
829 return this->followPGain;
830 }
831
833 template <class T>
834 void BaseCamera<T>::SetMaterial(const MaterialPtr &/*_material*/)
835 {
836 gzerr << "SetMaterial not implemented for current render"
837 << " engine" << std::endl;
838 }
839
841 template <class T>
843 {
844 gzerr << "RenderTextureGLId is not supported by current render"
845 << " engine" << std::endl;
846 return 0u;
847 }
848
850 template <class T>
852 {
853 gzerr << "RenderTextureMetalId is not supported by current render"
854 << " engine" << std::endl;
855 }
856
858 template <class T>
860 {
861 gzerr << "PrepareForExternalSampling is not supported by current render"
862 << " engine" << std::endl;
863 }
864
866 template <class T>
868 {
869 this->RenderTarget()->AddRenderPass(_pass);
870 }
871
873 template <class T>
875 {
876 this->RenderTarget()->RemoveRenderPass(_pass);
877 }
878
880 template <class T>
882 {
883 RenderTargetPtr renderTarget = this->RenderTarget();
884 if (renderTarget)
885 {
886 renderTarget->RemoveAllRenderPasses();
887 }
888 }
889
891 template <class T>
893 {
894 return this->RenderTarget()->RenderPassCount();
895 }
896
898 template <class T>
900 {
901 return this->RenderTarget()->RenderPassByIndex(_index);
902 }
903
905 template <class T>
907 {
908 // no op
909 }
910 }
911 }
912}
913#endif