Skip to content

visualizer: adopt backend-neutral cScene3DNode (OSG+VSG coexistence)#1116

Open
tabgab wants to merge 4 commits into
topic/inet-vsgfrom
fix/osg-vsg-coexist
Open

visualizer: adopt backend-neutral cScene3DNode (OSG+VSG coexistence)#1116
tabgab wants to merge 4 commits into
topic/inet-vsgfrom
fix/osg-vsg-coexist

Conversation

@tabgab

@tabgab tabgab commented Jul 3, 2026

Copy link
Copy Markdown

What

Companion to omnetpp/omnetpp-dev topic/VSG (backend-neutral cScene3DNode, PR omnetpp/omnetpp-dev#5). Updates INET's OSG and VSG visualizers to the renderer-neutral scene-handle API so INET builds and runs against an OMNeT++ that contains both 3-D backends, with the renderer chosen per simulation.

How

  • Wrap OSG scene roots with omnetpp::createScene3DNode() when calling cOsgCanvas::setScene().
  • Recover the typed root via getOsgRoot() / getVsgRoot() instead of casting cScene3DNode directly to a scene-graph type.
  • Updated both visualizer trees:
    • OSG: SceneOsgVisualizer, SceneOsgEarthVisualizer, SceneOsgVisualizerBase, OsgScene, GeographicCoordinateSystem
    • VSG: SceneVsgVisualizer, VsgScene

Verified

Built against an OMNeT++ with both backends. From the same build: INET OSG showcase (showcases/visualizer/osg/networknode, oppqtenv-osg) and VSG showcases (vsgsignal, vsgsignal3d, vsglidar, vsgsignalwave, oppqtenv-vsg) each render on the correct backend.

Requires the omnetpp-dev topic/VSG change (PR omnetpp/omnetpp-dev#5) to build.

🤖 Generated with Claude Code


Open in Devin Review

Companion to the omnetpp-dev change that makes cScene3DNode a
renderer-neutral handle rather than an alias of osg::Node. Wrap OSG scene
roots with omnetpp::createScene3DNode() when calling cOsgCanvas::setScene(),
and recover the typed root via getOsgRoot()/getVsgRoot() instead of casting
cScene3DNode directly to a scene-graph type.

Updated both visualizer trees:
  - OSG:  SceneOsgVisualizer, SceneOsgEarthVisualizer, SceneOsgVisualizerBase,
          OsgScene, and GeographicCoordinateSystem (osgEarth map node lookup)
  - VSG:  SceneVsgVisualizer, VsgScene

Lets INET build and run against an OMNeT++ that contains both 3-D backends,
with the renderer selected per simulation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread src/inet/visualizer/vsg/scene/SceneVsgVisualizer.cc
tabgab and others added 3 commits July 3, 2026 16:24
Corrects the "VisualizationOsg and VisualizationVsg are mutually exclusive"
note (true only before the backend-neutral cScene3DNode change) and documents
that an OMNeT++ configured with both WITH_OSG=yes and WITH_VSG=yes contains
both 3D backends, selected per simulation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The feature description said VisualizationOsg and VisualizationVsg are
mutually exclusive; that is no longer true after the backend-neutral
cScene3DNode change. There is no `conflicts` between them, so both can be
enabled together in an OMNeT++ built with WITH_OSG + WITH_VSG, each scene
rendering on the backend its visualizer creates. (VisualizationVsg is still
initiallyEnabled=false, so enable it explicitly for coexistence.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nehandle.h

The five OSG source files adopted in this PR #include
"qtenv/osg/osgscenehandle.h", which lives under $(OMNETPP_ROOT)/src. That
include path was only added by the VisualizationVsg makefrag block (line 81),
so an OSG-only build (VisualizationOsg enabled, VisualizationVsg disabled —
the common existing configuration) could not find the header and failed to
compile. Add -I$(OMNETPP_ROOT)/src to the VisualizationOsg block, mirroring
the VSG block.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tabgab

tabgab commented Jul 3, 2026

Copy link
Copy Markdown
Author

Thanks for the analysis — went through all four findings. Summary: one real bug (now fixed + verified), three not actionable. Details below.

1. OSG-only build failure (missing include path) — fixed in 6d3244880e

Confirmed and correct. The five OSG source files adopted in this PR now #include "qtenv/osg/osgscenehandle.h" (which lives under $(OMNETPP_ROOT)/src), but that include path was only added by the VisualizationVsg makefrag block (src/makefrag:81), not the VisualizationOsg block. So an OSG-only build (VisualizationOsg enabled, VisualizationVsg disabled — the common existing configuration) could not find the header.

Fix: add CFLAGS += -I$(OMNETPP_ROOT)/src to the VisualizationOsg block, mirroring the VSG one.

Verified with an actual OSG-only build from a clean checkout (VisualizationOsg enabled, VisualizationVsg disabled): make MODE=release completes with exit 0, all OSG scene visualizers compile (including the five that include the header), libINET.dylib links, and there are no osgscenehandle.h not-found errors. My earlier verification missed this because it was built with both features enabled, where the VSG block's -I masked the gap.

2. Null-safety at SceneVsgVisualizer.cc:42 — verified safe (see resolved thread)

omnetpp::getVsgRoot() (omnetpp-dev src/qtenv/vsg/vsgscenehandle.h) is:

return (node && node->getBackendType() == cScene3DNode::BACKEND_VSG)
           ? static_cast<VsgScene3DNode *>(node)->getRoot()
           : vsg::ref_ptr<vsg::Group>{};

The node && short-circuit returns an empty ref_ptr for a null (or wrong-backend) argument, so it never dereferences null. The null path ends in the existing if (topLevelScene == nullptr) throw cRuntimeError(...) — a clean error, not a crash. It is also stricter than the pre-PR code, which had no backend-type check.

3. OsgGeographicCoordinateSystem reads the scene at INITSTAGE_LOCAL — not a regression

The pre-PR code read the scene at the same stage; the getOsgRoot indirection does not change initialization order. No change needed. (A null scene here would surface as the existing "Could not find map node in the scene" cRuntimeError, same as before.)

4. getOsgRoot must return the full scene-graph root for findMapNode — correct by design

createScene3DNode(node) wraps node in OsgScene3DNode, which stores it verbatim, and getOsgRoot() returns that same pointer. So getOsgRoot(getOsgCanvas()->getScene()) yields the identical TopLevelScene root that SceneOsgEarthVisualizer::initializeScene() attaches the map scene to — findMapNode traverses the correct subtree, and no wrapper node is interposed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant