Recieve two textures in Openspace and Send camera matrix

This commit is contained in:
mariaBrunned
2024-06-03 15:24:31 -04:00
parent d67cabf578
commit 3d78e698e7
13 changed files with 770 additions and 10 deletions

View File

@@ -6,7 +6,7 @@ local Spout = {
Identifier = "Spouty",
Parent = transforms.SolarSystemBarycenter.Identifier,
Renderable = {
Type = "RenderablePlaneSpout",
Type = "RenderableVolumeYt",
Size = 3.0E11,
Origin = "Center",
Billboard = true

View File

@@ -54,6 +54,7 @@ set(HEADER_FILES
rendering/renderablenodearrow.h
rendering/renderablenodeline.h
rendering/renderableplane.h
rendering/renderablevolumeyt.h
rendering/renderableplaneimagelocal.h
rendering/renderableplaneimageonline.h
rendering/renderableplanetimevaryingimage.h
@@ -116,6 +117,7 @@ set(SOURCE_FILES
rendering/renderablenodearrow.cpp
rendering/renderablenodeline.cpp
rendering/renderableplane.cpp
rendering/renderablevolumeyt.cpp
rendering/renderableplaneimagelocal.cpp
rendering/renderableplaneimageonline.cpp
rendering/renderableplanetimevaryingimage.cpp

View File

@@ -61,6 +61,7 @@
#include <modules/base/rendering/renderableplanetimevaryingimage.h>
#include <modules/base/rendering/renderableprism.h>
#include <modules/base/rendering/renderabletimevaryingsphere.h>
#include <modules/base/rendering/renderablevolumeyt.h> // yt
#include <modules/base/rendering/screenspacedashboard.h>
#include <modules/base/rendering/screenspaceimagelocal.h>
#include <modules/base/rendering/screenspaceimageonline.h>
@@ -164,6 +165,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
fRenderable->registerClass<RenderableSphericalGrid>("RenderableSphericalGrid");
fRenderable->registerClass<RenderableTrailOrbit>("RenderableTrailOrbit");
fRenderable->registerClass<RenderableTrailTrajectory>("RenderableTrailTrajectory");
fRenderable->registerClass<RenderableVolumeYt>("RenderableVolumeYt"); // yt
ghoul::TemplateFactory<Translation>* fTranslation =
FactoryManager::ref().factory<Translation>();
@@ -250,6 +252,7 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
RenderableTimeVaryingSphere::Documentation(),
RenderableTrailOrbit::Documentation(),
RenderableTrailTrajectory::Documentation(),
RenderableVolumeYt::Documentation(), // yt
ScreenSpaceDashboard::Documentation(),
ScreenSpaceFramebuffer::Documentation(),

View File

@@ -42,12 +42,12 @@ namespace ghoul::opengl {
namespace openspace {
struct RenderData;
struct UpdateData;
struct RenderData;
struct UpdateData;
namespace documentation { struct Documentation; }
namespace documentation { struct Documentation; }
struct LinePoint;
struct LinePoint;
class RenderablePlane : public Renderable {
public:

View File

@@ -0,0 +1,401 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2024 *
* *
* 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/renderablevolumeyt.h>
#include <modules/base/basemodule.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h> // from renderablespout.cpp
#include <ghoul/misc/defer.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
#include <ghoul/glm.h>
#include <glm/gtx/string_cast.hpp>
#include <optional>
#include <variant>
// Debug purposes
#include <iostream>
using namespace std;
namespace {
constexpr std::array<const char*, 6> UniformNames = {
"modelViewProjection", "modelViewTransform", "colorTexture", "opacity",
"mirrorBackside", "multiplyColor"
};
enum BlendMode {
Normal = 0,
Additive
};
constexpr openspace::properties::Property::PropertyInfo BillboardInfo = {
"Billboard",
"Billboard mode",
"This value specifies whether the plane is a billboard, which means that it is "
"always facing the camera. If this is false, it can be oriented using other "
"transformations",
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo MirrorBacksideInfo = {
"MirrorBackside",
"Mirror backside of image plane",
"If this value is set to false, the image plane will not be mirrored when "
"looking from the backside. This is usually desirable when the image shows "
"data at a specific location, but not if it is displaying text for example",
// @VISIBILITY(2.67)
openspace::properties::Property::Visibility::User
};
constexpr openspace::properties::Property::PropertyInfo SizeInfo = {
"Size",
"Size (in meters)",
"This value specifies the size of the plane in meters",
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo AutoScaleInfo = {
"AutoScale",
"Auto Scale",
"When true, the plane will automatically adjust in size to match the aspect "
"ratio of the content. Otherwise it will remain in the given size."
};
constexpr openspace::properties::Property::PropertyInfo BlendModeInfo = {
"BlendMode",
"Blending Mode",
"This determines the blending mode that is applied to this plane",
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo MultiplyColorInfo = {
"MultiplyColor",
"Multiply Color",
"If set, the plane's texture is multiplied with this color. Useful for applying "
"a color grayscale images",
openspace::properties::Property::Visibility::User
};
struct [[codegen::Dictionary(RenderablePlane)]] Parameters {
// [[codegen::verbatim(BillboardInfo.description)]]
std::optional<bool> billboard;
// [[codegen::verbatim(MirrorBacksideInfo.description)]]
std::optional<bool> mirrorBackside;
// [[codegen::verbatim(SizeInfo.description)]]
std::variant<float, glm::vec2> size;
enum class [[codegen::map(BlendMode)]] BlendMode {
Normal,
Additive
};
// [[codegen::verbatim(BlendModeInfo.description)]]
std::optional<BlendMode> blendMode;
// [[codegen::verbatim(MultiplyColorInfo.description)]]
std::optional<glm::vec3> multiplyColor [[codegen::color()]];
std::optional<std::string> spoutName; // yt
};
#include "renderableplane_codegen.cpp"
} // namespace
namespace openspace {
documentation::Documentation RenderableVolumeYt::Documentation() {
return codegen::doc<Parameters>("yt_renderable_volume");
}
RenderableVolumeYt::RenderableVolumeYt(const ghoul::Dictionary& dictionary)
: Renderable(dictionary, { .automaticallyUpdateRenderBin = false })
, _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown)
, _billboard(BillboardInfo, false)
, _mirrorBackside(MirrorBacksideInfo, false)
, _size(SizeInfo, glm::vec2(10.f), glm::vec2(0.f), glm::vec2(1e25f))
, _autoScale(AutoScaleInfo, false)
, _multiplyColor(MultiplyColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
, _spoutReceiver(*this, dictionary, "color")
, _spoutReceiver_depth(*this, dictionary, "depth")
{
const Parameters p = codegen::bake<Parameters>(dictionary);
addProperty(Fadeable::_opacity);
if (std::holds_alternative<float>(p.size)) {
_size = glm::vec2(std::get<float>(p.size));
}
else {
_size = std::get<glm::vec2>(p.size);
}
_billboard = p.billboard.value_or(_billboard);
_mirrorBackside = p.mirrorBackside.value_or(_mirrorBackside);
_blendMode.addOptions({
{ static_cast<int>(BlendMode::Normal), "Normal" },
{ static_cast<int>(BlendMode::Additive), "Additive"}
});
_blendMode.onChange([this]() {
BlendMode m = static_cast<BlendMode>(_blendMode.value());
switch (m) {
case BlendMode::Normal:
setRenderBinFromOpacity();
break;
case BlendMode::Additive:
setRenderBin(Renderable::RenderBin::PreDeferredTransparent);
break;
}
});
_opacity.onChange([this]() {
if (_blendMode == static_cast<int>(BlendMode::Normal)) {
setRenderBinFromOpacity();
}
});
if (p.blendMode.has_value()) {
_blendMode = codegen::map<BlendMode>(*p.blendMode);
}
_multiplyColor = p.multiplyColor.value_or(_multiplyColor);
_multiplyColor.setViewOption(properties::Property::ViewOptions::Color);
addProperty(_billboard);
_size.setExponent(15.f);
addProperty(_size);
_size.onChange([this](){ _planeIsDirty = true; });
addProperty(_autoScale);
addProperty(_multiplyColor);
setBoundingSphere(glm::compMax(_size.value()));
}
bool RenderableVolumeYt::isReady() const {
return _shader != nullptr;
}
void RenderableVolumeYt::initializeGL() {
ZoneScoped;
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
createPlane();
_shader = BaseModule::ProgramObjectManager.request(
"Plane_yt",
[]() -> std::unique_ptr<ghoul::opengl::ProgramObject> {
return global::renderEngine->buildRenderProgram(
"Plane_yt",
absPath("${MODULE_BASE}/shaders/plane_vs.glsl"),
absPath("${MODULE_BASE}/shaders/plane_fs_yt.glsl")
);
}
);
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
}
void RenderableVolumeYt::deinitializeGL() {
ZoneScoped;
glDeleteVertexArrays(1, &_quad);
_quad = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
BaseModule::ProgramObjectManager.release(
"Plane_yt",
[](ghoul::opengl::ProgramObject* p) {
global::renderEngine->removeRenderProgram(p);
}
);
_shader = nullptr;
}
void RenderableVolumeYt::render(const RenderData& data, RendererTasks&) {
ZoneScoped;
_shader->activate();
_shader->setUniform(_uniformCache.opacity, opacity());
_shader->setUniform(_uniformCache.mirrorBackside, _mirrorBackside);
glm::dvec3 objectPositionWorld = glm::dvec3(
glm::translate(
glm::dmat4(1.0),
data.modelTransform.translation) * glm::dvec4(0.0, 0.0, 0.0, 1.0)
);
glm::dvec3 normal = glm::normalize(data.camera.positionVec3() - objectPositionWorld);
glm::dvec3 newRight = glm::normalize(
glm::cross(data.camera.lookUpVectorWorldSpace(), normal)
);
glm::dvec3 newUp = glm::cross(normal, newRight);
glm::dmat4 cameraOrientedRotation = glm::dmat4(1.0);
cameraOrientedRotation[0] = glm::dvec4(newRight, 0.0);
cameraOrientedRotation[1] = glm::dvec4(newUp, 0.0);
cameraOrientedRotation[2] = glm::dvec4(normal, 0.0);
const glm::dmat4 rotationTransform = _billboard ?
cameraOrientedRotation :
glm::dmat4(data.modelTransform.rotation);
auto [modelTransform, modelViewTransform, modelViewProjectionTransform] =
calcAllTransforms(data, { .rotation = rotationTransform });
_shader->setUniform(
_uniformCache.modelViewProjection,
glm::mat4(modelViewProjectionTransform)
);
_shader->setUniform(_uniformCache.modelViewTransform, glm::mat4(modelViewTransform));
ghoul::opengl::TextureUnit unit;
unit.activate();
//bindTexture(); // Binds the texture to OpenSpace
// Recive the color texture
if (_spoutReceiver.isReceiving()) {
_spoutReceiver.saveGLTextureState();
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(_spoutReceiver.spoutTexture()));
}
defer { unbindTexture(); };
_shader->setUniform(_uniformCache.colorTexture, unit);
_shader->setUniform(_uniformCache.multiplyColor, _multiplyColor);
ghoul::opengl::TextureUnit depth_unit;
depth_unit.activate();
// Recive the depth texture
if (_spoutReceiver_depth.isReceiving()) {
_spoutReceiver_depth.saveGLTextureState();
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(_spoutReceiver_depth.spoutTexture()));
}
defer{ unbindTexture(); };
_shader->setUniform("depthTexture", depth_unit);
bool additiveBlending = (_blendMode == static_cast<int>(BlendMode::Additive));
if (additiveBlending) {
glDepthMask(false);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
glDisable(GL_CULL_FACE);
glBindVertexArray(_quad);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
if (additiveBlending) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(true);
}
_shader->deactivate();
}
void RenderableVolumeYt::bindTexture() {
// Function from the renderableplanespout.cpp file
if (_spoutReceiver.isReceiving()) {
_spoutReceiver.saveGLTextureState();
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(_spoutReceiver.spoutTexture()));
//cout << "`\nglBindTexture: Texture";
/*_spoutReceiver.saveGLTextureState();
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(_spoutReceiver.spoutTexture()));*/
//cout << "\nglBindTexture: Depth values";
}
else {
//RenderableVolumeYt::bindTexture(); // Crashes with a stack overflow error
}
}
void RenderableVolumeYt::unbindTexture() {
if (_spoutReceiver.isReceiving()) {
_spoutReceiver.restoreGLTextureState();
}
else {
//RenderableVolumeYt::unbindTexture(); // Crashes with a stack overflow error
}
}
void RenderableVolumeYt::update(const UpdateData&) {
ZoneScoped;
if (_shader->isDirty()) {
_shader->rebuildFromFile();
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
}
if (_planeIsDirty) {
createPlane();
}
_spoutReceiver.updateReceiver(); // yt
}
void RenderableVolumeYt::createPlane() {
const GLfloat sizeX = _size.value().x;
const GLfloat sizeY = _size.value().y;
const GLfloat vertexData[] = {
// x y z w s t
-sizeX, -sizeY, 0.f, 0.f, 0.f, 0.f,
sizeX, sizeY, 0.f, 0.f, 1.f, 1.f,
-sizeX, sizeY, 0.f, 0.f, 0.f, 1.f,
-sizeX, -sizeY, 0.f, 0.f, 0.f, 0.f,
sizeX, -sizeY, 0.f, 0.f, 1.f, 0.f,
sizeX, sizeY, 0.f, 0.f, 1.f, 1.f
};
glBindVertexArray(_quad);
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, nullptr);
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(GLfloat) * 6,
reinterpret_cast<void*>(sizeof(GLfloat) * 4)
);
glBindVertexArray(0);
}
} // namespace openspace

View File

@@ -0,0 +1,108 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2024 *
* *
* 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. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_BASE___RENDERABLEVOLUMEYT___H__
#define __OPENSPACE_MODULE_BASE___RENDERABLEVOLUMEYT___H__
#ifdef WIN32
#include <openspace/rendering/renderable.h>
#include <modules/base/rendering/renderableplane.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/vector/vec2property.h>
#include <openspace/properties/vector/vec3property.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/uniformcache.h>
#include <modules/spout/spoutwrapper.h>
namespace ghoul::filesystem { class File; }
namespace ghoul::opengl {
class ProgramObject;
class Texture;
} // namespace ghoul::opengl
namespace openspace {
struct RenderData;
struct UpdateData;
namespace documentation { struct Documentation; }
struct LinePoint;
class RenderableVolumeYt : public Renderable {
public:
RenderableVolumeYt(const ghoul::Dictionary& dictionary);
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
void update(const UpdateData& data) override;
static documentation::Documentation Documentation();
protected:
virtual void bindTexture();
virtual void unbindTexture();
void createPlane();
properties::OptionProperty _blendMode;
properties::BoolProperty _billboard;
properties::BoolProperty _mirrorBackside;
properties::Vec2Property _size;
properties::BoolProperty _autoScale;
properties::Vec3Property _multiplyColor;
ghoul::opengl::ProgramObject* _shader = nullptr;
GLuint _quad = 0;
GLuint _vertexPositionBuffer = 0;
private:
bool _planeIsDirty = false;
UniformCache(modelViewProjection, modelViewTransform, colorTexture, opacity,
mirrorBackside, multiplyColor) _uniformCache;
// -------------------- yt ------------------
spout::SpoutReceiverPropertyProxy _spoutReceiver; // color texture
spout::SpoutReceiverPropertyProxy _spoutReceiver_depth; // depth
// -------------------- end ------------------
};
} // namespace openspace
#endif // WIN32
#endif // __OPENSPACE_MODULE_BASE___RENDERABLEVOLUMEYT___H__

View File

@@ -0,0 +1,74 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2024 *
* *
* 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 "fragment.glsl"
in vec4 vs_gPosition;
in vec3 vs_gNormal;
in float vs_screenSpaceDepth;
in vec2 vs_st;
uniform sampler2D colorTexture;
uniform float opacity = 1.0;
uniform bool mirrorBackside = true;
uniform vec3 multiplyColor;
uniform sampler2D depthTexture;
Fragment getFragment() {
Fragment frag;
if (gl_FrontFacing) {
frag.color = texture(colorTexture, vs_st);
}
else {
if (mirrorBackside) {
frag.color = texture(colorTexture, vec2(1.0 - vs_st.s, vs_st.t));
}
else {
frag.color = texture(colorTexture, vs_st);
}
}
frag.color.rgb *= multiplyColor;
frag.color.a *= opacity;
if (frag.color.a == 0.0) {
discard;
}
frag.depth = texture(depthTexture, vs_st).r;
if (frag.depth == 0.0) {
discard;
}
frag.depth = frag.depth;
//frag.color += texture(depthTexture, vs_st);
// G-Buffer
frag.gPosition = vs_gPosition;
frag.gNormal = vec4(vs_gNormal, 1.0);
return frag;
}

View File

@@ -51,6 +51,7 @@ set(HEADER_FILES
include/topics/topic.h
include/topics/triggerpropertytopic.h
include/topics/versiontopic.h
include/topics/camerainfotopic.h
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -80,6 +81,7 @@ set(SOURCE_FILES
src/topics/topic.cpp
src/topics/triggerpropertytopic.cpp
src/topics/versiontopic.cpp
src/topics/camerainfotopic.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})

View File

@@ -0,0 +1,56 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2024 *
* *
* 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. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_SERVER___CAMERAINFOTOPIC___H__
#define __OPENSPACE_MODULE_SERVER___CAMERAINFOTOPIC___H__
#include <modules/server/include/topics/topic.h>
#include <chrono>
namespace openspace {
class CameraInfoTopic : public Topic {
public:
CameraInfoTopic();
~CameraInfoTopic() override;
void handleJson(const nlohmann::json& json) override;
bool isDone() const override;
private:
static constexpr int UnsetOnChangeHandle = -1;
void sendCameraData();
int _dataCallbackHandle = UnsetOnChangeHandle;
bool _isDone = false;
std::chrono::system_clock::time_point _lastUpdateTime;
glm::dvec3 _lastPosition = glm::dvec3(0);
std::chrono::milliseconds _cameraPositionUpdateTime = std::chrono::milliseconds(100);
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_SERVER___CAMERAINFOTOPIC___H__

View File

@@ -28,6 +28,7 @@
#include <modules/server/include/topics/bouncetopic.h>
#include <modules/server/include/topics/camerapathtopic.h>
#include <modules/server/include/topics/cameratopic.h>
#include <modules/server/include/topics/camerainfotopic.h>
#include <modules/server/include/topics/documentationtopic.h>
#include <modules/server/include/topics/enginemodetopic.h>
#include <modules/server/include/topics/eventtopic.h>
@@ -103,6 +104,7 @@ Connection::Connection(std::unique_ptr<ghoul::io::Socket> s, std::string address
_topicFactory.registerClass<CameraTopic>("camera");
_topicFactory.registerClass<CameraPathTopic>("cameraPath");
_topicFactory.registerClass<EventTopic>("event");
_topicFactory.registerClass<CameraInfoTopic>("cameraInfo");
}
void Connection::handleMessage(const std::string& message) {

View File

@@ -0,0 +1,107 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2024 *
* *
* 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/server/include/topics/camerainfotopic.h>
#include <modules/globebrowsing/globebrowsingmodule.h>
#include <modules/server/include/connection.h>
#include <modules/server/servermodule.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/engine/globals.h>
#include <openspace/properties/property.h>
#include <openspace/util/distanceconversion.h>
#include <ghoul/logging/logmanager.h>
#include <openspace/navigation/navigationhandler.h>
#include <openspace/camera/camera.h>
namespace {
constexpr std::string_view SubscribeEvent = "start_subscription";
} // namespace
using nlohmann::json;
namespace openspace {
CameraInfoTopic::CameraInfoTopic()
: _lastUpdateTime(std::chrono::system_clock::now())
{}
CameraInfoTopic::~CameraInfoTopic() {
if (_dataCallbackHandle != UnsetOnChangeHandle) {
ServerModule* module = global::moduleEngine->module<ServerModule>();
if (module) {
module->removePreSyncCallback(_dataCallbackHandle);
}
}
}
bool CameraInfoTopic::isDone() const {
return _isDone;
}
void CameraInfoTopic::handleJson(const nlohmann::json& json) {
std::string event = json.at("event").get<std::string>();
if (event != SubscribeEvent) {
_isDone = true;
return;
}
ServerModule* module = global::moduleEngine->module<ServerModule>();
_dataCallbackHandle = module->addPreSyncCallback(
[this]() {
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
if (now - _lastUpdateTime > _cameraPositionUpdateTime) {
sendCameraData();
_lastUpdateTime = std::chrono::system_clock::now();
}
}
);
}
void CameraInfoTopic::sendCameraData() {
glm::dmat4 camMat = global::navigationHandler->camera()->combinedViewMatrix();
// Send the rotation information
// Angles for rotating
// Get the view matrix and update it in the yt code
// Either make the function in yt public or remake it so the code calls on it instead
// Split the array to its primative values
// Turn them into a float?
nlohmann::json jsonData = {
//{ "matrix_x", &camMat[0][1]},
{ "matrix_row0", camMat[0][0]},
{ "matrix_row1", camMat[1][0]},
{ "matrix_row2", camMat[2][0]},
{ "matrix_row3", camMat[3][0]}
};
_connection->sendJson(wrappedPayload(jsonData));
}
} // namespace openspace

View File

@@ -339,10 +339,12 @@ const properties::Property::PropertyInfo& SpoutReceiverPropertyProxy::UpdateInfo
}
SpoutReceiverPropertyProxy::SpoutReceiverPropertyProxy(properties::PropertyOwner& owner,
const ghoul::Dictionary& dictionary)
const ghoul::Dictionary& dictionary,
std::string ownerIdentifier)
: _spoutName(NameReceiverInfo)
, _spoutSelection(SelectionInfo)
, _updateSelection(UpdateInfo)
, _subowner({ ownerIdentifier, ownerIdentifier })
{
if (dictionary.hasKey(NameReceiverInfo.identifier)) {
_spoutName = dictionary.value<std::string>(NameReceiverInfo.identifier);
@@ -352,7 +354,7 @@ SpoutReceiverPropertyProxy::SpoutReceiverPropertyProxy(properties::PropertyOwner
}
_spoutName.onChange([this]() { _isSpoutDirty = true; });
owner.addProperty(_spoutName);
_subowner.addProperty(_spoutName);
_spoutSelection.onChange([this]() {
if (_spoutName.value().empty() && _spoutSelection.value() == 0) {
@@ -364,7 +366,7 @@ SpoutReceiverPropertyProxy::SpoutReceiverPropertyProxy(properties::PropertyOwner
_spoutName = _spoutSelection.option().description;
});
_spoutSelection.addOption(0, "");
owner.addProperty(_spoutSelection);
_subowner.addProperty(_spoutSelection);
_updateSelection.onChange([this]() {
const std::vector<std::string> receiverList = spoutReceiverList();
@@ -385,7 +387,8 @@ SpoutReceiverPropertyProxy::SpoutReceiverPropertyProxy(properties::PropertyOwner
_spoutSelection = idx;
});
owner.addProperty(_updateSelection);
_subowner.addProperty(_updateSelection);
owner.addPropertySubOwner(_subowner);
_updateSelection.trigger();
}

View File

@@ -117,13 +117,15 @@ public:
static const properties::Property::PropertyInfo& UpdateInfoProperty();
SpoutReceiverPropertyProxy(properties::PropertyOwner& owner,
const ghoul::Dictionary& dictionary);
const ghoul::Dictionary& dictionary, std::string ownerIdentifier = "Spout");
virtual ~SpoutReceiverPropertyProxy();
bool updateReceiver() override;
void releaseReceiver() override;
private:
properties::PropertyOwner _subowner;
properties::StringProperty _spoutName;
properties::OptionProperty _spoutSelection;
properties::TriggerProperty _updateSelection;