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.

voxelmath.cpp 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * =====================================================================================
  3. *
  4. * Filename: voxelmath.cpp
  5. *
  6. * Description:
  7. *
  8. * Version: 1.0
  9. * Created: 04/07/2014 03:48:53 PM
  10. * Revision: none
  11. * Compiler: gcc
  12. *
  13. * Author: YOUR NAME (),
  14. * Organization:
  15. *
  16. * =====================================================================================
  17. */
  18. #include "voxelmath.h"
  19. #include "world.h"
  20. #include "mathplus.h"
  21. #include <cmath>
  22. #include <iostream>
  23. namespace vtk {
  24. void VoxelMath::rayCast(glm::vec3& hitPos, glm::vec3& hitNormal, bool& success,
  25. const glm::vec3& origin, const glm::vec3& direction, const float& radius) {
  26. glm::vec3 adjustedOrigin = origin * linkedWorld->voxelSize;
  27. glm::vec3 voxelLoc(floor(adjustedOrigin.x),
  28. floor(adjustedOrigin.y),
  29. floor(adjustedOrigin.z));
  30. glm::vec3 step((float)mp::signum(direction.x),
  31. (float)mp::signum(direction.y),
  32. (float)mp::signum(direction.z));
  33. glm::vec3 max(mp::bound(adjustedOrigin.x, direction.x),
  34. mp::bound(adjustedOrigin.y, direction.y),
  35. mp::bound(adjustedOrigin.z, direction.z));
  36. glm::vec3 delta(step.x / direction.x,
  37. step.y / direction.y,
  38. step.z / direction.z);
  39. float nRadius = radius / sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z);
  40. if (direction.x == 0 && direction.y == 0 && direction.z == 0) {
  41. success = false;
  42. return;
  43. }
  44. while (true) {
  45. //std::cout << voxelLoc.x << ", " << voxelLoc.y << ", " << voxelLoc.z << std::endl;
  46. //std::cout << hitNormal.x << ", " << hitNormal.y << ", " << hitNormal.z << std::endl;
  47. if (max.x < max.y) {
  48. if (max.x < max.z) {
  49. if (max.x > nRadius) {
  50. success = false;
  51. break;
  52. }
  53. voxelLoc.x += step.x;
  54. max.x += delta.x;
  55. hitNormal.x = -step.x;
  56. hitNormal.y = 0.0f;
  57. hitNormal.z = 0.0f;
  58. } else {
  59. if (max.z > nRadius) {
  60. success = false;
  61. break;
  62. }
  63. voxelLoc.z += step.z;
  64. max.z += delta.z;
  65. hitNormal.x = 0.0f;
  66. hitNormal.y = 0.0f;
  67. hitNormal.z = -step.z;
  68. }
  69. } else {
  70. if (max.y < max.z) {
  71. if (max.y > nRadius) {
  72. success = false;
  73. break;
  74. }
  75. voxelLoc.y += step.y;
  76. max.y += delta.y;
  77. hitNormal.x = 0.0f;
  78. hitNormal.y = -step.y;
  79. hitNormal.z = 0.0f;
  80. } else {
  81. if (max.z > nRadius) {
  82. success = false;
  83. break;
  84. }
  85. voxelLoc.z += step.z;
  86. max.z += delta.z;
  87. hitNormal.x = 0.0f;
  88. hitNormal.y = 0.0f;
  89. hitNormal.z = -step.z;
  90. }
  91. }
  92. if (linkedWorld->isVoxelSolid((int)voxelLoc.x, (int)voxelLoc.y, (int)voxelLoc.z)) {
  93. success = true;
  94. hitPos = voxelLoc;
  95. break;
  96. }
  97. }
  98. }
  99. iPos VoxelMath::getChunkContaining(const int& x, const int& y, const int& z) {
  100. return std::make_tuple(floor((float)x / (float)linkedWorld->chunkSize),
  101. floor((float)y / (float)linkedWorld->chunkSize),
  102. floor((float)z / (float)linkedWorld->chunkSize));
  103. }
  104. }