Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Gamepad Support via GLFW #986

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 25 additions & 27 deletions core/src/view/AbstractView_EventConsumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,37 +106,35 @@ void view_poke_rendering(AbstractViewInterface& view, megamol::frontend_resource

bool camera_state_mutable_by_view = true;

if (renderinput.camera_view_projection_parameters_override.has_value()) {
auto& proj_parameters = renderinput.camera_view_projection_parameters_override.value();

auto& in_pose = proj_parameters.pose;
auto cam_pose = Camera::Pose{
if (renderinput.camera_view_pose_parameters_override.has_value()) {
auto& in_pose = renderinput.camera_view_pose_parameters_override.value();
camera.setPose(Camera::Pose{
in_pose.position, in_pose.direction, in_pose.up,
glm::cross(in_pose.direction, in_pose.up) // right, as computed by Camrea
};
glm::cross(in_pose.direction, in_pose.up), // right, as computed by Camrea
});
}

auto& in_proj = proj_parameters.projection;
if (renderinput.camera_view_projection_parameters_override.has_value()) {
auto& in_proj = renderinput.camera_view_projection_parameters_override.value();
switch (in_proj.type) {
case RenderInput::CameraViewProjectionParameters::ProjectionType::PERSPECTIVE:
camera = Camera{cam_pose,
Camera::PerspectiveParameters{
in_proj.fovy, // FieldOfViewY fovy; //< vertical field of view
in_proj.aspect, // AspectRatio aspect; //< aspect ratio of the camera frustrum
in_proj.near_plane, // NearPlane near_plane; //< near clipping plane
in_proj.far_plane, // FarPlane far_plane; //< far clipping plane
tile // ImagePlaneTile image_plane_tile; //< tile on the image plane displayed by camera
}};
case RenderInput::CameraProjection::ProjectionType::PERSPECTIVE:
camera.setPerspectiveProjection(Camera::PerspectiveParameters{
in_proj.fovy, // FieldOfViewY fovy; //< vertical field of view
in_proj.aspect, // AspectRatio aspect; //< aspect ratio of the camera frustrum
in_proj.near_plane, // NearPlane near_plane; //< near clipping plane
in_proj.far_plane, // FarPlane far_plane; //< far clipping plane
tile, // ImagePlaneTile image_plane_tile; //< tile on the image plane displayed by camera
});
break;
case RenderInput::CameraViewProjectionParameters::ProjectionType::ORTHOGRAPHIC:
camera = Camera{cam_pose,
Camera::OrthographicParameters{
in_proj
.fovy, // FrustrumHeight frustrum_height; //< vertical size of the orthographic frustrum in world space
in_proj.aspect, // AspectRatio aspect; //< aspect ratio of the camera frustrum
in_proj.near_plane, // NearPlane near_plane; //< near clipping plane
in_proj.far_plane, // FarPlane far_plane; //< far clipping plane
tile // ImagePlaneTile image_plane_tile; //< tile on the image plane displayed by camera
}};
case RenderInput::CameraProjection::ProjectionType::ORTHOGRAPHIC:
camera.setOrthographicProjection(Camera::OrthographicParameters{
in_proj
.fovy, // FrustrumHeight frustrum_height; //< vertical size of the orthographic frustrum in world space
in_proj.aspect, // AspectRatio aspect; //< aspect ratio of the camera frustrum
in_proj.near_plane, // NearPlane near_plane; //< near clipping plane
in_proj.far_plane, // FarPlane far_plane; //< far clipping plane
tile, // ImagePlaneTile image_plane_tile; //< tile on the image plane displayed by camera
});
break;
}

Expand Down
6 changes: 6 additions & 0 deletions frontend/main/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "CLIConfigParsing.h"
#include "CUDA_Service.hpp"
#include "Command_Service.hpp"
#include "ExoticInputs_Service.hpp"
#include "FrameStatistics_Service.hpp"
#include "FrontendServiceCollection.hpp"
#include "GUI_Service.hpp"
Expand Down Expand Up @@ -100,6 +101,10 @@ int main(const int argc, const char** argv) {
openglConfig.forceWindowSize = config.force_window_size;
gl_service.setPriority(2);

megamol::frontend::ExoticInputs_Service exoticinputs_service;
megamol::frontend::ExoticInputs_Service::Config exoticinputsConfig;
exoticinputs_service.setPriority(gl_service.getPriority() + 1); // depends on gamepad updates from GLFW

megamol::frontend::GUI_Service gui_service;
megamol::frontend::GUI_Service::Config guiConfig;
guiConfig.backend = (with_gl) ? (megamol::gui::GUIRenderBackend::OPEN_GL) : (megamol::gui::GUIRenderBackend::CPU);
Expand Down Expand Up @@ -196,6 +201,7 @@ int main(const int argc, const char** argv) {
if (with_gl) {
services.add(gl_service, &openglConfig);
}
services.add(exoticinputs_service, &exoticinputsConfig);
services.add(gui_service, &guiConfig);
services.add(lua_service_wrapper, &luaConfig);
services.add(screenshot_service, &screenshotConfig);
Expand Down
120 changes: 120 additions & 0 deletions frontend/resources/include/GamepadState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* GamepadState.h
*
* Copyright (C) 2022 by VISUS (Universitaet Stuttgart).
* Alle Rechte vorbehalten.
*/

#pragma once

#include <cstring>
#include <functional>
#include <list>
#include <string>
#include <vector>

namespace megamol {
namespace frontend_resources {

// SDL compatible XBox-like gamepad layout
// as defined in glfw3.h
struct GamepadState {
// Axis, Button enumeration taken from the GLFW docs
// https://www.glfw.org/docs/3.3/group__input.html
enum class Axis : unsigned int {
LEFT_X = 0,
LEFT_Y = 1,
RIGHT_X = 2,
RIGHT_Y = 3,
LEFT_TRIGGER = 4,
RIGHT_TRIGGER = 5,
LAST = RIGHT_TRIGGER,
};
enum class Button : unsigned int {
A = 0,
B = 1,
X = 2,
Y = 3,
LEFT_BUMPER = 4,
RIGHT_BUMPER = 5,
BACK = 6,
START = 7,
GUIDE = 8,
LEFT_THUMB = 9,
RIGHT_THUMB = 10,
DPAD_UP = 11,
DPAD_RIGHT = 12,
DPAD_DOWN = 13,
DPAD_LEFT = 14,
LAST = DPAD_LEFT,
CROSS = A,
CIRCLE = B,
SQUARE = X,
TRIANGLE = Y,
};
enum class ButtonIs : unsigned char {
Released = 0,
Pressed = 1,
};
enum class HatIs : unsigned char {
CENTERED = 0,
UP = 1,
RIGHT = 2,
DOWN = 4,
LEFT = 8,
RIGHT_UP = (RIGHT | UP),
RIGHT_DOWN = (RIGHT | DOWN),
LEFT_UP = (LEFT | UP),
LEFT_DOWN = (LEFT | DOWN),
};

std::vector<float> axes = {};
std::vector<unsigned char> buttons = {};
std::vector<unsigned char> hats = {};

std::string name;
std::string guid;

float axis(const Axis a) const {
return axes[static_cast<unsigned int>(a)];
}

unsigned char button(const Button b) const {
return buttons[static_cast<unsigned int>(b)];
}

bool pressed(const unsigned char button) const {
return button == static_cast<unsigned char>(ButtonIs::Pressed);
}

bool pressed(const Button b) const {
return pressed(button(b));
}

bool released(const unsigned char button) const {
return button == static_cast<unsigned char>(ButtonIs::Released);
}

HatIs hat(const unsigned int index) const {
return static_cast<HatIs>(hats[index]);
}

int hat_count() const {
return hats.size();
}

void clear() {
buttons.clear();
axes.clear();
hats.clear();
name.clear();
guid.clear();
}
};

struct Connected_Gamepads {
std::list<std::reference_wrapper<const GamepadState>> gamepads;
};

} /* end namespace frontend_resources */
} /* end namespace megamol */
38 changes: 17 additions & 21 deletions frontend/resources/include/RenderInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,25 @@ struct RenderInput {
// this is a rude copy-paste of the camera parameters from
// Camera.h to avoid linking and including the core/view in the resources CMakeLists.txt
// when things break or in doubt do as the Camera says or needs! the frontend is not here to be served, but to serve.
struct CameraViewProjectionParameters {
enum class ProjectionType { PERSPECTIVE, ORTHOGRAPHIC };

struct Pose {
glm::vec3 position;
glm::vec3 direction;
glm::vec3 up;
};

struct Projection {
ProjectionType type;
float
fovy; //< vertical field of view / orthographic frustrum_height: vertical size of the orthographic frustrum in world space
float aspect; //< aspect ratio of the camera frustrum
float near_plane; //< near clipping plane
float far_plane; //< far clipping plane
};
struct CameraPose {
glm::vec3 position;
glm::vec3 direction;
glm::vec3 up;
};
std::optional<CameraPose> camera_view_pose_parameters_override =
std::nullopt; //< if camera pose is overridden, this view still needs to render in local resolution

Pose pose;
Projection projection;
struct CameraProjection {
enum class ProjectionType { PERSPECTIVE, ORTHOGRAPHIC };
ProjectionType type;
float
fovy; //< vertical field of view / orthographic frustrum_height: vertical size of the orthographic frustrum in world space
float aspect; //< aspect ratio of the camera frustrum
float near_plane; //< near clipping plane
float far_plane; //< far clipping plane
};
std::optional<CameraViewProjectionParameters> camera_view_projection_parameters_override =
std::nullopt; //< if camera matrices are overridden, this view still needs to render in local resolution
std::optional<CameraProjection> camera_view_projection_parameters_override =
std::nullopt; //< if camera porjection is overridden, this view still needs to render in local resolution

double instanceTime_sec =
0.0; //< monotone high resolution time in seconds since first frame rendering of some (any) view
Expand Down
9 changes: 6 additions & 3 deletions frontend/resources/include/ViewRenderInputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ struct ViewRenderInputs : public frontend_resources::RenderInputsUpdate {
std::function<std::optional<frontend_resources::RenderInput::CameraMatrices>()> render_input_camera_handler = []() {
return std::nullopt;
};
std::function<std::optional<frontend_resources::RenderInput::CameraViewProjectionParameters>()>
render_input_camera_parameters_handler = []() { return std::nullopt; };
std::function<std::optional<frontend_resources::RenderInput::CameraPose>()>
render_input_camera_pose_parameters_handler = []() { return std::nullopt; };
std::function<std::optional<frontend_resources::RenderInput::CameraProjection>()>
render_input_camera_projection_parameters_handler = []() { return std::nullopt; };

void update() override {
auto fbo_size = render_input_framebuffer_size_handler();
Expand All @@ -45,7 +47,8 @@ struct ViewRenderInputs : public frontend_resources::RenderInputsUpdate {
render_input.local_tile_relative_end = {tile.tile_end_normalized.first, tile.tile_end_normalized.second};

render_input.camera_matrices_override = render_input_camera_handler();
render_input.camera_view_projection_parameters_override = render_input_camera_parameters_handler();
render_input.camera_view_projection_parameters_override = render_input_camera_projection_parameters_handler();
render_input.camera_view_pose_parameters_override = render_input_camera_pose_parameters_handler();
}

frontend::FrontendResource get_resource() override {
Expand Down
3 changes: 3 additions & 0 deletions frontend/services/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ file(GLOB_RECURSE header_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"remote_service/*.hpp"
"profiling_service/*.hpp"
"vr_service/*.hpp"
"exotic_inputs/*.hpp"
# "service_template/*.hpp"
)

Expand All @@ -48,6 +49,7 @@ file(GLOB_RECURSE source_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"remote_service/*.cpp"
"profiling_service/*.cpp"
"vr_service/*.cpp"
"exotic_inputs/*.cpp"
# "service_template/*.cpp"
)

Expand Down Expand Up @@ -109,6 +111,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC
"gui/3rd"
"gui/src"
"vr_service"
"exotic_inputs"
# "service_template"
)

Expand Down
Loading
Loading