Radium Engine  1.5.0
GeometryComponent.hpp
1 #pragma once
2 
3 #include <Core/Asset/GeometryData.hpp>
4 #include <Core/Asset/VolumeData.hpp>
5 #include <Core/Containers/MakeShared.hpp>
6 #include <Core/Geometry/TriangleMesh.hpp>
7 #include <Core/Geometry/Volume.hpp>
8 #include <Engine/Data/BlinnPhongMaterial.hpp>
9 #include <Engine/Data/MaterialConverters.hpp>
10 #include <Engine/Data/Mesh.hpp>
11 #include <Engine/Rendering/RenderObject.hpp>
12 #include <Engine/Scene/Component.hpp>
13 #include <Engine/Scene/ComponentMessenger.hpp>
14 #include <Engine/Scene/Entity.hpp>
15 
16 namespace Ra {
17 namespace Engine {
18 namespace Data {
19 class VolumeObject;
20 } // namespace Data
21 
22 namespace Scene {
23 
25 class RA_ENGINE_API GeometryComponent : public Component
26 {
27  public:
28  GeometryComponent( const std::string& name, Entity* entity ) :
29  Component( name, entity ), m_contentName( name ) {}
30  ~GeometryComponent() override {}
31 
32  void initialize() override {}
33 
34  // public:
35  // Component communication management
36  virtual void setupIO( const std::string& id );
37  void setContentName( const std::string& name ) { m_contentName = name; }
38  // void setDeformable( bool b );
39 
41  // Ra::Core::Utils::Index getRenderObjectIndex() const;
42  protected:
43  private:
44  const Ra::Core::Utils::Index* roIndexRead() const;
45 
46  protected:
47  // the index of the renderObject
48  Ra::Core::Utils::Index m_roIndex {};
49  std::string m_contentName {};
50 };
51 
61 template <typename CoreMeshType>
63 {
64  using base = GeometryComponent;
65 
66  public:
67  using RenderMeshType = typename Data::RenderMeshType::getType<CoreMeshType>::Type;
68 
69  inline SurfaceMeshComponent( const std::string& name,
70  Entity* entity,
71  const Ra::Core::Asset::GeometryData* data );
72  inline SurfaceMeshComponent( const std::string& name,
73  Entity* entity,
74  std::shared_ptr<RenderMeshType> data );
75 
80  inline SurfaceMeshComponent( const std::string& name,
81  Entity* entity,
82  CoreMeshType&& mesh,
83  Core::Asset::MaterialData* mat = nullptr );
84 
85  ~SurfaceMeshComponent() override = default;
86 
88  inline const CoreMeshType& getCoreGeometry() const;
89  inline RenderMeshType* getDisplayable();
90 
91  // Component communication management
92  inline void setupIO( const std::string& id ) override;
93  inline void setDeformable( bool b );
94 
95  private:
96  inline void generateMesh( const Ra::Core::Asset::GeometryData* data );
97 
98  inline void finalizeROFromGeometry( const Core::Asset::MaterialData* data,
99  Core::Transform transform );
100 
101  // Give access to the mesh and (if deformable) to update it
102  inline const CoreMeshType* getMeshOutput() const;
103  inline CoreMeshType* getMeshRw();
104 
105  private:
106  // directly hold a reference to the displayMesh to simplify accesses in handlers
107  std::shared_ptr<RenderMeshType> m_displayMesh { nullptr };
108 };
109 
114 
117 class RA_ENGINE_API PointCloudComponent : public GeometryComponent
118 {
119  using base = GeometryComponent;
120 
121  public:
122  PointCloudComponent( const std::string& name,
123  Entity* entity,
124  const Ra::Core::Asset::GeometryData* data );
125 
130  PointCloudComponent( const std::string& name,
131  Entity* entity,
132  Core::Geometry::PointCloud&& mesh,
133  Core::Asset::MaterialData* mat = nullptr );
134 
136 
137  void initialize() override;
138 
140  const Ra::Core::Geometry::PointCloud& getCoreGeometry() const;
141  Data::PointCloud* getGeometry();
142 
144  inline void setSplatSize( float s ) { m_splatSize = s; }
145 
147  inline float getSplatSize() const { return m_splatSize; }
148 
149  public:
150  // Component communication management
151  void setupIO( const std::string& id ) override;
152  void setDeformable( bool b );
153 
154  private:
155  void generatePointCloud( const Ra::Core::Asset::GeometryData* data );
156 
157  void finalizeROFromGeometry( const Core::Asset::MaterialData* data, Core::Transform transform );
158 
159  // Give access to the mesh and (if deformable) to update it
160  const Ra::Core::Geometry::PointCloud* getMeshOutput() const;
161  Ra::Core::Geometry::PointCloud* getPointCloudRw();
162 
163  private:
164  // directly hold a reference to the displayMesh to simplify accesses in handlers
165  std::shared_ptr<Data::PointCloud> m_displayMesh { nullptr };
166  // The diameter of the splat when rendered
167  float m_splatSize { 0.0025f };
168 };
169 
170 /*-----------------------------------------------------------------------------------------------*/
171 
178 class RA_ENGINE_API VolumeComponent : public Component
179 {
180  public:
181  VolumeComponent( const std::string& name,
182  Entity* entity,
183  const Ra::Core::Asset::VolumeData* data );
184  ~VolumeComponent() override;
185 
186  void initialize() override;
187 
188  public:
189  // Component communication management
190  void setupIO( const std::string& id );
191  void setContentName( const std::string& name );
192 
194  Ra::Core::Utils::Index getRenderObjectIndex() const;
195  Data::VolumeObject* getDisplayVolume();
196 
197  private:
198  void generateVolumeRender( const Ra::Core::Asset::VolumeData* data );
199 
200  const Ra::Core::Geometry::AbstractVolume* getVolumeOutput() const;
201  Ra::Core::Geometry::AbstractVolume* getVolumeRw();
202 
203  const Ra::Core::Utils::Index* roIndexRead() const;
204 
205  private:
206  Ra::Core::Utils::Index m_volumeIndex {};
207  std::string m_contentName {};
208  std::shared_ptr<Data::VolumeObject> m_displayVolume { nullptr };
209 };
210 
211 template <typename CoreMeshType>
213  const std::string& name,
214  Entity* entity,
215  const Ra::Core::Asset::GeometryData* data ) :
216  GeometryComponent( name, entity ), m_displayMesh( nullptr ) {
217  generateMesh( data );
218 }
219 
220 template <typename CoreMeshType>
221 SurfaceMeshComponent<CoreMeshType>::SurfaceMeshComponent( const std::string& name,
222  Entity* entity,
223  std::shared_ptr<RenderMeshType> data ) :
224  GeometryComponent( name, entity ), m_displayMesh( data ) {
225  finalizeROFromGeometry( nullptr, Core::Transform::Identity() );
226 }
227 
228 template <typename CoreMeshType>
230  Entity* entity,
231  CoreMeshType&& mesh,
233  GeometryComponent( name, entity ),
234  m_displayMesh( new RenderMeshType( name, std::move( mesh ) ) ) {
235  setContentName( name );
236  finalizeROFromGeometry( mat, Core::Transform::Identity() );
237 }
238 
239 template <typename CoreMeshType>
241  m_contentName = data->getName();
242  m_displayMesh = Ra::Core::make_shared<RenderMeshType>( m_contentName );
243  CoreMeshType mesh = Data::createCoreMeshFromGeometryData<CoreMeshType>( data );
244 
245  m_displayMesh->loadGeometry( std::move( mesh ) );
246 
247  finalizeROFromGeometry( data->hasMaterial() ? &( data->getMaterial() ) : nullptr,
248  data->getFrame() );
249 }
250 
251 template <typename CoreMeshType>
252 void SurfaceMeshComponent<CoreMeshType>::finalizeROFromGeometry(
253  const Core::Asset::MaterialData* data,
254  Core::Transform transform ) {
255  // The technique for rendering this component
256  std::shared_ptr<Data::Material> roMaterial;
257  // First extract the material from asset or create a default one
258  if ( data != nullptr ) {
260  auto mat = converter.second( data );
261  roMaterial.reset( mat );
262  }
263  else {
264  auto mat = new Data::BlinnPhongMaterial( m_contentName + "_DefaultBPMaterial" );
265  mat->m_renderAsSplat = m_displayMesh->getNumFaces() == 0;
266  mat->m_perVertexColor = m_displayMesh->getCoreGeometry().hasAttrib(
267  Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::VERTEX_COLOR ) );
268  roMaterial.reset( mat );
269  }
270  // initialize with a default rendertechique that draws nothing
271  std::string roName( m_name + "_" + m_contentName + "_RO" );
273  this,
274  Rendering::RenderObjectType::Geometry,
275  m_displayMesh,
276  Rendering::RenderTechnique {} );
277  ro->setTransparent( roMaterial->isTransparent() );
278  ro->setMaterial( roMaterial );
279  setupIO( m_contentName );
280  ro->setLocalTransform( transform );
281  m_roIndex = addRenderObject( ro );
282 }
283 
284 #ifndef CHECK_MESH_NOT_NULL
285 # define CHECK_MESH_NOT_NULL \
286  CORE_ASSERT( m_displayMesh != nullptr, \
287  "DisplayMesh should exist while component is alive" );
288 # define CHECK_MESH_NOT_NULL_UNDEF
289 #endif
290 
291 template <typename CoreMeshType>
293  CHECK_MESH_NOT_NULL;
294  return m_displayMesh->getCoreGeometry();
295 }
296 
297 template <typename CoreMeshType>
298 typename SurfaceMeshComponent<CoreMeshType>::RenderMeshType*
300  CHECK_MESH_NOT_NULL;
301  return m_displayMesh.get();
302 }
303 
304 template <typename CoreMeshType>
305 void SurfaceMeshComponent<CoreMeshType>::setupIO( const std::string& id ) {
306  CHECK_MESH_NOT_NULL;
307 
308  const auto& cm = ComponentMessenger::getInstance();
309  auto cbOut = std::bind( &SurfaceMeshComponent<CoreMeshType>::getMeshOutput, this );
310  auto cbRw = std::bind( &SurfaceMeshComponent<CoreMeshType>::getMeshRw, this );
311 
312  cm->registerOutput<CoreMeshType>( getEntity(), this, id, cbOut );
313  cm->registerReadWrite<CoreMeshType>( getEntity(), this, id, cbRw );
314 
315  base::setupIO( id );
316 }
317 
318 template <typename CoreMeshType>
319 const CoreMeshType* SurfaceMeshComponent<CoreMeshType>::getMeshOutput() const {
320  CHECK_MESH_NOT_NULL;
321  return &m_displayMesh->getCoreGeometry();
322 }
323 
324 template <typename CoreMeshType>
325 CoreMeshType* SurfaceMeshComponent<CoreMeshType>::getMeshRw() {
326  CHECK_MESH_NOT_NULL;
327  return &( m_displayMesh->getCoreGeometry() );
328 }
329 
330 #ifdef CHECK_MESH_NOT_NULL_UNDEF
331 # undef CHECK_MESH_NOT_NULL
332 #endif
333 
334 } // namespace Scene
335 } // namespace Engine
336 } // namespace Ra
virtual const std::string & getName() const
Acces to the name of the asset.
Definition: AssetData.hpp:29
const MaterialData & getMaterial() const
Return the MaterialData associated to the objet.
Transform getFrame() const
Return the Transform of the object.
bool hasMaterial() const
Return true if the object has MaterialData.
represent material data loaded by a file loader. Material data must be identified by a unique name....
std::string getType() const
TYPE.
A PointCloud without indices.
Definition: Mesh.hpp:311
static RenderObject * createRenderObject(const std::string &name, Scene::Component *comp, const RenderObjectType &type, std::shared_ptr< Data::Displayable > mesh, const RenderTechnique &techniqueConfig=RenderTechnique::createDefaultRenderTechnique())
A component is an element that can be updated by a system. It is also linked to some other components...
Definition: Component.hpp:31
An entity is an scene element. It ties together components with a transform.
Definition: Entity.hpp:23
Abstract interface of a geometric compoennet in the Engine.
void initialize() override
Pure virtual method to be overridden by any component. When this method is called you are guaranteed ...
void setSplatSize(float s)
set the splat size for rendering
float getSplatSize() const
get the splat size for rendering
Main class to convert Ra::Core::Asset::GeometryData to Ra::Engine::Mesh.
const CoreMeshType & getCoreGeometry() const
Returns the current display geometry.
Main class to convert Ra::Core::Asset::VolumeData to Ra::Engine::VolumeObject.
std::pair< bool, ConverterFunction > getMaterialConverter(const std::string &name)
Definition: Cage.cpp:3