Radium Engine  1.5.0
GeometryComponent.cpp
1 #include <Engine/Scene/GeometryComponent.hpp>
2 
3 #include <iostream>
4 
5 #include <Core/Asset/GeometryData.hpp>
6 #include <Core/Containers/MakeShared.hpp>
7 #include <Core/Utils/Color.hpp>
8 #include <Core/Utils/Log.hpp>
9 
10 #include <Engine/Data/BlinnPhongMaterial.hpp>
11 #include <Engine/Data/Material.hpp>
12 #include <Engine/Data/MaterialConverters.hpp>
13 #include <Engine/Data/Mesh.hpp>
14 #include <Engine/Data/VolumeObject.hpp>
15 #include <Engine/Data/VolumetricMaterial.hpp>
16 #include <Engine/Rendering/RenderObject.hpp>
17 #include <Engine/Rendering/RenderObjectManager.hpp>
18 #include <Engine/Rendering/RenderObjectTypes.hpp>
19 #include <Engine/Rendering/RenderTechnique.hpp>
20 #include <Engine/Scene/ComponentMessenger.hpp>
21 
22 #define CHECK_MESH_NOT_NULL \
23  CORE_ASSERT( m_displayMesh != nullptr, "DisplayMesh should exist while component is alive" );
24 
26 using namespace Ra::Core::Utils;
27 
28 namespace Ra {
29 namespace Engine {
30 namespace Scene {
31 
32 void GeometryComponent::setupIO( const std::string& id ) {
33  const auto& cm = ComponentMessenger::getInstance();
34  auto roOut = std::bind( &GeometryComponent::roIndexRead, this );
35  cm->registerOutput<Index>( getEntity(), this, id, roOut );
36 }
37 
38 const Index* GeometryComponent::roIndexRead() const {
39  return &m_roIndex;
40 }
41 
42 /*-----------------------------------------------------------------------------------------------*/
43 /*--------------------------------- PointCloud Component----------------------------------------*/
44 /*-----------------------------------------------------------------------------------------------*/
45 
46 PointCloudComponent::PointCloudComponent( const std::string& name,
47  Entity* entity,
48  const Ra::Core::Asset::GeometryData* data ) :
49  GeometryComponent( name, entity ), m_displayMesh( nullptr ) {
50  generatePointCloud( data );
51 }
52 
53 PointCloudComponent::PointCloudComponent( const std::string& name,
54  Entity* entity,
55  Core::Geometry::PointCloud&& mesh,
57  GeometryComponent( name, entity ),
58  m_displayMesh( new Data::PointCloud( name, std::move( mesh ) ) ) {
59  finalizeROFromGeometry( mat, Core::Transform::Identity() );
60 }
61 
64 
66 
68 
69 void PointCloudComponent::generatePointCloud( const Ra::Core::Asset::GeometryData* data ) {
70  m_contentName = data->getName();
71  m_displayMesh = Ra::Core::make_shared<Data::PointCloud>( m_contentName );
72  m_displayMesh->setRenderMode( Data::AttribArrayDisplayable::RM_POINTS );
73 
74  Ra::Core::Geometry::PointCloud mesh;
75 
76  // add custom attribs
77  mesh.vertexAttribs().copyAllAttributes( data->getGeometry().vertexAttribs() );
78 
79  m_displayMesh->loadGeometry( std::move( mesh ) );
80 
81  finalizeROFromGeometry( data->hasMaterial() ? &( data->getMaterial() ) : nullptr,
82  data->getFrame() );
83 }
84 
85 void PointCloudComponent::finalizeROFromGeometry( const Core::Asset::MaterialData* data,
86  Core::Transform transform ) {
87  // The technique for rendering this component
88  std::shared_ptr<Data::Material> roMaterial;
89  // First extract the material from asset or create a default one
90  if ( data != nullptr ) {
92  auto mat = converter.second( data );
93  roMaterial.reset( mat );
94  }
95  else {
96  auto mat = new Data::BlinnPhongMaterial( m_contentName + "_DefaultBPMaterial" );
97  mat->m_renderAsSplat = m_displayMesh->getNumFaces() == 0;
98  mat->m_perVertexColor = m_displayMesh->getCoreGeometry().hasAttrib(
99  Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::VERTEX_COLOR ) );
100  roMaterial.reset( mat );
101  }
102  // initialize with a default rendertechique that draws nothing
103  std::string roName( m_name + "_" + m_contentName + "_RO" );
105  this,
106  Rendering::RenderObjectType::Geometry,
107  m_displayMesh,
108  Rendering::RenderTechnique {} );
109  ro->setTransparent( roMaterial->isTransparent() );
110  ro->setMaterial( roMaterial );
111  setupIO( m_contentName );
112  ro->setLocalTransform( transform );
113  m_roIndex = addRenderObject( ro );
114 }
115 
116 const Ra::Core::Geometry::PointCloud& PointCloudComponent::getCoreGeometry() const {
117  CHECK_MESH_NOT_NULL;
118  return m_displayMesh->getCoreGeometry();
119 }
120 
121 Data::PointCloud* PointCloudComponent::getGeometry() {
122  CHECK_MESH_NOT_NULL;
123  return m_displayMesh.get();
124 }
125 
126 void PointCloudComponent::setupIO( const std::string& id ) {
127  CHECK_MESH_NOT_NULL;
128  auto cbOut = std::bind( &PointCloudComponent::getMeshOutput, this );
129  auto cbRw = std::bind( &PointCloudComponent::getPointCloudRw, this );
130 
131  const auto& cm = ComponentMessenger::getInstance();
132 
133  cm->registerOutput<Ra::Core::Geometry::PointCloud>( getEntity(), this, id, cbOut );
134  cm->registerReadWrite<Ra::Core::Geometry::PointCloud>( getEntity(), this, id, cbRw );
135  base::setupIO( id );
136 }
137 
138 const Ra::Core::Geometry::PointCloud* PointCloudComponent::getMeshOutput() const {
139  CHECK_MESH_NOT_NULL;
140  return &m_displayMesh->getCoreGeometry();
141 }
142 
143 Ra::Core::Geometry::PointCloud* PointCloudComponent::getPointCloudRw() {
144  CHECK_MESH_NOT_NULL;
145  return &( m_displayMesh->getCoreGeometry() );
146 }
147 
148 /*-----------------------------------------------------------------------------------------------*/
149 /*--------------------------------- Volume Component ------------------------------------------*/
150 /*-----------------------------------------------------------------------------------------------*/
151 VolumeComponent::VolumeComponent( const std::string& name,
152  Entity* entity,
153  const Ra::Core::Asset::VolumeData* data ) :
154  Component( name, entity ), m_displayVolume { nullptr } {
155  generateVolumeRender( data );
156 }
157 
158 VolumeComponent::~VolumeComponent() = default;
159 
161 
162 void VolumeComponent::generateVolumeRender( const Ra::Core::Asset::VolumeData* data ) {
163  m_contentName = data->getName();
164  m_displayVolume = Ra::Core::make_shared<Data::VolumeObject>( m_contentName );
165  m_displayVolume->loadGeometry( data->volume, data->boundingBox );
166 
167  auto roMaterial =
168  Ra::Core::make_shared<Data::VolumetricMaterial>( data->getName() + "_VolMat" );
169  roMaterial->setTexture( const_cast<Data::Texture*>( &( m_displayVolume->getDataTexture() ) ) );
170  roMaterial->m_sigma_a = data->sigma_a;
171  roMaterial->m_sigma_s = data->sigma_s;
172  roMaterial->m_modelToMedium = data->densityToModel.inverse();
173 
174  std::string roName( m_name + "_" + m_contentName + "_RO" );
176  this,
177  Rendering::RenderObjectType::Geometry,
178  m_displayVolume,
180  ro->setTransparent( roMaterial->isTransparent() );
181  ro->setMaterial( roMaterial );
182  ro->setLocalTransform( data->modelToWorld );
183 
184  setupIO( m_contentName );
185  m_volumeIndex = addRenderObject( ro );
186 }
187 
188 #define CHECK_VOL_NOT_NULL \
189  CORE_ASSERT( m_displayVolume != nullptr, \
190  "DisplayVolume should exist while component is alive" );
191 
192 Data::VolumeObject* VolumeComponent::getDisplayVolume() {
193  CHECK_VOL_NOT_NULL;
194  return m_displayVolume.get();
195 }
196 
198  CHECK_VOL_NOT_NULL;
199  return m_volumeIndex;
200 }
201 
202 void VolumeComponent::setContentName( const std::string& name ) {
203  this->m_contentName = name;
204 }
205 
206 void VolumeComponent::setupIO( const std::string& id ) {
207  CHECK_VOL_NOT_NULL;
208 
209  const auto& cm = ComponentMessenger::getInstance();
210  auto cbOut = std::bind( &VolumeComponent::getVolumeOutput, this );
211  auto cbRw = std::bind( &VolumeComponent::getVolumeRw, this );
212  auto roOut = std::bind( &VolumeComponent::roIndexRead, this );
213 
214  cm->registerOutput<Ra::Core::Geometry::AbstractVolume>( getEntity(), this, id, cbOut );
215  cm->registerReadWrite<Ra::Core::Geometry::AbstractVolume>( getEntity(), this, id, cbRw );
216  cm->registerOutput<Ra::Core::Utils::Index>( getEntity(), this, id, roOut );
217 }
218 
219 const Index* VolumeComponent::roIndexRead() const {
220  CHECK_VOL_NOT_NULL;
221  return &m_volumeIndex;
222 }
223 
224 const Ra::Core::Geometry::AbstractVolume* VolumeComponent::getVolumeOutput() const {
225  CHECK_VOL_NOT_NULL;
226  return &m_displayVolume->getVolume();
227 }
228 
229 Ra::Core::Geometry::AbstractVolume* VolumeComponent::getVolumeRw() {
230  CHECK_VOL_NOT_NULL;
231  return &m_displayVolume->getVolume();
232 }
233 
234 } // namespace Scene
235 } // namespace Engine
236 } // 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.
Geometry::MultiIndexedGeometry & getGeometry()
Read/write access to the multiIndexedGeometry;.
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.
Utils::AttribManager & vertexAttribs()
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())
virtual Entity * getEntity() const
Return the entity the component belongs to.
Definition: Component.hpp:53
Core::Utils::Index addRenderObject(Rendering::RenderObject *renderObject)
Add a new render object to the component. This adds the RO to the manager for drawing.
Definition: Component.cpp:41
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 ...
const Ra::Core::Geometry::PointCloud & getCoreGeometry() const
Returns the current display geometry.
Ra::Core::Utils::Index getRenderObjectIndex() const
Returns the index of the associated RO (the display volume)
void initialize() override
Pure virtual method to be overridden by any component. When this method is called you are guaranteed ...
std::pair< bool, ConverterFunction > getMaterialConverter(const std::string &name)
Definition: Cage.cpp:3
Aabb boundingBox
The bounding box of the volume.
Definition: VolumeData.hpp:28
Geometry::AbstractVolume * volume
The underlaying density matrix.
Definition: VolumeData.hpp:21
Transform modelToWorld
Transformation matrix of the object.
Definition: VolumeData.hpp:33
Utils::Color sigma_a
Absortion coefficient of the volume (default is Air)
Definition: VolumeData.hpp:23
Utils::Color sigma_s
Scattering coefficient of the volume (default is Air)
Definition: VolumeData.hpp:25