Skip to content

Commit

Permalink
[octree] Make neighbor return std::optional<std::shared_ptr<Cube>>
Browse files Browse the repository at this point in the history
  • Loading branch information
movabo committed May 6, 2021
1 parent 5ebfa57 commit 9dba059
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 16 deletions.
4 changes: 2 additions & 2 deletions include/inexor/vulkan-renderer/world/cube.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include <spdlog/spdlog.h>

#include <array>
#include <functional>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <stack>
Expand Down Expand Up @@ -158,7 +158,7 @@ class Cube : public std::enable_shared_from_this<Cube> {
/// Get the neighbor of this cube.
/// @param axis The axis on which to get the neighboring cube
/// @param direction Whether to get the cube which is above or below this cube on the selected axis
[[nodiscard]] std::weak_ptr<Cube> neighbor(NeighborAxis axis, NeighborDirection direction);
[[nodiscard]] std::optional<std::shared_ptr<Cube>> neighbor(NeighborAxis axis, NeighborDirection direction);
};

} // namespace inexor::vulkan_renderer::world
24 changes: 18 additions & 6 deletions src/vulkan-renderer/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,24 @@ void Application::load_octree_geometry() {

std::shared_ptr<world::Cube> test = cube->children()[4]->children()[3]->children()[3];
test->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::X, world::Cube::NeighborDirection::POSITIVE).lock()->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::X, world::Cube::NeighborDirection::NEGATIVE).lock()->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::Y, world::Cube::NeighborDirection::POSITIVE).lock()->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::Y, world::Cube::NeighborDirection::NEGATIVE).lock()->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::Z, world::Cube::NeighborDirection::POSITIVE).lock()->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::Z, world::Cube::NeighborDirection::NEGATIVE).lock()->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::X, world::Cube::NeighborDirection::POSITIVE)
.value()
->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::X, world::Cube::NeighborDirection::NEGATIVE)
.value()
->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::Y, world::Cube::NeighborDirection::POSITIVE)
.value()
->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::Y, world::Cube::NeighborDirection::NEGATIVE)
.value()
->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::Z, world::Cube::NeighborDirection::POSITIVE)
.value()
->set_type(world::Cube::Type::SOLID);
test->neighbor(world::Cube::NeighborAxis::Z, world::Cube::NeighborDirection::NEGATIVE)
.value()
->set_type(world::Cube::Type::SOLID);

for (const auto &polygons : cube->polygons(true)) {
for (const auto &triangle : *polygons) {
Expand Down
16 changes: 8 additions & 8 deletions src/vulkan-renderer/world/cube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ void Cube::rotate<3>(const RotationAxis::Type &axis) {

Cube::Cube(const float size, const glm::vec3 &position) : m_size(size), m_position(position) {}

Cube::Cube(std::weak_ptr<Cube> parent, uint8_t index, const float size, const glm::vec3 &position) : Cube(size, position) {
Cube::Cube(std::weak_ptr<Cube> parent, uint8_t index, const float size, const glm::vec3 &position)
: Cube(size, position) {
m_parent = std::move(parent);
m_index = index;
}
Expand Down Expand Up @@ -423,7 +424,7 @@ std::vector<PolygonCache> Cube::polygons(const bool update_invalid) const {
collect(*this);
return polygons;
}
std::weak_ptr<Cube> Cube::neighbor(const NeighborAxis axis, const NeighborDirection direction) {
std::optional<std::shared_ptr<Cube>> Cube::neighbor(NeighborAxis axis, NeighborDirection direction) {
assert(!is_root());

// Each axis only requires information and manipulation of one (relevant) bit to find the neighbor.
Expand All @@ -443,13 +444,12 @@ std::weak_ptr<Cube> Cube::neighbor(const NeighborAxis axis, const NeighborDirect
// The relevant bit denotes whether `m_parent` and `this` share a face on the upper side of the relevant axis.
// If they share one and also the user wants to go in the positive direction, then the neighbor is not a sibling.
// (Same for opposite, i.e. share face on lower side and going negative direction.)
if (this_bit && direction == NeighborDirection::NEGATIVE
|| !this_bit && direction == NeighborDirection::POSITIVE) {
if (this_bit && direction == NeighborDirection::NEGATIVE || !this_bit && direction == NeighborDirection::POSITIVE) {
// The demanded neighbor is a sibling! Return the neighboring sibling.
return parent->m_children[toggle_bit(index)];
}
if (parent->is_root()) {
return std::weak_ptr<Cube>();
return std::nullopt;
}
// the neighbor is further away than a sibling

Expand All @@ -465,7 +465,7 @@ std::weak_ptr<Cube> Cube::neighbor(const NeighborAxis axis, const NeighborDirect
while (get_bit(p_index) == this_bit) {
parent = parent->m_parent.lock();
if (parent->is_root()) {
return std::weak_ptr<Cube>();
return std::nullopt;
}
p_index = parent->m_index.value();
history.push(p_index);
Expand All @@ -478,13 +478,13 @@ std::weak_ptr<Cube> Cube::neighbor(const NeighborAxis axis, const NeighborDirect
while (!history.empty()) {
if (child->m_type != Type::OCTANT) {
// The neighbor is larger but still a neighbor!
return std::weak_ptr<Cube>(child);
return std::shared_ptr<Cube>(child);
}
child = child->m_children[toggle_bit(history.top())];
history.pop();
}

// We found a same-sized neighbor!
return std::weak_ptr<Cube>(child);
return std::shared_ptr<Cube>(child);
}
} // namespace inexor::vulkan_renderer::world

0 comments on commit 9dba059

Please sign in to comment.