1 #ifndef PROCEDURAL_VOXEL_ACCESSOR_ACCESSOR_HPP
2 #define PROCEDURAL_VOXEL_ACCESSOR_ACCESSOR_HPP
4 #include "blub/async/mutexReadWrite.hpp"
5 #include "blub/core/globals.hpp"
6 #include "blub/core/hashList.hpp"
7 #include "blub/core/hashMap.hpp"
8 #include "blub/core/noncopyable.hpp"
9 #include "blub/core/signal.hpp"
10 #include "blub/math/axisAlignedBoxInt32.hpp"
11 #include "blub/math/vector3.hpp"
12 #include "blub/procedural/log/global.hpp"
13 #include "blub/procedural/voxel/simple/base.hpp"
14 #include "blub/procedural/voxel/simple/container/base.hpp"
15 #include "blub/procedural/voxel/simple/container/utils/tile.hpp"
16 #include "blub/procedural/voxel/tile/accessor.hpp"
17 #include "blub/procedural/voxel/tile/container.hpp"
35 template <
class configType>
36 class accessor :
public base<typename configType::t_accessor::t_tile>
40 typedef typename t_config::t_accessor::t_tile t_tile;
41 typedef sharedPointer<t_tile> t_tilePtr;
42 typedef base<t_tile> t_base;
46 typedef hashMap<vector3int32, t_tilePtr> t_tiles;
48 typedef typename t_config::t_container::t_tile t_tileContainer;
49 typedef sharedPointer<t_tileContainer> t_tileContainerPtr;
50 typedef hashList<vector3int32> t_tileIdList;
51 typedef container::utils::tileState t_tileState;
52 typedef container::utils::tile<t_tileContainer> t_tileHolder;
53 typedef hashMap<t_tileId, t_tileHolder> t_tileHolderMap;
55 typedef typename t_config::t_container::t_simple t_simpleContainerVoxel;
66 t_simpleContainerVoxel &voxels,
71 , m_voxelSkip(
math::pow(2, m_lod))
85 blub::BOUT(
"accessor::~accessor()");
106 typename t_tiles::const_iterator it = m_tiles.find(
id);
107 if (it == m_tiles.cend())
121 m_voxels.lockForRead();
131 const auto& changedTiles(m_voxels.getTilesThatGotEdited());
132 #ifdef BLUB_LOG_VOXEL
133 BLUB_PROCEDURAL_LOG_OUT() <<
"accessor tilesGotChangedMaster changedTiles.size():" << changedTiles.size();
135 BASSERT(!changedTiles.empty());
142 t_tileIdList affectedTiles;
143 for (
auto change : changedTiles)
145 const t_tileId id(change.first);
146 const t_tileHolder workTile(change.second);
150 if (workTile.state == container::utils::tileState::empty)
152 if (m_tiles.find(
id) == m_tiles.cend())
162 if (affectedTiles.empty())
165 m_voxels.unlockRead();
170 BASSERT(m_numTilesInWork == 0);
171 m_numTilesInWork = affectedTiles.size();
173 for (
const t_tileId
id : affectedTiles)
186 if (workTile.isNull())
192 const vector3int32 voxelStart(
id*t_tile::voxelLength*m_voxelSkip);
194 t_tileHolderMap lastUsedTiles;
196 bool valuesChanged(
false);
197 for (int32 indX = -1; indX < t_tile::voxelLength+2; ++indX)
199 for (int32 indY = -1; indY < t_tile::voxelLength+2; ++indY)
201 for (int32 indZ = -1; indZ < t_tile::voxelLength+2; ++indZ)
204 const vector3int32 voxelPosAbs(voxelStart + pos*m_voxelSkip);
206 valuesChanged |= workTile->setVoxel(pos,
getVoxelData(voxelPosAbs, lastUsedTiles));
211 if (workTile->getCalculateLod())
213 BASSERT(m_voxelSkip > 0);
215 const int32 voxelLengthLod = t_tile::voxelLengthLod;
224 for (int32 lod = 0; lod < 6; ++lod)
228 for (int32 indX = start.x; indX < end.x; ++indX)
230 for (int32 indY = start.y; indY < end.y; ++indY)
232 for (int32 indZ = start.z; indZ < end.z; ++indZ)
235 const vector3int32 voxelPosAbs(voxelStart + pos*(m_voxelSkip/2));
237 const t_voxel result(
getVoxelData(voxelPosAbs, lastUsedTiles));
243 BASSERT(workTile->getVoxel(pos / 2) == result);
247 valuesChanged |= workTile->setVoxelLod(pos-start, result, lod);
254 if (workTile->isEmpty() || workTile->isFull())
273 typename t_tiles::const_iterator it = m_tiles.find(
id);
276 if (workTile.isNull())
278 if (it != m_tiles.cend())
286 BASSERT(!workTile.isNull());
287 if (it == m_tiles.cend())
289 m_tiles.insert(
id, workTile);
291 if (didValuesChanged)
299 if (m_numTilesInWork == 0)
301 if (t_base::m_tilesThatGotEdited.size() == 0)
303 BLUB_LOG_WARNING() <<
"nothing changed";
305 m_voxels.unlockRead();
320 const vector3 forDiv(conterainerId);
321 const vector3int32 result((forDiv / (real)m_voxelSkip).getFloor());
322 resultingSurfaceTiles.insert(result);
325 if (holder.state == t_tileState::partitial)
327 BASSERT(holder.data->getEditedVoxelBoundingBox().isValid());
328 minimum = holder.data->getEditedVoxelBoundingBox().getMinimum();
335 const vector3int32 resultMod(conterainerId%m_voxelSkip);
336 if (resultMod.x == 0 && minimum.x == 0)
338 resultingSurfaceTiles.insert(result -
vector3int32(1, 0, 0));
340 if (resultMod.y == 0 && minimum.y == 0)
342 resultingSurfaceTiles.insert(result -
vector3int32(0, 1, 0));
344 if (resultMod.z == 0 && minimum.z == 0)
346 resultingSurfaceTiles.insert(result -
vector3int32(0, 0, 1));
348 if (resultMod.x == 0 && resultMod.y == 0 && minimum.x == 0 && minimum.y == 0)
350 resultingSurfaceTiles.insert(result -
vector3int32(1, 1, 0));
352 if (resultMod.x == 0 && resultMod.z == 0 && minimum.x == 0 && minimum.z == 0)
354 resultingSurfaceTiles.insert(result -
vector3int32(1, 0, 1));
356 if (resultMod.y == 0 && resultMod.z == 0 && minimum.y == 0 && minimum.z == 0)
358 resultingSurfaceTiles.insert(result -
vector3int32(0, 1, 1));
360 if (resultMod.x == 0 && resultMod.y == 0 && resultMod.z == 0 && minimum ==
vector3int32(0))
362 resultingSurfaceTiles.insert(result -
vector3int32(1, 1, 1));
373 result->setCalculateLod(m_lod > 0);
385 const vector3int32 &tilePos(m_voxels.calculateVoxelPosToTileId(voxelPosAbs));
388 typename t_tileHolderMap::const_iterator it = lastUsedTiles.find(tilePos);
391 if (it != lastUsedTiles.cend())
393 const t_tileHolder &lastUsedTile(it->second);
394 switch(lastUsedTile.state)
396 case t_tileState::partitial:
397 result = lastUsedTile.data->getVoxel(voxelPosAbs-tilePosAbs);
399 case t_tileState::empty:
402 case t_tileState::full:
412 const t_tileHolder &lastUsedTile(m_voxels.getTileHolder(tilePos));
413 lastUsedTiles.insert(tilePos, lastUsedTile);
416 switch(lastUsedTile.state)
418 case t_tileState::partitial:
419 result = lastUsedTile.data->getVoxel(voxelPosAbs-tilePosAbs);
421 case t_tileState::empty:
424 case t_tileState::full:
435 t_simpleContainerVoxel& m_voxels;
437 const int32 m_voxelSkip;
438 int32 m_numTilesInWork;
442 boost::signals2::scoped_connection m_connTilesGotChanged;
452 #endif // PROCEDURAL_VOXEL_ACCESSOR_ACCESSOR_HPP
virtual void lockForEditMaster()
lockForEditMaster locks for write, or waits until possible. Call by master dispatcher.
Definition: base.hpp:228
void tilesGotChangedMaster()
tilesGotChangedMaster must not get called paralell.
Definition: accessor.hpp:129
Definition: customVertexInformation.cpp:193
t_simpleContainerVoxel & getVoxelContainer() const
getVoxelContainer returns the voxel container, set in the constructor.
Definition: accessor.hpp:93
void setMax()
setMax sets all values to maximum. See class description.
Definition: data.hpp:113
void setMin()
setMin sets all values to minimum. See class description.
Definition: data.hpp:105
vector3int32 t_tileId
Definition: base.hpp:44
virtual t_tilePtr createTile() const
createTile creates a new Tile. Uses callback set by setCreateTileCallback()
Definition: base.hpp:249
void afterCalculateAccessorMaster(const t_tileId &id, t_tilePtr workTile, const bool &didValuesChanged)
afterCalculateAccessorMaster gets called after a worker-thread finished calculation of a part...
Definition: accessor.hpp:269
virtual void unlockForEditMaster()
unlockForEditMaster unlocks write. Call by master dispatcher.
Definition: base.hpp:236
const t_tilesGotChangedMap & getTilesThatGotEdited() const
getTilesThatGotEdited returns a list of tiles which changed since the last call lockForEdit() / lockF...
Definition: base.hpp:198
t_voxel getVoxelData(const vector3int32 &voxelPosAbs, t_tileHolderMap &lastUsedTiles)
getVoxelData returns a voxel from a cahned container-tile or looks up the tile and returns it...
Definition: accessor.hpp:383
void addToChangeList(const t_tileId &id, t_tilePtr toAdd)
addToChangeList adds a tile to the change-list.
Definition: base.hpp:210
Definition: dispatcher.hpp:29
t_tilePtr getTile(const t_tileId &id) const
getTile returns an accessor tile. Read-lock class before.
Definition: accessor.hpp:104
Definition: vector3.hpp:26
accessor(async::dispatcher &worker, t_simpleContainerVoxel &voxels, const int32 &lod)
accessor constructor
Definition: accessor.hpp:65
~accessor()
~accessor destructor
Definition: accessor.hpp:82
void calculateAccessorTS(const t_tileId &id, t_tilePtr workTile)
calculateAccessorTS accesses the container and pulls out all voxel needed for surface calculation (ma...
Definition: accessor.hpp:184
The data class is the default voxel. Contains an 8-bit interpolation value. Replace/derive it and set...
Definition: data.hpp:27
blub::async::dispatcher & m_worker
m_worker use it to dispatch heavy work. Don't write to class member with it. Do not use any locks...
Definition: base.hpp:148
void tilesGotChanged()
tilesGotChanged gets called after in the voxel container m_voxels, set in the constructor, the voxels changed. Which leads to a recalculation of the cache.
Definition: accessor.hpp:119
t_tilePtr createTile() const override
createTile creates an empty tile.
Definition: accessor.hpp:370
void calculateAffectedAccessorTilesByContainerTile(const t_tileId &conterainerId, const t_tileHolder &holder, t_tileIdList &resultingSurfaceTiles)
When a tile in container gets changed it affects (because of normal-correction and lod) 3^3 accessor-...
Definition: accessor.hpp:318
Definition: deadlineTimer.hpp:10
blub::async::strand m_master
m_master The master synchronises jobs for the worker-thread and writes to class member. The master calls all methods which end with *Master.
Definition: base.hpp:143
void setCreateTileCallback(const t_createTileCallback &callback)
setCreateTileCallback sets a callback for creating tiles. Use this method if you want to create custo...
Definition: base.hpp:204
Definition: customVertexInformation.cpp:177