diff --git a/src/DrawingProgram/DrawingProgramCache.cpp b/src/DrawingProgram/DrawingProgramCache.cpp index 3f3315c..d5379fc 100644 --- a/src/DrawingProgram/DrawingProgramCache.cpp +++ b/src/DrawingProgram/DrawingProgramCache.cpp @@ -170,6 +170,19 @@ void DrawingProgramCache::traverse_bvh_run_function_recursive(const std::shared_ } } +CollabListType::ObjectInfoPtr DrawingProgramCache::get_front_object_colliding_with(const SCollision::ColliderCollection& cC) { + auto cCWorld = drawP.world.drawData.cam.c.collider_to_world, SCollision::ColliderCollection>(cC); + CollabListType::ObjectInfoPtr p; + traverse_bvh_run_function(cCWorld.bounds, [&](const std::shared_ptr& bvhNode, const std::vector& components) { + for(auto& c : components) { + if((!p || c->pos >= p->pos) && c->obj->collides_with_world_coords(drawP.world.drawData.cam.c, cCWorld)) + p = c; + } + return true; + }); + return p; +} + void DrawingProgramCache::preupdate_component(const CollabListType::ObjectInfoPtr& c) { auto parentBvhNode = c->obj->parentBvhNode.lock(); if(parentBvhNode) { diff --git a/src/DrawingProgram/DrawingProgramCache.hpp b/src/DrawingProgram/DrawingProgramCache.hpp index dffae37..8042fe7 100644 --- a/src/DrawingProgram/DrawingProgramCache.hpp +++ b/src/DrawingProgram/DrawingProgramCache.hpp @@ -66,8 +66,10 @@ class DrawingProgramCache { const std::vector& get_unsorted_component_list() const; const std::chrono::steady_clock::time_point& get_last_bvh_build_time() const; void clear_own_cached_surfaces(); - private: + CollabListType::ObjectInfoPtr get_front_object_colliding_with(const SCollision::ColliderCollection& cC); + + private: static std::unordered_set> nodesWithCachedSurfaces; void draw_cache_image_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::shared_ptr& bvhNode); diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index 50454b3..ce6c6f1 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -70,32 +70,36 @@ std::function&, std::vect return toRet; } -void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, bool onlyFrontObject) { - auto cCWorld = drawP.world.drawData.cam.c.collider_to_world, SCollision::ColliderCollection>(cC); +void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, bool frontObjectOnly) { std::unordered_set selectedComponents; - drawP.compCache.traverse_bvh_erase_function(cCWorld.bounds, erase_select_objects_in_bvh_func(selectedComponents, cC, cCWorld)); - if(onlyFrontObject && !selectedComponents.empty()) { - CollabListType::ObjectInfoPtr p = *std::max_element(selectedComponents.begin(), selectedComponents.end(), [](auto& a, auto& b) { - return a->pos < b->pos; - }); - selectedComponents.clear(); - selectedComponents.emplace(p); + if(frontObjectOnly) { + CollabListType::ObjectInfoPtr a = drawP.compCache.get_front_object_colliding_with(cC); + if(a) { + selectedComponents.emplace(a); + drawP.compCache.erase_component(a); + } + } + else { + auto cCWorld = drawP.world.drawData.cam.c.collider_to_world, SCollision::ColliderCollection>(cC); + drawP.compCache.traverse_bvh_erase_function(cCWorld.bounds, erase_select_objects_in_bvh_func(selectedComponents, cC, cCWorld)); } add_to_selection(selectedComponents); } -void DrawingProgramSelection::remove_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, bool onlyFrontObject) { +void DrawingProgramSelection::remove_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, bool frontObjectOnly) { auto cCWorld = drawP.world.drawData.cam.c.collider_to_world, SCollision::ColliderCollection>(cC); std::unordered_set selectedComponents; - cache.traverse_bvh_erase_function(cCWorld.bounds, erase_select_objects_in_bvh_func(selectedComponents, cC, cCWorld)); - if(onlyFrontObject && !selectedComponents.empty()) { - CollabListType::ObjectInfoPtr p = *std::max_element(selectedComponents.begin(), selectedComponents.end(), [](auto& a, auto& b) { - return a->pos < b->pos; - }); - selectedComponents.clear(); - selectedComponents.emplace(p); + if(frontObjectOnly) { + CollabListType::ObjectInfoPtr a = cache.get_front_object_colliding_with(cC); + if(a) { + selectedComponents.emplace(a); + cache.erase_component(a); + } + } + else { + cache.traverse_bvh_erase_function(cCWorld.bounds, erase_select_objects_in_bvh_func(selectedComponents, cC, cCWorld)); + cache.clear_own_cached_surfaces(); } - cache.clear_own_cached_surfaces(); std::erase_if(selectedSet, [&](auto& c) { return selectedComponents.contains(c); }); @@ -111,19 +115,6 @@ void DrawingProgramSelection::remove_from_cam_coord_collider_to_selection(const } } -CollabListType::ObjectInfoPtr DrawingProgramSelection::get_front_object_colliding_with(const SCollision::ColliderCollection& cC) { - auto cCWorld = drawP.world.drawData.cam.c.collider_to_world, SCollision::ColliderCollection>(cC); - CollabListType::ObjectInfoPtr p; - cache.traverse_bvh_run_function(cCWorld.bounds, [&](const std::shared_ptr& bvhNode, const std::vector& components) { - for(auto& c : components) { - if((!p || c->pos >= p->pos) && c->obj->collides_with_world_coords(drawP.world.drawData.cam.c, cCWorld)) - p = c; - } - return true; - }); - return p; -} - void DrawingProgramSelection::add_to_selection(const std::unordered_set& newSelection) { selectedSet.insert(newSelection.begin(), newSelection.end()); for(auto& obj : newSelection) @@ -241,6 +232,10 @@ void DrawingProgramSelection::commit_transform_selection() { set_to_selection(selectedSetTemp); } +CollabListType::ObjectInfoPtr DrawingProgramSelection::get_front_object_colliding_with(const SCollision::ColliderCollection& cC) { + return cache.get_front_object_colliding_with(cC); +} + void DrawingProgramSelection::invalidate_cache_at_optional_aabb_before_pos(const std::optional>& aabb, uint64_t placementToInvalidateAt) { cache.invalidate_cache_at_optional_aabb_before_pos(aabb, placementToInvalidateAt); } diff --git a/src/DrawingProgram/DrawingProgramSelection.hpp b/src/DrawingProgram/DrawingProgramSelection.hpp index da8c381..0218d07 100644 --- a/src/DrawingProgram/DrawingProgramSelection.hpp +++ b/src/DrawingProgram/DrawingProgramSelection.hpp @@ -7,8 +7,9 @@ class DrawingProgram; class DrawingProgramSelection { public: DrawingProgramSelection(DrawingProgram& initDrawP); - void add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, bool onlyFrontObject = false); - void remove_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, bool onlyFrontObject = false); + void add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, bool frontObjectOnly = false); + void remove_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC, bool frontObjectOnly = false); + CollabListType::ObjectInfoPtr get_front_object_colliding_with(const SCollision::ColliderCollection& cC); void deselect_all();