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.
129 lines
3.7 KiB
129 lines
3.7 KiB
/* |
|
* ===================================================================================== |
|
* |
|
* Filename: voxelmath.cpp |
|
* |
|
* Description: |
|
* |
|
* Version: 1.0 |
|
* Created: 04/07/2014 03:48:53 PM |
|
* Revision: none |
|
* Compiler: gcc |
|
* |
|
* Author: YOUR NAME (), |
|
* Organization: |
|
* |
|
* ===================================================================================== |
|
*/ |
|
|
|
#include "voxelmath.h" |
|
#include "world.h" |
|
#include "mathplus.h" |
|
|
|
#include <cmath> |
|
#include <iostream> |
|
|
|
namespace vtk { |
|
|
|
void VoxelMath::rayCast(glm::vec3& hitPos, glm::vec3& hitNormal, bool& success, |
|
const glm::vec3& origin, const glm::vec3& direction, const float& radius) { |
|
|
|
glm::vec3 adjustedOrigin = origin * linkedWorld->voxelSize; |
|
glm::vec3 voxelLoc(floor(adjustedOrigin.x), |
|
floor(adjustedOrigin.y), |
|
floor(adjustedOrigin.z)); |
|
|
|
glm::vec3 step((float)mp::signum(direction.x), |
|
(float)mp::signum(direction.y), |
|
(float)mp::signum(direction.z)); |
|
|
|
glm::vec3 max(mp::bound(adjustedOrigin.x, direction.x), |
|
mp::bound(adjustedOrigin.y, direction.y), |
|
mp::bound(adjustedOrigin.z, direction.z)); |
|
|
|
glm::vec3 delta(step.x / direction.x, |
|
step.y / direction.y, |
|
step.z / direction.z); |
|
|
|
float nRadius = radius / sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z); |
|
|
|
if (direction.x == 0 && direction.y == 0 && direction.z == 0) { |
|
success = false; |
|
return; |
|
} |
|
|
|
while (true) { |
|
//std::cout << voxelLoc.x << ", " << voxelLoc.y << ", " << voxelLoc.z << std::endl; |
|
//std::cout << hitNormal.x << ", " << hitNormal.y << ", " << hitNormal.z << std::endl; |
|
|
|
if (max.x < max.y) { |
|
if (max.x < max.z) { |
|
if (max.x > nRadius) { |
|
success = false; |
|
break; |
|
} |
|
|
|
voxelLoc.x += step.x; |
|
max.x += delta.x; |
|
|
|
hitNormal.x = -step.x; |
|
hitNormal.y = 0.0f; |
|
hitNormal.z = 0.0f; |
|
|
|
} else { |
|
if (max.z > nRadius) { |
|
success = false; |
|
break; |
|
} |
|
|
|
voxelLoc.z += step.z; |
|
max.z += delta.z; |
|
|
|
hitNormal.x = 0.0f; |
|
hitNormal.y = 0.0f; |
|
hitNormal.z = -step.z; |
|
} |
|
} else { |
|
if (max.y < max.z) { |
|
if (max.y > nRadius) { |
|
success = false; |
|
break; |
|
} |
|
|
|
voxelLoc.y += step.y; |
|
max.y += delta.y; |
|
|
|
hitNormal.x = 0.0f; |
|
hitNormal.y = -step.y; |
|
hitNormal.z = 0.0f; |
|
} else { |
|
if (max.z > nRadius) { |
|
success = false; |
|
break; |
|
} |
|
|
|
voxelLoc.z += step.z; |
|
max.z += delta.z; |
|
|
|
hitNormal.x = 0.0f; |
|
hitNormal.y = 0.0f; |
|
hitNormal.z = -step.z; |
|
} |
|
} |
|
|
|
if (linkedWorld->isVoxelSolid((int)voxelLoc.x, (int)voxelLoc.y, (int)voxelLoc.z)) { |
|
success = true; |
|
hitPos = voxelLoc; |
|
break; |
|
} |
|
} |
|
|
|
} |
|
|
|
iPos VoxelMath::getChunkContaining(const int& x, const int& y, const int& z) { |
|
return std::make_tuple(floor((float)x / (float)linkedWorld->chunkSize), |
|
floor((float)y / (float)linkedWorld->chunkSize), |
|
floor((float)z / (float)linkedWorld->chunkSize)); |
|
} |
|
|
|
}
|
|
|