You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

heightmap.cpp 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #include "heightmap.h"
  2. #include "world.h"
  3. namespace vtk {
  4. HeightMap::HeightMap(const glm::ivec2& pos, World& world) :
  5. mPos(pos),
  6. mWorld(world)
  7. {
  8. //initialize all heights to 0
  9. for (int i = 0; i < mHeights.size(); ++i) {
  10. mHeights[i].store(0x80000000);
  11. }
  12. }
  13. glm::ivec2 HeightMap::getPos() {
  14. return mPos;
  15. }
  16. int HeightMap::getHeight(const glm::ivec2 &pos) {
  17. int index = pos.x + (16 * pos.y);
  18. return mHeights[index].load(std::memory_order_consume);
  19. }
  20. bool HeightMap::pushUpdate(const glm::ivec3 &pos, const bool &destroyed) {
  21. return mUpdateQueue.try_enqueue(std::make_pair(pos, destroyed));
  22. }
  23. void HeightMap::blockHeight(const glm::ivec3& pos) {
  24. if (getHeight(glm::ivec2(pos.x, pos.z)) < pos.y) {
  25. setHeight(pos);
  26. }
  27. }
  28. void HeightMap::unblockHeight(const glm::ivec3& pos) {
  29. int height = getHeight(glm::ivec2(pos.x, pos.z));
  30. if (height <= pos.y) {
  31. glm::ivec3 searchPos(pos.x + (mPos.x * 16), pos.y, pos.z + (mPos.y * 16));
  32. while (!mWorld.isVoxelSolid(searchPos.x, searchPos.y, searchPos.z)) {
  33. --searchPos.y;
  34. }
  35. setHeight(glm::ivec3(pos.x, searchPos.y, pos.z));
  36. }
  37. }
  38. void HeightMap::flushUpdates() {
  39. std::pair<glm::ivec3, bool> updateItem;
  40. while (mUpdateQueue.try_dequeue(updateItem)) {
  41. glm::ivec3& pos = updateItem.first;
  42. int height = getHeight(glm::ivec2(pos.x, pos.z));
  43. if (updateItem.second) { // if destroyed
  44. if(height == pos.y) { // if voxel is at the top of the heightmap
  45. // search downward until the next solid voxel is reached
  46. glm::ivec3 searchPos(pos.x + (mPos.x * 16), pos.y, pos.z + (mPos.y * 16));
  47. while(!mWorld.isVoxelSolid(searchPos.x, searchPos.y, searchPos.z)) {
  48. --searchPos.y;
  49. }
  50. setHeight(glm::ivec3(pos.x, searchPos.y, pos.z));
  51. }
  52. } else { // if placed
  53. if (height < pos.y)
  54. setHeight(pos);
  55. }
  56. }
  57. }
  58. void HeightMap::setHeight(const glm::ivec3& pos) {
  59. mHeights[pos.x + (16 * pos.z)].store(pos.y, std::memory_order_release);
  60. }
  61. }