voxelTerrain
 All Classes Functions Variables Typedefs Enumerations Pages
OgreTile.hpp
1 #ifndef OGRETILE_HPP
2 #define OGRETILE_HPP
3 
4 #include "blub/async/dispatcher.hpp"
5 #include "blub/async/predecl.hpp"
6 #include "blub/core/sharedPointer.hpp"
7 #include "blub/log/global.hpp"
8 #include "blub/math/axisAlignedBox.hpp"
9 #include "blub/math/vector3.hpp"
10 #include "blub/math/vector3int.hpp"
11 #include "blub/procedural/voxel/tile/renderer.hpp"
12 #include "blub/procedural/voxel/tile/surface.hpp"
13 #include "blub/procedural/voxel/data.hpp"
14 
15 #include <OGRE/OgreEntity.h>
16 #include <OGRE/OgreHardwareBuffer.h>
17 #include <OGRE/OgreHardwareBufferManager.h>
18 #include <OGRE/OgreHardwareIndexBuffer.h>
19 #include <OGRE/OgreMesh.h>
20 #include <OGRE/OgreMeshManager.h>
21 #include <OGRE/OgreSceneManager.h>
22 #include <OGRE/OgreSubEntity.h>
23 #include <OGRE/OgreSubMesh.h>
24 
25 
26 blub::uint32 g_meshId = 0;
27 
28 
36 template <typename configType = blub::procedural::voxel::config>
38 {
39 public:
40  typedef configType t_config;
44  typedef typename t_config::t_renderer::t_tile* t_thiz;
45  typedef typename t_config::t_surface::t_tile t_voxelSurfaceTile;
46  typedef typename t_base::t_tileData::t_vertices t_vertices;
47  typedef typename t_config::t_vertex t_vertex;
48 
58  static pointer create(Ogre::SceneManager *sc,
59  Ogre::String materialName,
60  blub::async::dispatcher *graphicDispatcher); // needed because only Ogre3d thread may call ogre3d methods
65  virtual ~OgreTile();
66 
67  void setTileData(typename t_base::t_tileDataPtr convertToRenderAble, const blub::axisAlignedBox &aabb);
68 
69  void setVisible(const bool& vis) override;
70  void setVisibleLod(const blub::uint16& indLod, const bool& vis) override;
71 
72 protected:
77  OgreTile(Ogre::SceneManager *sc,
78  Ogre::String materialName,
79  blub::async::dispatcher &graphicDispatcher);
84  void initialise();
85 
89  void createMeshGraphic();
100  void setVisibleGraphic(const bool& vis);
107  void setVisibleLodGraphic(const blub::uint16& indLod, const bool& vis);
115  static void destroyAllGraphic(Ogre::SceneManager* scene, Ogre::MeshPtr mesh_, Ogre::Entity *entity_, Ogre::SceneNode *node_);
116 
117  void addCustomVertexInformation(Ogre::VertexBufferBinding* binding, const t_vertices& vertices) {;}
118  void addCustomVertexDeclaration(Ogre::VertexDeclaration* decl) {;}
119 
120  constPointer getSharedThisPtr() const;
121  pointer getSharedThisPtr();
122 
123 private:
124  blub::async::dispatcher &m_graphicDispatcher;
125 
126  Ogre::String m_materialName;
127  Ogre::SceneManager* m_scene;
128  Ogre::MeshPtr m_mesh;
129  Ogre::Entity* m_entity;
130  Ogre::SceneNode* m_node;
131 
132  blub::int32 m_indexLodSubMesh[6];
133 };
134 
135 
136 template <typename configType>
137 OgreTile<configType>::OgreTile(Ogre::SceneManager *sc,
138  Ogre::String materialName,
139  blub::async::dispatcher &graphicDispatcher)
140  : m_graphicDispatcher(graphicDispatcher)
141  , m_materialName(materialName)
142  , m_scene(sc)
143  , m_entity(nullptr)
144  , m_node(nullptr)
145 {
146  for (blub::int32 ind = 0; ind < 6; ++ind)
147  {
148  m_indexLodSubMesh[ind] = -1;
149  }
150 }
151 
152 
153 template <typename configType>
155  Ogre::String materialName,
156  blub::async::dispatcher *graphicDispatcher)
157 {
158  BASSERT(graphicDispatcher != nullptr);
159  pointer result(new OgreTile(sc, materialName, *graphicDispatcher));
160  result->initialise();
161  return result;
162 }
163 
164 template <typename configType>
166 {
167  m_graphicDispatcher.dispatch(boost::bind(&OgreTile::destroyAllGraphic, m_scene, m_mesh, m_entity, m_node));
168 }
169 
170 template <typename configType>
172 {
173  m_graphicDispatcher.dispatch(boost::bind(&OgreTile::createMeshGraphic, getSharedThisPtr()));
174 }
175 
176 template <typename configType>
177 void OgreTile<configType>::setTileData(typename t_base::t_tileDataPtr convertToRenderAble, const blub::axisAlignedBox &aabb)
178 {
179  typename t_voxelSurfaceTile::pointer convertToRenderAbleCasted(convertToRenderAble.template staticCast<t_voxelSurfaceTile>());
180  typename t_voxelSurfaceTile::pointer copy(t_voxelSurfaceTile::createCopy(convertToRenderAbleCasted));
181  m_graphicDispatcher.dispatch(boost::bind(&OgreTile::setTileDataGraphic, getSharedThisPtr(), copy, aabb));
182 }
183 
184 template <typename configType>
185 void OgreTile<configType>::setVisible(const bool &vis)
186 {
187  t_base::setVisible(vis);
188  m_graphicDispatcher.dispatch(boost::bind(&OgreTile::setVisibleGraphic, getSharedThisPtr(), vis));
189 }
190 
191 template <typename configType>
192 void OgreTile<configType>::setVisibleLod(const blub::uint16 &indLod, const bool &vis)
193 {
194  if (t_base::m_lodShouldBeVisible[indLod] == vis)
195  {
196  return; // nothing todo
197  }
198  t_base::setVisibleLod(indLod, vis);
199  m_graphicDispatcher.dispatch(boost::bind(&OgreTile::setVisibleLodGraphic, getSharedThisPtr(), indLod, vis));
200 }
201 
202 
203 template <typename configType>
205 {
206  m_mesh = Ogre::MeshManager::getSingleton().createManual(
207  blub::string("voxel_") + blub::string::number(g_meshId++),
208  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
209  m_node = m_scene->getRootSceneNode()->createChildSceneNode();
210 }
211 
212 template <typename configType>
214 {
215  using namespace blub;
216 
217  bool wasVisible(false);
218  if (m_entity)
219  {
220  wasVisible = m_entity->getVisible();
221 
222  delete m_entity;
223  m_entity = nullptr;
224  }
225 
226  uint32 numSubmeshes(1);
227  if (convertToRenderAble->getCaluculateLod())
228  {
229  for (int32 indLod = 0; indLod < 6; ++indLod)
230  {
231  if (convertToRenderAble->getIndicesLod(indLod).size() > 0)
232  {
233  ++numSubmeshes;
234  }
235  }
236  }
237 
238  {
239  const t_vertices vertices(convertToRenderAble->getVertices());
240  const typename t_base::t_tileData::t_indices indices(convertToRenderAble->getIndices());
241 
242  BASSERT(vertices.size() >= 3);
243  BASSERT(indices.size() >= 3);
244  BASSERT(indices.size() % 3 == 0);
245 
246  Ogre::MeshPtr meshWork(m_mesh);
247 
248  const vector3 aabbHalfSize(aabb.getHalfSize());
249  meshWork->_setBounds(axisAlignedBox(-aabbHalfSize, aabbHalfSize), false);
250  // meshWork->_setBounds(aabb, false);
251  const real radius(aabbHalfSize.length());
252  meshWork->_setBoundingSphereRadius(radius);
253  // BLUB_LOG_OUT() << "aabbHalfSize:" << aabbHalfSize;
254 
255  if (meshWork->sharedVertexData == nullptr)
256  {
257  meshWork->sharedVertexData = new Ogre::VertexData();
258 
259  {
260  Ogre::VertexDeclaration* decl = meshWork->sharedVertexData->vertexDeclaration;
261 
262  decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
263  decl->addElement(1, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
264  static_cast<t_thiz>(this)->addCustomVertexDeclaration(decl);
265  }
266  }
267 
268  meshWork->sharedVertexData->vertexCount = vertices.size();
269  Ogre::VertexBufferBinding* bind = meshWork->sharedVertexData->vertexBufferBinding;
270  {
271  Ogre::HardwareVertexBufferSharedPtr positionBuffer;
272  const size_t sizeVertex = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
273 
274  positionBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
275  sizeVertex, meshWork->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
276 
277  vector3* toWriteTo(static_cast<vector3*>(positionBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)));
278  for (uint32 ind = 0; ind < vertices.size(); ++ind)
279  {
280  toWriteTo[ind] = vertices.at(ind).position - aabbHalfSize;
281  }
282  positionBuffer->unlock();
283 
284  bind->setBinding(0, positionBuffer);
285  }
286  {
287  Ogre::HardwareVertexBufferSharedPtr normalBuffer;
288  const size_t sizeVertex = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
289 
290  normalBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
291  sizeVertex, meshWork->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
292 
293  vector3* toWriteTo(static_cast<vector3*>(normalBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)));
294  for (uint32 ind = 0; ind < vertices.size(); ++ind)
295  {
296  toWriteTo[ind] = vertices.at(ind).normal;
297  }
298  normalBuffer->unlock();
299 
300  bind->setBinding(1, normalBuffer);
301  }
302  static_cast<t_thiz>(this)->addCustomVertexInformation(bind, vertices);
303 
304  if (numSubmeshes < meshWork->getNumSubMeshes())
305  {
306  for (int32 ind = 0; meshWork->getNumSubMeshes() - numSubmeshes; ++ind)
307  {
308  meshWork->destroySubMesh(0);
309  }
310  }
311  if (numSubmeshes > meshWork->getNumSubMeshes())
312  {
313  for (int32 ind = 0; numSubmeshes - meshWork->getNumSubMeshes(); ++ind)
314  {
315  Ogre::SubMesh* sub(meshWork->createSubMesh());
316  sub->setBuildEdgesEnabled(false);
317  sub->useSharedVertices = true;
318  }
319  }
320  BASSERT(numSubmeshes == meshWork->getNumSubMeshes());
321 
322  for (int32 indLod = 0; indLod < 6; ++indLod)
323  {
324  m_indexLodSubMesh[indLod] = -1;
325  }
326 
327  int32 indexSubMesh(0);
328  uint32 numIterations(7);
329  if (numSubmeshes == 1)
330  {
331  numIterations = 1;
332  }
333  for (uint32 indSubMesh = 0; indSubMesh < numIterations; ++indSubMesh)
334  {
335  uint16 numIndices;
336  if (indSubMesh == 0)
337  {
338  BASSERT(indices.size() < 65536);
339  numIndices = indices.size();
340  }
341  else
342  {
343  const typename t_base::t_tileData::t_indices& indicesLod(convertToRenderAble->getIndicesLod(indSubMesh-1));
344  BASSERT(indicesLod.size() < 65536);
345  if (indicesLod.empty())
346  {
347  continue;
348  }
349  BASSERT(indicesLod.size() % 3 == 0);
350  numIndices = indicesLod.size();
351  }
352 
353  Ogre::HardwareIndexBufferSharedPtr indexBuffer = Ogre::HardwareBufferManager::getSingleton().
354  createIndexBuffer(
355  Ogre::HardwareIndexBuffer::IT_16BIT,
356  numIndices,
357  Ogre::HardwareBuffer::HBU_STATIC);
358  uint16* toWriteTo(static_cast<uint16*>(indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)));
359  {
360  if (indSubMesh == 0)
361  {
362  memcpy(toWriteTo, indices.data(), sizeof(uint16) * numIndices);
363  }
364  else
365  {
366  const typename t_base::t_tileData::t_indices& indicesLod(convertToRenderAble->getIndicesLod(indSubMesh-1));
367  memcpy(toWriteTo, indicesLod.data(), sizeof(uint16) * numIndices);
368  }
369  }
370  indexBuffer->unlock();
371 
372  Ogre::SubMesh* sub = meshWork->getSubMesh(indexSubMesh);
373  sub->indexData->indexBuffer = indexBuffer;
374  sub->indexData->indexCount = numIndices;
375  sub->indexData->indexStart = 0;
376  sub->setMaterialName(m_materialName);
377 
378  if (indSubMesh > 0)
379  {
380  m_indexLodSubMesh[indSubMesh-1] = indexSubMesh;
381  }
382  ++indexSubMesh;
383  }
384  }
385 
386  m_entity = m_scene->createEntity(m_mesh);
387  m_node->setPosition(aabb.getCenter());
388  m_node->attachObject(m_entity);
389  setVisibleGraphic(wasVisible);
390 
391  for (int32 indLod = 0; indLod < 6; ++indLod)
392  {
393  if (m_indexLodSubMesh[indLod] != -1)
394  {
395  m_entity->getSubEntity(m_indexLodSubMesh[indLod])->setVisible(t_base::m_lodShouldBeVisible[indLod]);
396  }
397  }
398 }
399 
400 template <typename configType>
402 {
403  m_node->setVisible(vis);
404 }
405 
406 template <typename configType>
407 void OgreTile<configType>::setVisibleLodGraphic(const blub::uint16& indLod, const bool& vis)
408 {
409  if (m_indexLodSubMesh[indLod] != -1)
410  {
411  m_entity->getSubEntity(m_indexLodSubMesh[indLod])->setVisible(vis);
412  }
413 }
414 
415 template <typename configType>
416 void OgreTile<configType>::destroyAllGraphic(Ogre::SceneManager* scene, Ogre::MeshPtr mesh_, Ogre::Entity *entity_, Ogre::SceneNode *node_)
417 {
418  scene->destroyEntity(entity_);
419  Ogre::MeshManager::getSingleton().remove(mesh_->getName());
420 
421  scene->destroySceneNode(node_);
422 }
423 
424 template <typename configType>
426 {
427  return t_base::getSharedThisPtr().template staticCast<const OgreTile<configType> >();
428 }
429 template <typename configType>
431 {
432  return t_base::getSharedThisPtr().template staticCast<OgreTile<configType> >();
433 }
434 
435 
436 
437 #endif // OGRETILE_HPP
void setTileDataGraphic(blub::sharedPointer< t_voxelSurfaceTile > convertToRenderAble, const blub::axisAlignedBox &aabb)
setTileDataGraphic convertes a vector of vertices and indices to ogres hardware buffer.
Definition: OgreTile.hpp:213
Definition: customVertexInformation.cpp:186
vector3 getCenter(void) const
Gets the centre of the box.
Definition: axisAlignedBox.hpp:479
void setVisible(const bool &vis) override
setVisible sets if a tile should get rendered. All lod-submeshes must not be rendered either...
Definition: OgreTile.hpp:185
void setVisibleLodGraphic(const blub::uint16 &indLod, const bool &vis)
setVisibleLodGraphic sets a subentity-visibility. Gets called if the neighbour tile has a different L...
Definition: OgreTile.hpp:407
virtual ~OgreTile()
~OgreTile desctructor. Calls the static method destroyAllGraphic() to ensure Ogre instances get delet...
Definition: OgreTile.hpp:165
static void destroyAllGraphic(Ogre::SceneManager *scene, Ogre::MeshPtr mesh_, Ogre::Entity *entity_, Ogre::SceneNode *node_)
destroyAllGraphic gets called by destructor - ensures that ogre3d classes get destroyed by the right ...
Definition: OgreTile.hpp:416
OgreTile(Ogre::SceneManager *sc, Ogre::String materialName, blub::async::dispatcher &graphicDispatcher)
OgreTile constrcutor.
Definition: OgreTile.hpp:137
void initialise()
initialise calls createMeshGraphic() on graphic thread. Not called by constructor because getSharedTh...
Definition: OgreTile.hpp:171
Definition: sharedPointer.hpp:12
vector3 getHalfSize(void) const
Gets the half-size of the box.
Definition: axisAlignedBox.cpp:79
Definition: string.hpp:22
Definition: dispatcher.hpp:29
Definition: vector3.hpp:26
The OgreTile class converts the resulting vertices and indices of the voxel-terrain to the Ogre Hardw...
Definition: OgreTile.hpp:37
Definition: axisAlignedBox.hpp:20
The base class gets derived by every class in the namespace tile::*. Never instance this class and de...
Definition: predecl.hpp:17
The renderer class contains information if a tile::surface should get rendered and how it should get ...
Definition: predecl.hpp:23
static pointer create(Ogre::SceneManager *sc, Ogre::String materialName, blub::async::dispatcher *graphicDispatcher)
create creates an instance and calls initialise().
Definition: OgreTile.hpp:154
Definition: deadlineTimer.hpp:10
void createMeshGraphic()
createMeshGraphic allocates and initialises an Ogre::Mesh where the vertices and indices will get sav...
Definition: OgreTile.hpp:204
void setVisibleGraphic(const bool &vis)
setVisibleGraphic sets the whole tile to visible or invisible. Gets called when tile cutted because t...
Definition: OgreTile.hpp:401