Add explicit checks whenever we are accessing another scene graph node (closes #1831)

This commit is contained in:
Alexander Bock
2022-02-20 19:17:06 +01:00
parent 797a81dbe6
commit a6f048e342
12 changed files with 80 additions and 55 deletions

View File

@@ -117,11 +117,9 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
const Parameters p = codegen::bake<Parameters>(dictionary);
_start = p.startNode.value_or(_start);
_start.onChange([&]() { validateNodes(); });
addProperty(_start);
_end = p.endNode.value_or(_end);
_end.onChange([&]() { validateNodes(); });
addProperty(_end);
_lineColor = p.color.value_or(_lineColor);
@@ -203,15 +201,26 @@ void RenderableNodeLine::bindGL() {
}
void RenderableNodeLine::updateVertexData() {
SceneGraphNode* startNode = global::renderEngine->scene()->sceneGraphNode(_start);
SceneGraphNode* endNode = global::renderEngine->scene()->sceneGraphNode(_end);
if (!startNode || !endNode) {
LERRORC(
"RenderableNodeLine",
fmt::format(
"Could not find starting '{}' or ending '{}'",
_start.value(), _end.value()
)
);
return;
}
_vertexArray.clear();
// Update the positions of the nodes
_startPos = coordinatePosFromAnchorNode(
global::renderEngine->scene()->sceneGraphNode(_start)->worldPosition()
);
_endPos = coordinatePosFromAnchorNode(
global::renderEngine->scene()->sceneGraphNode(_end)->worldPosition()
);
_startPos = coordinatePosFromAnchorNode(startNode->worldPosition());
_endPos = coordinatePosFromAnchorNode(endNode->worldPosition());
_vertexArray.push_back(static_cast<float>(_startPos.x));
_vertexArray.push_back(static_cast<float>(_startPos.y));
@@ -235,9 +244,11 @@ void RenderableNodeLine::updateVertexData() {
unbindGL();
}
void RenderableNodeLine::render(const RenderData& data, RendererTasks&) {
void RenderableNodeLine::update(const UpdateData&) {
updateVertexData();
}
void RenderableNodeLine::render(const RenderData& data, RendererTasks&) {
_program->activate();
glm::dmat4 anchorTranslation(1.0);
@@ -278,19 +289,4 @@ void RenderableNodeLine::render(const RenderData& data, RendererTasks&) {
global::renderEngine->openglStateCache().resetLineState();
}
void RenderableNodeLine::validateNodes() {
if (!global::renderEngine->scene()->sceneGraphNode(_start)) {
LERROR(fmt::format(
"There is no scenegraph node with id {}, defaults to 'Root'", _start
));
_start = Root;
}
if (!global::renderEngine->scene()->sceneGraphNode(_end)) {
LERROR(fmt::format(
"There is no scenegraph node with id {}, defaults to 'Root'", _end
));
_end = Root;
}
}
} // namespace openspace

View File

@@ -62,8 +62,8 @@ private:
bool isReady() const override;
void updateVertexData();
void update(const UpdateData& data) override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
void validateNodes();
void unbindGL();
void bindGL();

View File

@@ -130,7 +130,7 @@ GlobeRotation::GlobeRotation(const ghoul::Dictionary& dictionary)
void GlobeRotation::findGlobe() {
SceneGraphNode* n = sceneGraphNode(_globe);
if (n->renderable() && dynamic_cast<RenderableGlobe*>(n->renderable())) {
if (n && n->renderable() && dynamic_cast<RenderableGlobe*>(n->renderable())) {
_globeNode = dynamic_cast<RenderableGlobe*>(n->renderable());
}
else {

View File

@@ -133,7 +133,7 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
void GlobeTranslation::fillAttachedNode() {
SceneGraphNode* n = sceneGraphNode(_globe);
if (n->renderable() && dynamic_cast<RenderableGlobe*>(n->renderable())) {
if (n && n->renderable() && dynamic_cast<RenderableGlobe*>(n->renderable())) {
_attachedNode = dynamic_cast<RenderableGlobe*>(n->renderable());
}
else {
@@ -142,7 +142,7 @@ void GlobeTranslation::fillAttachedNode() {
"Could not set attached node as it does not have a RenderableGlobe"
);
if (_attachedNode) {
// Reset the globe name to it's previous name
// Reset the globe name to its previous name
_globe = _attachedNode->identifier();
}
}

View File

@@ -2033,6 +2033,14 @@ void RenderableGlobe::calculateEclipseShadows(ghoul::opengl::ProgramObject& prog
SceneGraphNode* casterNode =
global::renderEngine->scene()->sceneGraphNode(caster);
if ((sourceNode == nullptr) || (casterNode == nullptr)) {
LERRORC(
"Renderableglobe",
"Invalid scenegraph node for the shadow's caster or shadow's receiver."
);
return;
}
const double sourceRadiusScale = std::max(
glm::compMax(sourceNode->scale()),
1.0
@@ -2043,14 +2051,6 @@ void RenderableGlobe::calculateEclipseShadows(ghoul::opengl::ProgramObject& prog
1.0
);
if ((sourceNode == nullptr) || (casterNode == nullptr)) {
LERRORC(
"Renderableglobe",
"Invalid scenegraph node for the shadow's caster or shadow's receiver."
);
return;
}
// First we determine if the caster is shadowing the current planet (all
// calculations in World Coordinates):
const glm::dvec3 planetCasterVec = casterPos - data.modelTransform.translation;

View File

@@ -608,10 +608,18 @@ void RingsComponent::update(const UpdateData& data) {
_textureIsDirty = false;
}
_sunPosition = glm::normalize(
global::renderEngine->scene()->sceneGraphNode("Sun")->worldPosition() -
data.modelTransform.translation
);
// @TODO (abock, 2022-02-20) This should be replaced with the more general light
// source solution that we are using in other places
SceneGraphNode* sun = global::renderEngine->scene()->sceneGraphNode("Sun");
if (sun) {
_sunPosition = glm::normalize(
sun->worldPosition() - data.modelTransform.translation
);
}
else {
// If the Sun node is not found, we assume the light source to be in the origin
_sunPosition = glm::normalize(-data.modelTransform.translation);
}
}
void RingsComponent::loadTexture() {
@@ -619,7 +627,6 @@ void RingsComponent::loadTexture() {
using namespace ghoul::opengl;
if (!_texturePath.value().empty()) {
std::unique_ptr<Texture> texture = TextureReader::ref().loadTexture(
absPath(_texturePath).string(),
1

View File

@@ -356,7 +356,13 @@ void ShadowComponent::end() {
void ShadowComponent::update(const UpdateData&) {
ZoneScoped
_sunPosition = global::renderEngine->scene()->sceneGraphNode("Sun")->worldPosition();
SceneGraphNode* sun = global::renderEngine->scene()->sceneGraphNode("Sun");
if (sun) {
_sunPosition = sun->worldPosition();
}
else {
_sunPosition = glm::dvec3(0.0);
}
glm::ivec2 renderingResolution = global::renderEngine->renderingResolution();
if (_dynamicDepthTextureRes && ((_shadowDepthTextureWidth != renderingResolution.x) ||

View File

@@ -226,8 +226,14 @@ void RenderableRings::update(const UpdateData& data) {
_textureIsDirty = false;
}
_sunPosition = global::renderEngine->scene()->sceneGraphNode("Sun")->worldPosition() -
data.modelTransform.translation;
SceneGraphNode* sun = global::renderEngine->scene()->sceneGraphNode("Sun");
if (sun) {
_sunPosition = sun->worldPosition() - data.modelTransform.translation;
}
else {
// If the Sun node does not exist, we assume the light source to be in the origin
_sunPosition = -data.modelTransform.translation;
}
}
void RenderableRings::loadTexture() {

View File

@@ -319,11 +319,14 @@ void RenderableModelProjection::update(const UpdateData& data) {
}
}
glm::dvec3 p =
global::renderEngine->scene()->sceneGraphNode("Sun")->worldPosition() -
data.modelTransform.translation;
_sunPosition = static_cast<glm::vec3>(p);
SceneGraphNode* sun = global::renderEngine->scene()->sceneGraphNode("Sun");
if (sun) {
_sunPosition = sun->worldPosition() - data.modelTransform.translation;
}
else {
// If the Sun node doesn't exist, we assume that the light source is in the origin
_sunPosition = -data.modelTransform.translation;
}
}
void RenderableModelProjection::imageProjectGPU(

View File

@@ -136,11 +136,19 @@ void RenderableDistanceLabel::update(const UpdateData&) {
// Update placement of label with transformation matrix
SceneGraphNode* startNode = RE.scene()->sceneGraphNode(nodeline->start());
glm::dvec3 start = startNode->worldPosition();
SceneGraphNode* endNode = RE.scene()->sceneGraphNode(nodeline->end());
glm::dvec3 end = endNode->worldPosition();
glm::dvec3 goalPos = start + (end - start) / 2.0;
_transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos);
if (startNode && endNode) {
glm::dvec3 start = startNode->worldPosition();
glm::dvec3 end = endNode->worldPosition();
glm::dvec3 goalPos = start + (end - start) / 2.0;
_transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos);
}
else {
LERROR(fmt::format(
"Could not find scene graph node {} or {}",
nodeline->start(), nodeline->end()
));
}
}
else {
LERROR(fmt::format("There is no scenegraph node with id {}", _nodelineId));

View File

@@ -2004,7 +2004,6 @@ bool SessionRecording::processCameraKeyframe(double now) {
Scene* scene = camera->parent()->scene();
const SceneGraphNode* n = scene->sceneGraphNode(_keyframesCamera[prevIdx].focusNode);
if (n) {
global::navigationHandler->orbitalNavigator().setFocusNode(n->identifier());
}