From a797253f7e2ad84dc3df7b14c11abbd33d0dd877 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 27 Sep 2023 16:57:48 +0100 Subject: [PATCH] Added support to vsg::Builder for decorating created subgraphs with CullNode --- include/vsg/utils/Builder.h | 4 +++ src/vsg/utils/Builder.cpp | 54 ++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/include/vsg/utils/Builder.h b/include/vsg/utils/Builder.h index 391632045..a816ed6fd 100644 --- a/include/vsg/utils/Builder.h +++ b/include/vsg/utils/Builder.h @@ -57,6 +57,9 @@ namespace vsg vec4 color = {1.0f, 1.0f, 1.0f, 1.0f}; mat4 transform; + /// cullNode flag indicates whether a CullNode should decorate the creted subgraph + bool cullNode = false; + template void set(const t_box& bb) { @@ -122,6 +125,7 @@ namespace vsg ref_ptr instancePositions(const GeometryInfo& info, uint32_t& instanceCount); ref_ptr instanceColors(const GeometryInfo& info, uint32_t instanceCount); vec3 y_texcoord(const StateInfo& info) const; + ref_ptr decorateWithCullNodeIfRequired(const GeometryInfo& info, ref_ptr node) const; ref_ptr _flatShadedShaderSet; ref_ptr _phongShaderSet; diff --git a/src/vsg/utils/Builder.cpp b/src/vsg/utils/Builder.cpp index cb0db55c3..dc420730d 100644 --- a/src/vsg/utils/Builder.cpp +++ b/src/vsg/utils/Builder.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -203,6 +204,45 @@ vec3 Builder::y_texcoord(const StateInfo& info) const } } +ref_ptr Builder::decorateWithCullNodeIfRequired(const GeometryInfo& info, ref_ptr node) const +{ + if (info.cullNode) + { + auto cullNode = vsg::CullNode::create(); + cullNode->child = node; + + if (info.positions) + { + if (auto v3a = info.positions.cast()) + { + box bound; + for(auto& v : *v3a) + { + bound.add(v); + } + cullNode->bound.center = (bound.min + bound.max) * 0.5f; + cullNode->bound.radius = vsg::length(bound.max - bound.min) * 0.5 + vsg::length(info.dx + info.dy + info.dz); + } + else + { + // unable to compute bound so do not decorate with a CullNode. + return node; + } + } + else + { + cullNode->bound.center = info.position; + cullNode->bound.radius = vsg::length(info.dx + info.dy + info.dz); + } + + return cullNode; + } + else + { + return node; + } +} + ref_ptr Builder::createBox(const GeometryInfo& info, const StateInfo& stateInfo) { auto& subgraph = _boxes[info]; @@ -339,7 +379,7 @@ ref_ptr Builder::createBox(const GeometryInfo& info, const StateInfo& stat if (compileTraversal) compileTraversal->compile(scenegraph); - subgraph = scenegraph; + subgraph = decorateWithCullNodeIfRequired(info, scenegraph); return subgraph; } @@ -568,7 +608,7 @@ ref_ptr Builder::createCapsule(const GeometryInfo& info, const StateInfo& if (compileTraversal) compileTraversal->compile(scenegraph); - subgraph = scenegraph; + subgraph = decorateWithCullNodeIfRequired(info, scenegraph); return subgraph; } @@ -778,7 +818,7 @@ ref_ptr Builder::createCone(const GeometryInfo& info, const StateInfo& sta if (compileTraversal) compileTraversal->compile(scenegraph); - subgraph = scenegraph; + subgraph = decorateWithCullNodeIfRequired(info, scenegraph); return subgraph; } @@ -1025,7 +1065,7 @@ ref_ptr Builder::createCylinder(const GeometryInfo& info, const StateInfo& if (compileTraversal) compileTraversal->compile(scenegraph); - subgraph = scenegraph; + subgraph = decorateWithCullNodeIfRequired(info, scenegraph); return subgraph; } @@ -1128,7 +1168,7 @@ ref_ptr Builder::createDisk(const GeometryInfo& info, const StateInfo& sta if (compileTraversal) compileTraversal->compile(scenegraph); - subgraph = scenegraph; + subgraph = decorateWithCullNodeIfRequired(info, scenegraph); return subgraph; } @@ -1317,7 +1357,7 @@ ref_ptr Builder::createSphere(const GeometryInfo& info, const StateInfo& s if (compileTraversal) compileTraversal->compile(scenegraph); - subgraph = scenegraph; + subgraph = decorateWithCullNodeIfRequired(info, scenegraph); return subgraph; } @@ -1450,6 +1490,6 @@ ref_ptr Builder::createHeightField(const GeometryInfo& info, const StateIn if (compileTraversal) compileTraversal->compile(scenegraph); - subgraph = scenegraph; + subgraph = decorateWithCullNodeIfRequired(info, scenegraph); return subgraph; }