Add rendering for mouse interaction (#3781)

This commit is contained in:
Alexander Bock
2025-09-07 15:36:46 +02:00
committed by GitHub
parent 8f12fa045f
commit 0e72a2cb0d
5 changed files with 215 additions and 14 deletions
@@ -37,6 +37,7 @@
#include <openspace/navigation/pathnavigator.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec4property.h>
#include <openspace/util/mouse.h>
#include <openspace/util/keys.h>
@@ -99,6 +100,8 @@ public:
void mousePositionCallback(double x, double y);
void mouseScrollWheelCallback(double pos);
void renderOverlay() const;
std::vector<std::string> listAllJoysticks() const;
void setJoystickAxisMapping(std::string joystickName,
int axis, JoystickCameraStates::AxisType mapping,
@@ -208,6 +211,17 @@ private:
properties::BoolProperty _disableJoystickInputs;
properties::BoolProperty _useKeyFrameInteraction;
properties::FloatProperty _jumpToFadeDuration;
struct {
properties::PropertyOwner owner;
properties::BoolProperty enable;
properties::Vec4Property color;
bool isMouseFirstPress = false;
bool isMousePressed = false;
glm::vec2 clickPosition;
glm::vec2 currentPosition;
} _mouseVisualizer;
};
} // namespace openspace::interaction
+8
View File
@@ -63,6 +63,9 @@ void renderBox(const glm::vec2& position, const glm::vec2& size, const glm::vec4
void renderBox(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color,
const ghoul::opengl::Texture& texture, Anchor anchor = Anchor::NW);
void renderLine(const glm::vec2& startPosition, const glm::vec2& endPosition,
const glm::vec2& size, const glm::vec4& startColor, const glm::vec4& endColor);
struct Shaders {
struct {
std::unique_ptr<ghoul::opengl::ProgramObject> program;
@@ -105,6 +108,11 @@ struct VertexObjects {
int nElements = 64;
} cone;
struct {
GLuint vao = 0;
GLuint vbo = 0;
} line;
struct {
GLuint vao = 0;
} empty;
+1
View File
@@ -1299,6 +1299,7 @@ void OpenSpaceEngine::drawOverlays() {
if (isGuiWindow) {
global::renderEngine->renderOverlays(_shutdown);
global::sessionRecordingHandler->render();
global::navigationHandler->renderOverlay();
}
for (const std::function<void()>& func : *global::callback::draw2D) {
+76 -1
View File
@@ -28,6 +28,7 @@
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/events/event.h>
#include <openspace/events/eventengine.h>
#include <openspace/interaction/actionmanager.h>
@@ -36,7 +37,7 @@
#include <openspace/navigation/waypoint.h>
#include <openspace/network/parallelpeer.h>
#include <openspace/query/query.h>
#include <openspace/scene/profile.h>
#include <openspace/rendering/helper.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scripting/lualibrary.h>
@@ -100,6 +101,27 @@ namespace {
"again.",
openspace::properties::Property::Visibility::User
};
const openspace::properties::PropertyOwner::PropertyOwnerInfo MouseVisualizerInfo = {
"MouseInteractionVisualizer",
"Mouse Interaction Visualizer",
"The mouse interaction visualizer shows the distance the mouse has been moved "
"since it was pressed down."
};
constexpr openspace::properties::Property::PropertyInfo MouseVisualizerEnabledInfo = {
"Enabled",
"Enabled",
"If this setting is enabled, the mouse interaction will be visualized on the "
"screen by showing the distance the mouse has been moved since it was pressed "
"down."
};
constexpr openspace::properties::Property::PropertyInfo MouseVisualizerColorInfo = {
"Color",
"Color",
"The color used to render the line showing the mouse visualizer."
};
} // namespace
namespace openspace::interaction {
@@ -111,6 +133,20 @@ NavigationHandler::NavigationHandler()
, _disableJoystickInputs(DisableJoystickInputInfo, false)
, _useKeyFrameInteraction(FrameInfo, false)
, _jumpToFadeDuration(JumpToFadeDurationInfo, 1.f, 0.f, 10.f)
, _mouseVisualizer({
properties::PropertyOwner(MouseVisualizerInfo),
properties::BoolProperty(MouseVisualizerEnabledInfo, false),
properties::Vec4Property(
MouseVisualizerColorInfo,
glm::vec4(1.f),
glm::vec4(0.f),
glm::vec4(1.f)
),
false,
false,
glm::vec2(0.f),
glm::vec2(0.f)
})
{
addPropertySubOwner(_orbitalNavigator);
addPropertySubOwner(_pathNavigator);
@@ -120,6 +156,11 @@ NavigationHandler::NavigationHandler()
addProperty(_disableJoystickInputs);
addProperty(_useKeyFrameInteraction);
addProperty(_jumpToFadeDuration);
addPropertySubOwner(_mouseVisualizer.owner);
_mouseVisualizer.owner.addProperty(_mouseVisualizer.enable);
_mouseVisualizer.color.setViewOption(properties::Property::ViewOptions::Color);
_mouseVisualizer.owner.addProperty(_mouseVisualizer.color);
}
NavigationHandler::~NavigationHandler() {}
@@ -495,12 +536,33 @@ const KeyboardInputState& NavigationHandler::keyboardInputState() const {
void NavigationHandler::mouseButtonCallback(MouseButton button, MouseAction action) {
if (!_disableMouseInputs) {
_mouseInputState.mouseButtonCallback(button, action);
if (_mouseVisualizer.enable) {
if (action == MouseAction::Press) {
_mouseVisualizer.isMouseFirstPress = true;
_mouseVisualizer.isMousePressed = true;
}
else if (action == MouseAction::Release) {
_mouseVisualizer.isMousePressed = false;
_mouseVisualizer.currentPosition = glm::vec2(0.f);
_mouseVisualizer.clickPosition = glm::vec2(0.f);
}
}
}
}
void NavigationHandler::mousePositionCallback(double x, double y) {
if (!_disableMouseInputs) {
_mouseInputState.mousePositionCallback(x, y);
if (_mouseVisualizer.enable && _mouseVisualizer.isMousePressed) {
if (_mouseVisualizer.isMouseFirstPress) {
_mouseVisualizer.clickPosition = glm::vec2(x, y);
_mouseVisualizer.isMouseFirstPress = false;
}
_mouseVisualizer.currentPosition = glm::vec2(x, y);
}
}
}
@@ -517,6 +579,19 @@ void NavigationHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActio
_keyboardInputState.keyboardCallback(key, modifier, action);
}
void NavigationHandler::renderOverlay() const {
if (_mouseVisualizer.enable && _mouseVisualizer.isMousePressed) {
constexpr glm::vec4 StartColor = glm::vec4(0.4f, 0.4f, 0.4f, 0.25f);
rendering::helper::renderLine(
_mouseVisualizer.clickPosition,
_mouseVisualizer.currentPosition,
global::windowDelegate->currentWindowSize(),
StartColor,
_mouseVisualizer.color
);
}
}
bool NavigationHandler::disabledKeybindings() const {
return _disableKeybindings;
}
+116 -13
View File
@@ -42,6 +42,12 @@
namespace {
struct VertexXYUVRGBA {
std::array<GLfloat, 2> xy;
std::array<GLfloat, 2> uv;
std::array<GLfloat, 4> rgba;
};
bool isInitialized = false;
std::filesystem::path xyuvrgbaVertexFile;
@@ -218,11 +224,6 @@ void initialize() {
glBindVertexArray(vertexObjects.square.vao);
glBindBuffer(GL_ARRAY_BUFFER, vertexObjects.square.vbo);
struct VertexXYUVRGBA {
std::array<GLfloat, 2> xy;
std::array<GLfloat, 2> uv;
std::array<GLfloat, 4> rgba;
};
constexpr std::array<VertexXYUVRGBA, 6> Vtx = {
// X Y U V R G B A
VertexXYUVRGBA{ { -1.f, -1.f }, { 0.f, 0.f }, { 1.f, 1.f, 1.f, 1.f } },
@@ -288,11 +289,23 @@ void initialize() {
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(Vertex, uv)));
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(Vertex, uv))
);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(Vertex, rgba)));
glVertexAttribPointer(
2,
4,
GL_FLOAT,
GL_FALSE,
sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(Vertex, rgba))
);
glBindVertexArray(0);
vertexObjects.sphere.nElements = static_cast<int>(sphereData.indices.size());
@@ -325,8 +338,14 @@ void initialize() {
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexXYZNormal), nullptr);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexXYZNormal),
reinterpret_cast<GLvoid*>(offsetof(VertexXYZNormal, normal)));
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
sizeof(VertexXYZNormal),
reinterpret_cast<GLvoid*>(offsetof(VertexXYZNormal, normal))
);
glBindVertexArray(0);
vertexObjects.cylinder.nElements = static_cast<int>(cylinderData.indices.size());
@@ -359,12 +378,54 @@ void initialize() {
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexXYZNormal), nullptr);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexXYZNormal),
reinterpret_cast<GLvoid*>(offsetof(VertexXYZNormal, normal)));
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
sizeof(VertexXYZNormal),
reinterpret_cast<GLvoid*>(offsetof(VertexXYZNormal, normal))
);
glBindVertexArray(0);
vertexObjects.cone.nElements = static_cast<int>(coneData.indices.size());
//
// Line vertex array object
//
glGenVertexArrays(1, &vertexObjects.line.vao);
glGenBuffers(1, &vertexObjects.line.vbo);
glBindVertexArray(vertexObjects.line.vao);
glBindBuffer(GL_ARRAY_BUFFER, vertexObjects.line.vbo);
glBufferData(
GL_ARRAY_BUFFER,
2 * sizeof(VertexXYUVRGBA),
nullptr,
GL_STATIC_DRAW
);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexXYUVRGBA), nullptr);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(VertexXYUVRGBA),
reinterpret_cast<GLvoid*>(offsetof(VertexXYUVRGBA, uv))
);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2,
4,
GL_FLOAT,
GL_FALSE,
sizeof(VertexXYUVRGBA),
reinterpret_cast<GLvoid*>(offsetof(VertexXYUVRGBA, rgba))
);
glBindVertexArray(0);
//
// Empty vertex array objects
//
@@ -501,6 +562,48 @@ void renderBox(const glm::vec2& position, const glm::vec2& size, const glm::vec4
shdr.program->deactivate();
}
void renderLine(const glm::vec2& startPosition, const glm::vec2& endPosition,
const glm::vec2& size, const glm::vec4& startColor,
const glm::vec4& endColor)
{
auto& shdr = shaders.xyuvrgba;
shdr.program->activate();
shdr.program->setUniform(shdr.cache.proj, ortho(glm::vec2(0.f), glm::vec2(1.f)));
shdr.program->setUniform(shdr.cache.hasTexture, 0);
glBindVertexArray(vertexObjects.line.vao);
// Move the start and end position from a [0,res] range to a [-1, 1] range
const glm::vec2 start = (startPosition / size) * 2.f - glm::vec2(1.f);
const glm::vec2 end = (endPosition / size) * 2.f - glm::vec2(1.f);
std::array<VertexXYUVRGBA, 2> vertexData = {
VertexXYUVRGBA{
{ start.x, -start.y },
{ 0.f, 0.f },
{ startColor.r, startColor.g, startColor.b, startColor.a }
},
VertexXYUVRGBA{
{ end.x, -end.y },
{ 0.f, 0.f },
{ endColor.r, endColor.g, endColor.b, endColor.a }
}
};
glBindBuffer(GL_ARRAY_BUFFER, vertexObjects.line.vbo);
glBufferData(
GL_ARRAY_BUFFER,
2 * sizeof(VertexXYUVRGBA),
vertexData.data(),
GL_STATIC_DRAW
);
glEnable(GL_LINE_SMOOTH);
glLineWidth(6.f);
glDrawArrays(GL_LINES, 0, 2);
glPointSize(6.f);
glDrawArrays(GL_POINTS, 0, 2);
glBindVertexArray(0);
}
VertexXYZ convertToXYZ(const Vertex& v) {
return VertexXYZ{ v.xyz[0], v.xyz[1], v.xyz[2] };
}