From 7ff8b84f4cca08fd342e03c4eaf8aee58f5f8bfc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 9 May 2013 10:46:52 -0700 Subject: [PATCH] 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. --- interface/src/VoxelSystem.cpp | 5 +++-- interface/src/VoxelSystem.h | 3 ++- interface/src/main.cpp | 36 +++++++++++++++++++++++++----- libraries/voxels/src/AABox.cpp | 19 +++++++++++----- libraries/voxels/src/AABox.h | 11 ++++++++- libraries/voxels/src/VoxelTree.cpp | 10 ++++++--- libraries/voxels/src/VoxelTree.h | 3 ++- 7 files changed, 68 insertions(+), 19 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index ac97e7fcfe..6f2bbc24f3 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -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; diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 4476ca9fe2..3c95edb6ae 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -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; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 23a65fc405..2a1eb91e75 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -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; diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index d253167bc6..c26e73e12a 100644 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -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; diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index 2b75affdae..63d586de22 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -13,6 +13,15 @@ #include +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; diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index daf2e01a72..bb55f01bc2 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -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(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; } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 319b4aed95..5574ca7602 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -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);