mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 04:03:59 +02:00
Return the box face, as well as the distance, from the ray intersection test.
Use it to determine which voxel neighbor we create when adding.
This commit is contained in:
parent
2b9c2ca9a2
commit
7ff8b84f4c
7 changed files with 68 additions and 19 deletions
|
@ -680,9 +680,10 @@ void VoxelSystem::removeOutOfView() {
|
|||
}
|
||||
}
|
||||
|
||||
bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance) {
|
||||
bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
VoxelDetail& detail, float& distance, BoxFace& face) {
|
||||
VoxelNode* node;
|
||||
if (!_tree->findRayIntersection(origin, direction, node, distance)) {
|
||||
if (!_tree->findRayIntersection(origin, direction, node, distance, face)) {
|
||||
return false;
|
||||
}
|
||||
detail.x = node->getCorner().x;
|
||||
|
|
|
@ -65,7 +65,8 @@ public:
|
|||
void removeOutOfView();
|
||||
bool hasViewChanged();
|
||||
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance);
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
VoxelDetail& detail, float& distance, BoxFace& face);
|
||||
|
||||
private:
|
||||
int _callsToTreesToArrays;
|
||||
|
|
|
@ -1489,11 +1489,34 @@ void addVoxelUnderCursor() {
|
|||
|
||||
VoxelDetail detail;
|
||||
float distance;
|
||||
if (voxels.findRayIntersection(origin, direction, detail, distance)) {
|
||||
// get the hit location relative to the center of the voxel
|
||||
float half = detail.s * 0.5f;
|
||||
glm::vec3 hit = origin + distance*direction - glm::vec3(detail.x + half, detail.y + half, detail.z + half);
|
||||
|
||||
BoxFace face;
|
||||
if (voxels.findRayIntersection(origin, direction, detail, distance, face)) {
|
||||
// use the face to determine the side on which to create a neighbor
|
||||
switch (face) {
|
||||
case MIN_X_FACE:
|
||||
detail.x -= detail.s;
|
||||
break;
|
||||
|
||||
case MAX_X_FACE:
|
||||
detail.x += detail.s;
|
||||
break;
|
||||
|
||||
case MIN_Y_FACE:
|
||||
detail.y -= detail.s;
|
||||
break;
|
||||
|
||||
case MAX_Y_FACE:
|
||||
detail.y += detail.s;
|
||||
break;
|
||||
|
||||
case MIN_Z_FACE:
|
||||
detail.z -= detail.s;
|
||||
break;
|
||||
|
||||
case MAX_Z_FACE:
|
||||
detail.z += detail.s;
|
||||
break;
|
||||
}
|
||||
unsigned char* bufferOut;
|
||||
int sizeOut;
|
||||
|
||||
|
@ -1510,7 +1533,8 @@ void deleteVoxelUnderCursor() {
|
|||
|
||||
VoxelDetail detail;
|
||||
float distance;
|
||||
if (voxels.findRayIntersection(origin, direction, detail, distance)) {
|
||||
BoxFace face;
|
||||
if (voxels.findRayIntersection(origin, direction, detail, distance, face)) {
|
||||
unsigned char* bufferOut;
|
||||
int sizeOut;
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ static bool findIntersection(float origin, float direction, float corner, float
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
|
||||
bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const {
|
||||
// handle the trivial case where the box contains the origin
|
||||
if (contains(origin)) {
|
||||
distance = 0;
|
||||
|
@ -105,14 +105,23 @@ bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct
|
|||
float axisDistance;
|
||||
if ((findIntersection(origin.x, direction.x, _corner.x, _size.x, axisDistance) && axisDistance >= 0 &&
|
||||
isWithin(origin.y + axisDistance*direction.y, _corner.y, _size.y) &&
|
||||
isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z)) ||
|
||||
(findIntersection(origin.y, direction.y, _corner.y, _size.y, axisDistance) && axisDistance >= 0 &&
|
||||
isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z))) {
|
||||
distance = axisDistance;
|
||||
face = direction.x > 0 ? MIN_X_FACE : MAX_X_FACE;
|
||||
return true;
|
||||
}
|
||||
if ((findIntersection(origin.y, direction.y, _corner.y, _size.y, axisDistance) && axisDistance >= 0 &&
|
||||
isWithin(origin.x + axisDistance*direction.x, _corner.x, _size.x) &&
|
||||
isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z)) ||
|
||||
(findIntersection(origin.z, direction.z, _corner.z, _size.z, axisDistance) && axisDistance >= 0 &&
|
||||
isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z))) {
|
||||
distance = axisDistance;
|
||||
face = direction.y > 0 ? MIN_Y_FACE : MAX_Y_FACE;
|
||||
return true;
|
||||
}
|
||||
if ((findIntersection(origin.z, direction.z, _corner.z, _size.z, axisDistance) && axisDistance >= 0 &&
|
||||
isWithin(origin.y + axisDistance*direction.y, _corner.y, _size.y) &&
|
||||
isWithin(origin.x + axisDistance*direction.x, _corner.x, _size.x))) {
|
||||
distance = axisDistance;
|
||||
face = direction.z > 0 ? MIN_Z_FACE : MAX_Z_FACE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -13,6 +13,15 @@
|
|||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
enum BoxFace {
|
||||
MIN_X_FACE,
|
||||
MAX_X_FACE,
|
||||
MIN_Y_FACE,
|
||||
MAX_Y_FACE,
|
||||
MIN_Z_FACE,
|
||||
MAX_Z_FACE
|
||||
};
|
||||
|
||||
class AABox
|
||||
{
|
||||
|
||||
|
@ -37,7 +46,7 @@ public:
|
|||
const glm::vec3& getCenter() const { return _center; };
|
||||
|
||||
bool contains(const glm::vec3& point) const;
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
||||
|
||||
private:
|
||||
glm::vec3 _corner;
|
||||
|
|
|
@ -605,6 +605,7 @@ public:
|
|||
glm::vec3 direction;
|
||||
VoxelNode*& node;
|
||||
float& distance;
|
||||
BoxFace& face;
|
||||
bool found;
|
||||
};
|
||||
|
||||
|
@ -612,7 +613,8 @@ bool findRayOperation(VoxelNode* node, void* extraData) {
|
|||
RayArgs* args = static_cast<RayArgs*>(extraData);
|
||||
AABox box = node->getAABox();
|
||||
float distance;
|
||||
if (!box.findRayIntersection(args->origin, args->direction, distance)) {
|
||||
BoxFace face;
|
||||
if (!box.findRayIntersection(args->origin, args->direction, distance, face)) {
|
||||
return false;
|
||||
}
|
||||
if (!node->isLeaf()) {
|
||||
|
@ -621,14 +623,16 @@ bool findRayOperation(VoxelNode* node, void* extraData) {
|
|||
if (!args->found || distance < args->distance) {
|
||||
args->node = node;
|
||||
args->distance = distance;
|
||||
args->face = face;
|
||||
args->found = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode*& node, float& distance)
|
||||
bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
VoxelNode*& node, float& distance, BoxFace& face)
|
||||
{
|
||||
RayArgs args = { origin / (float)TREE_SCALE, direction, node, distance };
|
||||
RayArgs args = { origin / (float)TREE_SCALE, direction, node, distance, face };
|
||||
recurseTreeWithOperation(findRayOperation, &args);
|
||||
return args.found;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,8 @@ public:
|
|||
void clearDirtyBit() { _isDirty = false; };
|
||||
unsigned long int getNodesChangedFromBitstream() const { return _nodesChangedFromBitstream; };
|
||||
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode*& node, float& distance);
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
VoxelNode*& node, float& distance, BoxFace& face);
|
||||
|
||||
// Note: this assumes the fileFormat is the HIO individual voxels code files
|
||||
void loadVoxelsFile(const char* fileName, bool wantColorRandomizer);
|
||||
|
|
Loading…
Reference in a new issue