mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2025-12-31 16:30:07 -06:00
* Fix faulty log category and minor inconsistencies in GlobeTranslation and GlobeRotation * Small refactor * Remove unused return value from initialize function * Fill attached node in globetranslation initialize and initialize all timeline Should make the timeline translation work with globetranslations in other cases that the renderabletrails * Do the same type of change for rotation and scale * Update initialize function singatures * Initialize and update translation in trail before use * Screenspace renderable renderable - move initialize call to initialize * Refactor trail position calls to make it clearer what is being done * Call timeframe initialize functions in transform classes * Do not call update in trail position after all - it borks up the performance * GlobeTransform: Only fill attached node in init and onchange, and allow nodes without renderable * Correctly initialize the multi-transform types * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Alexander Bock <alexander.bock@liu.se> * Address code review comment * Update comments in renderabletrail --------- Co-authored-by: Alexander Bock <alexander.bock@liu.se>
312 lines
13 KiB
C++
312 lines
13 KiB
C++
/*****************************************************************************************
|
|
* *
|
|
* OpenSpace *
|
|
* *
|
|
* Copyright (c) 2014-2025 *
|
|
* *
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
|
* software and associated documentation files (the "Software"), to deal in the Software *
|
|
* without restriction, including without limitation the rights to use, copy, modify, *
|
|
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
|
* permit persons to whom the Software is furnished to do so, subject to the following *
|
|
* conditions: *
|
|
* *
|
|
* The above copyright notice and this permission notice shall be included in all copies *
|
|
* or substantial portions of the Software. *
|
|
* *
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
|
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
|
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
|
****************************************************************************************/
|
|
|
|
#include <modules/base/rendering/screenspacerenderablerenderable.h>
|
|
|
|
#include <openspace/camera/camera.h>
|
|
#include <openspace/rendering/renderable.h>
|
|
#include <openspace/scene/rotation.h>
|
|
#include <openspace/scene/scale.h>
|
|
#include <openspace/scene/translation.h>
|
|
#include <openspace/util/updatestructures.h>
|
|
|
|
namespace {
|
|
constexpr openspace::properties::Property::PropertyInfo TimeInfo = {
|
|
"Time",
|
|
"Time",
|
|
"The time (in J2000 seconds) that is used to calculate transformations and the "
|
|
"renderable's data."
|
|
};
|
|
|
|
constexpr openspace::properties::Property::PropertyInfo CameraPositionInfo = {
|
|
"CameraPosition",
|
|
"Camera Position",
|
|
"Specifies the location of the virtual camera that is showing the renderable "
|
|
"class. This position is provided in meters."
|
|
};
|
|
|
|
constexpr openspace::properties::Property::PropertyInfo CameraCenterInfo = {
|
|
"CameraCenter",
|
|
"Camera Center",
|
|
"The location of the camera's focal point. The camera's view direction will "
|
|
"always be pointing at the provided center location. This position is provided "
|
|
"in meters."
|
|
};
|
|
|
|
constexpr openspace::properties::Property::PropertyInfo CameraUpInfo = {
|
|
"CameraUp",
|
|
"Camera Up",
|
|
"The direction that is 'up' for the provided camera. This value does not have "
|
|
"any units."
|
|
};
|
|
|
|
constexpr openspace::properties::Property::PropertyInfo CameraFovInfo = {
|
|
"CameraFov",
|
|
"Camera Field of view",
|
|
"The camera's field of view in degrees."
|
|
};
|
|
|
|
const openspace::properties::PropertyOwner::PropertyOwnerInfo TransformInfo = {
|
|
"Transform",
|
|
"Transform",
|
|
"The Translation, Rotation, and Scale that are applied to the rendered "
|
|
"Renderable."
|
|
};
|
|
|
|
// This [ScreenSpaceRenderable](#core_screenspacerenderable) object can render any
|
|
// [Renderable](#renderable) type into an image that is shown in screen space. This
|
|
// can be used to display a rendered object as an overlay in front of the regular 3D
|
|
// rendering of the scene.
|
|
//
|
|
// Note that to use this `ScreenSpaceRenderable`, it might be necessary to specify the
|
|
// `size` parameter, which determines the resolution of the inset window into which
|
|
// the Renderable is rendered. For many use cases, the default should suffice,
|
|
// however.
|
|
//
|
|
// A possible use-case for the ScreenSpaceRenderable would be to show a 3D model of a
|
|
// spacecraft without the need to place it at a position in the 3D scene with the need
|
|
// to fly to that object to talk about it.
|
|
struct [[codegen::Dictionary(ScreenSpaceRenderableRenderable)]] Parameters {
|
|
std::optional<std::string> identifier [[codegen::private()]];
|
|
|
|
// The [Renderable](#renderable) object that is shown in this ScreenSpace object.
|
|
// See the list of creatable renderable objects for options that can be used for
|
|
// this type.
|
|
ghoul::Dictionary renderable [[codegen::reference("renderable")]];
|
|
|
|
struct Transform {
|
|
// The [Translation](#core_transform_translation) object that is used for the
|
|
// provided [Renderable](#renderable). If no value is specified, a
|
|
// [StaticTranslation](#base_transform_translation_static) is created instead.
|
|
std::optional<ghoul::Dictionary> translation
|
|
[[codegen::reference("core_transform_translation")]];
|
|
|
|
// The [Rotation](#core_transform_rotation) object that is used for the
|
|
// provided [Renderable](#renderable). If no value is specified, a
|
|
// [StaticRotation](#base_transform_rotation_static) is created instead.
|
|
std::optional<ghoul::Dictionary> rotation
|
|
[[codegen::reference("core_transform_rotation")]];
|
|
|
|
// The [Scale](#core_transform_scale) object that is used for the provided
|
|
// [Renderable](#renderable). If no value is specified, a
|
|
// [StaticScale](#base_transform_scale_static) is created instead.
|
|
std::optional<ghoul::Dictionary> scale
|
|
[[codegen::reference("core_transform_scale")]];
|
|
};
|
|
// The collection of transformations that are applied to the
|
|
// [Renderable](#renderable) before it is shown on screen.
|
|
std::optional<Transform> transform;
|
|
|
|
// Specifies the start date that is used to control the renderable and the
|
|
// transforms. If no value is specified the date of 2000 JAN 01 12:00:00 is used
|
|
// instead.
|
|
std::optional<std::string> time [[codegen::datetime()]];
|
|
|
|
// [[codegen::verbatim(CameraPositionInfo.description)]]
|
|
std::optional<glm::vec3> cameraPosition;
|
|
|
|
// [[codegen::verbatim(CameraCenterInfo.description)]]
|
|
std::optional<glm::vec3> cameraCenter;
|
|
|
|
// [[codegen::verbatim(CameraUpInfo.description)]]
|
|
std::optional<glm::vec3> cameraUp;
|
|
|
|
// [[codegen::verbatim(CameraFovInfo.description)]]
|
|
std::optional<float> cameraFov;
|
|
};
|
|
#include "screenspacerenderablerenderable_codegen.cpp"
|
|
} // namespace
|
|
|
|
namespace openspace {
|
|
|
|
documentation::Documentation ScreenSpaceRenderableRenderable::Documentation() {
|
|
return codegen::doc<Parameters>(
|
|
"base_screenspace_renderable",
|
|
ScreenSpaceFramebuffer::Documentation()
|
|
);
|
|
}
|
|
|
|
ScreenSpaceRenderableRenderable::ScreenSpaceRenderableRenderable(
|
|
const ghoul::Dictionary& dictionary)
|
|
: ScreenSpaceFramebuffer(dictionary)
|
|
, _time(
|
|
TimeInfo,
|
|
0.0,
|
|
-std::numeric_limits<double>::max(),
|
|
std::numeric_limits<double>::max()
|
|
)
|
|
, _cameraPosition(
|
|
CameraPositionInfo,
|
|
glm::vec3(0.f, 2.f, 2.f),
|
|
glm::vec3(-10.f, -10.f, -10.f),
|
|
glm::vec3(10.f, 10.f, 10.f)
|
|
)
|
|
, _cameraCenter(CameraCenterInfo, glm::vec3(0.f), glm::vec3(-1.f), glm::vec3(1.f))
|
|
, _cameraUp(CameraUpInfo, glm::vec3(0.f, 1.f, 0.f), glm::vec3(-1.f), glm::vec3(1.f))
|
|
, _cameraFov(CameraFovInfo, 45.f, 5.f, 90.f)
|
|
{
|
|
const Parameters p = codegen::bake<Parameters>(dictionary);
|
|
|
|
std::string identifier = p.identifier.value_or("ScreenSpaceRenderableRenderable");
|
|
setIdentifier(makeUniqueIdentifier(std::move(identifier)));
|
|
|
|
if (p.time.has_value()) {
|
|
_time = Time(*p.time).j2000Seconds();
|
|
}
|
|
_time.onChange([this]() { _previousTime = _time; });
|
|
addProperty(_time);
|
|
|
|
_cameraPosition = p.cameraPosition.value_or(_cameraPosition);
|
|
addProperty(_cameraPosition);
|
|
_cameraCenter = p.cameraCenter.value_or(_cameraCenter);
|
|
addProperty(_cameraCenter);
|
|
_cameraUp = p.cameraUp.value_or(_cameraUp);
|
|
addProperty(_cameraUp);
|
|
_cameraFov = p.cameraFov.value_or(_cameraFov);
|
|
addProperty(_cameraFov);
|
|
|
|
_renderable = Renderable::createFromDictionary(p.renderable);
|
|
addPropertySubOwner(_renderable.get());
|
|
|
|
_transform = ghoul::mm_unique_ptr<properties::PropertyOwner>(
|
|
new properties::PropertyOwner(TransformInfo)
|
|
);
|
|
addPropertySubOwner(_transform.get());
|
|
|
|
if (p.transform.has_value() && p.transform->translation.has_value()) {
|
|
_translation = Translation::createFromDictionary(*p.transform->translation);
|
|
}
|
|
else {
|
|
ghoul::Dictionary translation;
|
|
translation.setValue("Type", std::string("StaticTranslation"));
|
|
translation.setValue("Position", glm::dvec3(0.0));
|
|
_translation = Translation::createFromDictionary(translation);
|
|
}
|
|
_transform->addPropertySubOwner(_translation.get());
|
|
|
|
if (p.transform.has_value() && p.transform->rotation.has_value()) {
|
|
_rotation = Rotation::createFromDictionary(*p.transform->rotation);
|
|
}
|
|
else {
|
|
ghoul::Dictionary rotation;
|
|
rotation.setValue("Type", std::string("StaticRotation"));
|
|
rotation.setValue("Rotation", glm::dvec3(0.0));
|
|
_rotation = Rotation::createFromDictionary(rotation);
|
|
}
|
|
_transform->addPropertySubOwner(_rotation.get());
|
|
|
|
if (p.transform.has_value() && p.transform->scale.has_value()) {
|
|
_scale = Scale::createFromDictionary(*p.transform->scale);
|
|
}
|
|
else {
|
|
ghoul::Dictionary scale;
|
|
scale.setValue("Type", std::string("StaticScale"));
|
|
scale.setValue("Scale", 1.0);
|
|
_scale = Scale::createFromDictionary(scale);
|
|
}
|
|
_transform->addPropertySubOwner(_scale.get());
|
|
}
|
|
|
|
ScreenSpaceRenderableRenderable::~ScreenSpaceRenderableRenderable() {}
|
|
|
|
void ScreenSpaceRenderableRenderable::initialize() {
|
|
ScreenSpaceFramebuffer::initialize();
|
|
_translation->initialize();
|
|
_rotation->initialize();
|
|
_scale->initialize();
|
|
_renderable->initialize();
|
|
}
|
|
|
|
void ScreenSpaceRenderableRenderable::initializeGL() {
|
|
ScreenSpaceFramebuffer::initializeGL();
|
|
|
|
_renderable->initializeGL();
|
|
|
|
addRenderFunction([this]() {
|
|
glm::vec4 bg = _backgroundColor;
|
|
glClearColor(bg.r, bg.g, bg.b, bg.a);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
Camera camera;
|
|
// @TODO (2025-03-24, abock): These two lines can be removed once #3573 is fixed
|
|
camera.setPositionVec3(glm::dvec3(0.0, 0.0, 0.0));
|
|
camera.setRotation(glm::dvec3(0.0, 0.0, 0.0));
|
|
|
|
glm::mat4 view = glm::lookAt(
|
|
_cameraPosition.value(),
|
|
_cameraCenter.value(),
|
|
glm::normalize(_cameraUp.value())
|
|
);
|
|
camera.sgctInternal.setViewMatrix(view);
|
|
|
|
glm::mat4 proj = glm::perspectiveFov(
|
|
glm::radians(_cameraFov.value()),
|
|
_size.value().x,
|
|
_size.value().y,
|
|
0.1f,
|
|
20.f
|
|
);
|
|
camera.sgctInternal.setProjectionMatrix(proj);
|
|
|
|
openspace::RenderData renderData = {
|
|
.camera = camera,
|
|
.time = Time(_time),
|
|
.modelTransform = {
|
|
.translation = _translation->position(),
|
|
.rotation = _rotation->matrix(),
|
|
.scale = _scale->scaleValue()
|
|
}
|
|
};
|
|
RendererTasks tasks;
|
|
_renderable->render(renderData, tasks);
|
|
});
|
|
}
|
|
|
|
void ScreenSpaceRenderableRenderable::deinitializeGL() {
|
|
_renderable->deinitializeGL();
|
|
_renderable->deinitialize();
|
|
|
|
ScreenSpaceFramebuffer::deinitializeGL();
|
|
}
|
|
|
|
void ScreenSpaceRenderableRenderable::update() {
|
|
UpdateData updateData = {
|
|
.time = Time(_time),
|
|
.previousFrameTime = Time(_previousTime)
|
|
};
|
|
|
|
_translation->update(updateData);
|
|
updateData.modelTransform.translation = _translation->position();
|
|
|
|
_rotation->update(updateData);
|
|
updateData.modelTransform.rotation = _rotation->matrix();
|
|
|
|
_scale->update(updateData);
|
|
updateData.modelTransform.scale = _scale->scaleValue();
|
|
|
|
_renderable->update(updateData);
|
|
}
|
|
|
|
} // namespace openspace
|