iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Shapes.H
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_GRAPHICS_SHAPES_H
37 #define INCLUDE_NRT_GRAPHICS_SHAPES_H
38 
39 #include <nrt/Graphics/Shape.H>
40 #include <nrt/Eigen/Eigen.H>
41 #include <nrt/Core/Geometry/Dims.H>
46 #include <nrt/Core/Typing/Enum.H>
50 
51 #include <nrt/External/cereal/types/vector.hpp>
52 #include <nrt/External/cereal/types/string.hpp>
53 #include <nrt/External/cereal/types/base_class.hpp>
54 
55 /*! \defgroup graphicshapes Graphic primitive shapes
56 
57  The nrt graphics primitives allow one to draw spheres, cubes, cylinders, extruded contours, etc into an OpenGL
58  display, possibly using different 3D effects such as texture mapping.
59 
60  \ingroup graphics */
61 
62 namespace nrt
63 {
64  namespace graphics
65  {
66  //! End capping policy for extruded shapes (e.g., cylinder)
67  /*! \class Capped
68 
69  Some 3D shapes that are extruted, e.g., Cylinder, Cone, etc, may or may not be capped at their end(s). If
70  uncapped, they will appear hollow, while they will appear solid if capped.
71 
72  - if nrt::graphics::Capped::Yes the shape will be capped
73  - if nrt::graphics::Capped::No the shape will not be capped
74 
75  \ingroup graphicshapes */
76  NRT_DEFINE_ENUM_CLASS(Capped, (Yes) (No));
77 
78  // ######################################################################
79  //! A 2D grid
80  /*! \ingroup graphicshapes */
81  class Grid : public Shape
82  {
83  public:
84  //! Constructor
85  /*! The grid spans between (-0.5, -0.5, 0) and (0.5, 0.5, 0) with nx and ny steps */
86  Grid(size_t const nx_ = 10, size_t const ny_ = 10,
87  Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
88  nrt::Duration const & lifetime_ = nrt::forev(),
89  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
90  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
91 
92  //! Virtual destructor for safe inheritance
93  virtual ~Grid();
94 
95  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
96  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
97 
98  protected:
99  size_t nx, ny; //! Number of steps in X and Y
100 
101  public:
102  //! Serialization
103  template <class Archive> void serialize(Archive & ar)
104  {
105  ar( cereal::base_class<Shape>(this) );
106  ar( nx, ny );
107  }
108  };
109 
110  // ######################################################################
111  //! A set of 3D axes, drawn using standard colors (red for X, green for Y, blue for Z)
112  /*! \ingroup graphicshapes */
113  class Axes : public Shape
114  {
115  public:
116  //! Constructor
117  /*! The three unit vectors starting from the origin (red for X, green for Y, blue for Z). \note The brush is
118  ignored, and only the alpha channel is used for the pen, as the colors are fixed by conventipon. */
119  Axes(Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
120  nrt::Duration const & lifetime_ = nrt::forev(),
121  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
122  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
123 
124  //! Virtual destructor for safe inheritance
125  virtual ~Axes();
126 
127  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
128  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
129 
130  public:
131  //! Serialization
132  template <class Archive> void serialize(Archive & ar)
133  {
134  ar( cereal::base_class<Shape>(this) );
135  }
136  };
137 
138  // ######################################################################
139  //! A line segment
140  /*! \ingroup graphicshapes */
141  class Line : public Shape
142  {
143  public:
144  //! Constructor for a unit line (-0.5, 0, 0) to (0.5, 0, 0)
145  Line(Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
146  nrt::Duration const & lifetime_ = nrt::forev(),
147  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
148  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
149 
150  //! Constructor for a line from p1 to p2
151  Line(Eigen::Vector3f const & p1, Eigen::Vector3f const & p2,
152  nrt::Duration const & lifetime_ = nrt::forev(),
153  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
154  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
155 
156  //! Virtual destructor for safe inheritance
157  virtual ~Line();
158 
159  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
160  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
161 
162  public:
163 
164  //! Serialization
165  template <class Archive> void serialize(Archive & ar)
166  {
167  ar( cereal::base_class<Shape>(this) );
168  }
169  };
170 
171  // ######################################################################
172  //! A flat rectangle
173  /*! \ingroup graphicshapes */
174  class Rectangle : public Shape
175  {
176  public:
177  //! Constructor for a unit rectangle in the X-Y plane, center (0,0,0), width 1, height 1
178  Rectangle(Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
179  nrt::Duration const & lifetime_ = nrt::forev(),
180  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
181  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
182 
183  //! Virtual destructor for safe inheritance
184  virtual ~Rectangle();
185 
186  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
187  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
188 
189  public:
190 
191  //! Serialization
192  template <class Archive> void serialize(Archive & ar)
193  {
194  ar( cereal::base_class<Shape>(this) );
195  }
196  };
197 
198  // ######################################################################
199  //! A circle
200  /*! \ingroup graphicshapes */
201  class Circle : public Shape
202  {
203  public:
204  //! Constructor for a unit circle in the X-Y plane, center (0,0,0) radius 1
205  Circle(Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
206  nrt::Duration const & lifetime_ = nrt::forev(),
207  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
208  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
209 
210  //! Virtual destructor for safe inheritance
211  virtual ~Circle();
212 
213  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
214  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
215 
216  public:
217 
218  //! Serialization
219  template <class Archive> void serialize(Archive & ar)
220  {
221  ar( cereal::base_class<Shape>(this) );
222  }
223  };
224 
225  // ######################################################################
226  //! A 3D box
227  /*! \ingroup graphicshapes */
228  class Box : public Shape
229  {
230  public:
231  //! Constructor for a unit cube centered at (0,0,0)
232  /*! The Brush should contain either a Material, or a texture with one element (which will be displayed on every
233  face), or a texture with 6 elements (one per face). */
234  Box(Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
235  nrt::Duration const & lifetime_ = nrt::forev(),
236  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
237  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
238 
239  //! Virtual destructor for safe inheritance
240  virtual ~Box();
241 
242  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
243  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
244 
245  public:
246 
247  //! Serialization
248  template <class Archive> void serialize(Archive & ar)
249  {
250  ar( cereal::base_class<Shape>(this) );
251  }
252  };
253 
254  // ######################################################################
255  //! A flat polygon
256  /*! \ingroup graphicshapes */
257  class Polygon : public Shape
258  {
259  public:
260  //! Constructor for an arbitrary 3D polygon
261  Polygon(std::vector<nrt::Point3D<float>> const & polygon_ = {},
262  Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
263  nrt::Duration const & lifetime_ = nrt::forev(),
264  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
265  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
266 
267  //! Virtual destructor for safe inheritance
268  virtual ~Polygon();
269 
270  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
271  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
272 
273  protected:
274  std::vector<nrt::Point3D<float>> polygon;
275 
276  public:
277 
278  //! Serialization
279  template <class Archive> void serialize(Archive & ar)
280  {
281  ar( cereal::base_class<Shape>(this) );
282  ar( polygon );
283  }
284  };
285 
286  // ######################################################################
287  //! An extruded contour
288  /*! \ingroup graphicshapes */
289  class ExtrudedContour : public Shape
290  {
291  public:
292  //! Constructor for an extruded contour in the X-Y plane with extrusion height 1 (from Z=0 to Z=1)
293  ExtrudedContour(nrt::Polygon<float> const & contour_ = {},
294  Capped const capped_ = Capped::Yes,
295  Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
296  nrt::Duration const & lifetime_ = nrt::forev(),
297  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
298  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
299 
300  //! Virtual destructor for safe inheritance
301  virtual ~ExtrudedContour();
302 
303  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
304  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
305 
306  protected:
307  nrt::Polygon<float> contour;
308  Capped capped;
309 
310  public:
311 
312  //! Serialization
313  template <class Archive> void serialize(Archive & ar)
314  {
315  ar( cereal::base_class<Shape>(this) );
316  ar( contour, capped );
317  }
318  };
319 
320  // ######################################################################
321  //! A sphere
322  /*! \ingroup graphicshapes */
323  class Sphere : public Shape
324  {
325  public:
326  //! Constructor for a unit sphere centered at (0,0,0) and radius 1
327  Sphere(Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
328  nrt::Duration const & lifetime_ = nrt::forev(),
329  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
330  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
331 
332  //! Virtual destructor for safe inheritance
333  virtual ~Sphere();
334 
335  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
336  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
337 
338  public:
339 
340  //! Serialization
341  template <class Archive> void serialize(Archive & ar)
342  {
343  ar( cereal::base_class<Shape>(this) );
344  }
345  };
346 
347  // ######################################################################
348  //! A cylinder
349  /*! \ingroup graphicshapes */
350  class Cylinder : public Shape
351  {
352  public:
353  //! Constructor for a cylinder, circle in X-Y centered at (0,0,0) radius 1, height 1 along Z (from Z=0 to Z=1)
354  Cylinder(Capped const capped_ = Capped::Yes,
355  Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
356  nrt::Duration const & lifetime_ = nrt::forev(),
357  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
358  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
359 
360  //! Virtual destructor for safe inheritance
361  virtual ~Cylinder();
362 
363  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
364  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
365 
366  protected:
367  Capped capped;
368 
369  public:
370 
371  //! Serialization
372  template <class Archive> void serialize(Archive & ar)
373  {
374  ar( cereal::base_class<Shape>(this) );
375  ar( capped );
376  }
377  };
378 
379  // ######################################################################
380  //! A cone
381  /*! \ingroup graphicshapes */
382  class Cone : public Shape
383  {
384  public:
385  //! Constructor for a cone, circle in X-Y centered at (0,0,0) radius 1, height 1 along Z (from Z=0 to Z=1)
386  Cone(Capped const capped_ = Capped::Yes,
387  Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
388  nrt::Duration const & lifetime_ = nrt::forev(),
389  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
390  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
391 
392  //! Virtual destructor for safe inheritance
393  virtual ~Cone();
394 
395  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
396  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
397 
398  protected:
399  Capped capped;
400 
401  public:
402 
403  //! Serialization
404  template <class Archive> void serialize(Archive & ar)
405  {
406  ar( cereal::base_class<Shape>(this) );
407  ar( capped );
408  }
409  };
410 
411  // ######################################################################
412  //! A point cloud
413  /*! \ingroup graphicshapes */
414  class PointCloud : public Shape
415  {
416  public:
417  //! The type of primitive to draw for each point.
419  {
420  Point, //!< A simple round point. Points will always be drawn the same size on the screen, regardless of the camera view.
421  Sprite, //!< A simple square point. Sprites will always be drawn the same size on the screen, regardless of the camera view.
422  Billboard, //!< A square point which always faces the camera. Billboards will get smaller as the camera moves further away.
423  Cube //!< A 3D cube aligned to the global coordinate frame.
424  };
425 
426  //! Constructor
427  /*! @param pointcloud_ The PointCloud to display
428 
429  @param pointsize_ The size of the points. If displayType is Point
430  or Sprite, then pointsize_ will be in pixels. Otherwise, pointsize_
431  will be interpreted as meters.
432 
433  @param frame_ The frame in which to render the points.
434 
435  @param lifetime_ The lifetime of the graphics object.
436 
437  @param pen_ The pen to use when rendering the points.
438 
439  @param brush_ The brush to use when rendering the points.
440 
441  @param useVBO If set to true, then the points will be rendered
442  using the more efficient Vertex Buffer Objects. Otherwise, the
443  points will be rendered in immediate mode.
444 
445  @param displayType The type of primitive to draw for each point.
446  See nrt::graphics::PointCloud::DisplayType for details. */
447  PointCloud(nrt::PointCloud2 const & pointcloud_ = nrt::PointCloud2(),
448  float const pointsize_ = 1.0F,
449  Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
450  nrt::Duration const & lifetime_ = nrt::forev(),
451  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
452  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush(),
453  bool const useVBO = true, DisplayType displayType = Point);
454 
455  //! Virtual destructor for safe inheritance
456  virtual ~PointCloud();
457 
458  //! Render this shape into a ShapeRenderer (e.g., OpenGL window).
459  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
460 
461  //! Set the point size.
462  void setPointSize(float pointsize);
463 
464  //! Set whether or not to use Vertex Buffer Objects.
465  /*! Vertex buffer objects are more efficient, but may not be available on older versions of OpenGL. */
466  void setUseVBO(bool useVBO);
467 
468  //! Set the display type to use.
469  void setDisplayType(DisplayType displayType);
470 
471  protected:
472  nrt::PointCloud2 pointcloud;
473  float pointsize;
474  bool useVBO;
475  DisplayType displayType;
476 
477  public:
478  //! Serialization
479  template <class Archive> void serialize(Archive & ar)
480  {
481  ar( cereal::base_class<Shape>(this) );
482  ar( pointcloud, pointsize, useVBO, displayType );
483  }
484  };
485 
486  // ######################################################################
487  //! Normals contained in a Point Cloud
488  /*! \param scaleByCurvature If true, then the length of the normals will be equal to normallength * normal.curvature().
489  \param normallength The maximum length of the normals in meters.
490  \ingroup graphicshapes */
491  class PointCloudNormals : public Shape
492  {
493  public:
494  //! Constructor
495  PointCloudNormals(nrt::PointCloud2 const & pointcloud_ = nrt::PointCloud2(),
496  bool scaleByCurvature = false,
497  float const normallength = 0.01F, // in meters
498  Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
499  nrt::Duration const & lifetime_ = nrt::forev(),
500  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
501  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
502 
503  //! Virtual destructor for safe inheritance
504  virtual ~PointCloudNormals();
505 
506  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
507  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
508 
509  protected:
510  nrt::PointCloud2 pointcloud;
511  bool scaleByCurvature;
512  float normallength;
513 
514  public:
515 
516  template <class Archive> void serialize(Archive & ar)
517  {
518  ar( cereal::base_class<Shape>(this) );
519  ar( pointcloud, scaleByCurvature, normallength );
520  }
521  };
522 
523  // ######################################################################
524  //! An articulated skeleton structural definition
525  /*! To avoid sending over and over the structural details of a skeleton, the SkeletonDefinition shape should be used
526  jointly with the SkeletonPosture shape. You should only render a SkeletonDefinition shape once (i.e., not in
527  your main display loop, but before it), giving it a unique name, and the ShapeRenderer will create an optimized
528  rendering for it and will remember it. In your main display loop, you would then render for every frame a
529  SkeletonPosture (using the same unique name), which just contains the joint angles for your previously defined
530  SkeletonDefinition.
531 
532  \ingroup graphicshapes */
533  class SkeletonDefinition : public Shape
534  {
535  public:
536  //! Constructor
537  SkeletonDefinition(std::string const & name_ = "Unknown",
539 
540  //! Virtual destructor for safe inheritance
541  virtual ~SkeletonDefinition();
542 
543  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
544  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
545 
546  protected:
547  std::string name;
549 
550  public:
551 
552  //! Serialization
553  template <class Archive> void serialize(Archive & ar)
554  {
555  ar( cereal::base_class<Shape>(this) );
556  ar( name, skeleton );
557  }
558  };
559 
560  // ######################################################################
561  //! An articulated skeleton posture data
562  /*! To avoid sending over and over the structural details of a skeleton, the SkeletonDefinition shape should be used
563  jointly with the SkeletonPosture shape. You should only render a SkeletonDefinition shape once (i.e., not in
564  your main display loop, but before it), giving it a unique name, and the ShapeRenderer will create an optimized
565  rendering for it and will remember it. In your main display loop, you would then render for every frame a
566  SkeletonPosture (using the same unique name), which just contains the joint angles for your previously defined
567  SkeletonDefinition.
568 
569  \ingroup graphicshapes */
570  class SkeletonPosture : public Shape
571  {
572  public:
573  //! Constructor
574  SkeletonPosture(std::string const & name_ = "Unknown",
576  bool showframes_ = false, Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
577  nrt::Duration const & lifetime_ = nrt::forev());
578 
579  //! Virtual destructor for safe inheritance
580  virtual ~SkeletonPosture();
581 
582  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
583  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
584 
585  protected:
586  std::string name; //!< unique skeleton name
588  bool showframes; //!< Also draw the frame axes for each joint if true
589 
590  public:
591 
592  //! Serialization
593  template <class Archive> void serialize(Archive & ar)
594  {
595  ar( cereal::base_class<Shape>(this) );
596  ar( name, posture, showframes );
597  }
598  };
599 
600  // ######################################################################
601  //! A set of textures to be used later by Brush objects
602  /*! To avoid sending over and over texture maps, we handle textures as follows: First register new textures by name
603  by sending a single Texture message. Then, create Brush objects that use that name and the texture index under
604  that name to use a registered texture. You can have multiple textures associated with a name; for example, if a
605  robot model needs 100 textures, you can send them all in one message here, then it is assumed that you will
606  remember which texture number you want to slap onto each different part of your robot (e.g., number 0 for torso,
607  1 for left arm, etc).
608 
609  \ingroup graphicshapes */
610  class Textures : public Shape
611  {
612  public:
613  //! Constructor from a bunch of RGB textures
614  Textures(std::string const & name_ = "Unknown",
615  std::vector<nrt::Image<nrt::PixRGB<nrt::byte> > > const & textures_ = {});
616 
617  //! Virtual destructor for safe inheritance
618  virtual ~Textures();
619 
620  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
621  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
622 
623  protected:
624  std::string name; //!< unique name for a collection of textures
625  std::vector<nrt::Image<nrt::PixRGB<nrt::byte> > > textures; //!< Our textures
626 
627  public:
628 
629  //! Serialization
630  template <class Archive> void serialize(Archive & ar)
631  {
632  ar( cereal::base_class<Shape>(this) );
633  ar( name, textures );
634  }
635  };
636 
637  // ######################################################################
638  //! Draws text in 3D
639  /*! TODO detailed description
640  \ingroup graphicshapes */
641  class Text3D : public Shape
642  {
643  public:
644  //! Constructor
645  Text3D(std::string const & text = "",
646  Eigen::Affine3f const & frame_ = Eigen::Affine3f::Identity(),
647  nrt::Duration const & lifetime_ = nrt::forev(),
648  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
649  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
650 
651  //! Virtual destructor for safe inheritance
652  virtual ~Text3D();
653 
654  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
655  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
656 
657  //! Serialization
658  template <class Archive> void serialize(Archive & ar)
659  {
660  ar( cereal::base_class<Shape>(this) );
661  ar( itsText );
662  }
663 
664  private:
665  std::string itsText;
666  };
667 
668  // ######################################################################
669  //! Draws text in 2D (screen coordinates)
670  /*! TODO detailed description
671  \ingroup graphicshapes */
672  class Text2D : public Shape
673  {
674  public:
675  //! Constructor
676  Text2D(std::string const & text = "",
677  nrt::Point2D<nrt::int32> const & location = nrt::Point2D<nrt::int32>(0, 0),
678  nrt::Duration const & lifetime_ = nrt::forev(),
679  nrt::graphics::Pen const & pen_ = nrt::graphics::Pen(),
680  nrt::graphics::Brush const & brush_ = nrt::graphics::Brush());
681 
682  //! Virtual destructor for safe inheritance
683  virtual ~Text2D();
684 
685  //! Render this shape into a ShapeRenderer (e.g., OpenGL window)
686  virtual void render(nrt::graphics::ShapeRenderer & sr) const;
687 
688  //! Serialization
689  template <class Archive> void serialize(Archive & ar)
690  {
691  ar( cereal::base_class<Shape>(this) );
692  ar( itsText );
693  }
694 
695  private:
696  std::string itsText;
697  nrt::Point2D<nrt::int32> itsLocation;
698  };
699 
700  } // namespace graphics
701 } // namespace nrt
702 
703 #endif // INCLUDE_NRT_GRAPHICS_SHAPES_H