Created
December 6, 2025 16:32
-
-
Save CrosRoad95/8ddc3457f14bc0bb9072246391becdf9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| struct VisibilityContext { | |
| flecs::entity observer; | |
| flecs::entity target; | |
| float distanceSquared; | |
| }; | |
| template <glm::vec3 (*ObserverPosFn)(flecs::entity), glm::vec3 (*TargetPosFn)(flecs::entity), typename... Checks> | |
| struct VisibilityPipeline { | |
| private: | |
| std::tuple<Checks...> checks; | |
| public: | |
| VisibilityPipeline(Checks... c): checks(std::move(c)...) {} | |
| FORCEINLINE bool IsVisible(flecs::entity observer, flecs::entity target) const { | |
| VisibilityContext ctx {}; | |
| ctx.observer = observer; | |
| ctx.target = target; | |
| auto obsPos = ObserverPosFn(observer); | |
| auto tgtPos = TargetPosFn(target); | |
| ctx.distanceSquared = glm::distance(obsPos, tgtPos); | |
| return IsVisibleImpl(ctx, std::index_sequence_for<Checks...> {}); | |
| } | |
| template <typename Context> | |
| FORCEINLINE bool IsVisible(const Context &ctx) const { | |
| return IsVisibleImpl(ctx, std::index_sequence_for<Checks...> {}); | |
| } | |
| private: | |
| template <std::size_t... I, typename Context> | |
| FORCEINLINE bool IsVisibleImpl(const Context &ctx, std::index_sequence<I...>) const { | |
| return (... && std::get<I>(checks)(ctx)); | |
| } | |
| }; | |
| template <auto ObsFn, auto TgtFn, typename... Checks> | |
| FORCEINLINE auto CreateVisibilityPipeline(Checks... checks) { | |
| return VisibilityPipeline<ObsFn, TgtFn, Checks...>(std::move(checks)...); | |
| } | |
| struct DistanceCheck { | |
| float maxDistanceSq; | |
| FORCEINLINE bool operator()(const VisibilityContext &ctx) const { | |
| return ctx.distanceSquared <= maxDistanceSq; | |
| } | |
| }; | |
| template <typename Pipeline> | |
| struct SubPipeline { | |
| const Pipeline &subPipeline; | |
| // Constructor | |
| SubPipeline(const Pipeline &p): subPipeline(p) {} | |
| FORCEINLINE bool operator()(const VisibilityContext &ctx) const { | |
| return subPipeline.IsVisible(ctx.observer, ctx.target); | |
| } | |
| }; | |
| // Usage: | |
| glm::vec3 getPos1(flecs::entity e) { | |
| return glm::vec3 {0, 0, 0}; | |
| } | |
| glm::vec3 getPos2(flecs::entity e) { | |
| return glm::vec3 {10, 0, 0}; | |
| } | |
| VisibilityPipeline customPipeline = CreateVisibilityPipeline<getPos1, getPos2>(DistanceCheck {15}, DistanceCheck {12}); | |
| VisibilityPipeline customPipeline2 = CreateVisibilityPipeline<getPos1, getPos2>(SubPipeline {customPipeline}, DistanceCheck {9}); | |
| flecs::entity a; | |
| flecs::entity b; | |
| bool result = customPipeline2.IsVisible(a, b); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment