IInputManager, QtInputManager & buggy camera rotations

This commit is contained in:
floralrainfall 2023-07-18 22:52:34 -04:00
parent e48ac7f435
commit 9f1ccaa7ab
13 changed files with 272 additions and 5 deletions

View File

@ -1,12 +1,14 @@
list(APPEND SOURCE
Source/GL/Adorn.cpp
Source/OgreWidget.cpp
Source/QtInputManager.cpp
)
list(APPEND HEADER
Header/GL/Adorn.hpp
Header/GL/RenderContext.hpp
Header/OgreWidget.hpp
Header/QtInputManager.hpp
)
qt_standard_project_setup()

View File

@ -9,6 +9,7 @@
#include <OGRE/RTShaderSystem/OgreShaderGenerator.h>
#include <App/V8/Tree/Instance.hpp>
#include <App/V8/World/World.hpp>
#include <QtInputManager.hpp>
#include <GL/Adorn.hpp>
@ -34,9 +35,12 @@ namespace RNR
Ogre::Camera* ogreCamera;
Ogre::Viewport* ogreViewport;
Ogre::RTShader::ShaderGenerator* ogreShaderGen;
QCursor cursor;
void render();
void initializeOgre();
void setWorld(RNR::World* world) { this->world = world; inputManager->setWorld(world); }
Ogre::NameValuePairList getRenderOptions();
Ogre::String getWindowHandle();
@ -44,11 +48,18 @@ namespace RNR
protected:
virtual void paintEvent(QPaintEvent* pEvent);
virtual void resizeEvent(QResizeEvent* rEvent);
virtual void keyPressEvent(QKeyEvent *event);
virtual void keyReleaseEvent(QKeyEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void closeEvent(QCloseEvent* event);
virtual QPaintEngine* paintEngine() const;
private:
QElapsedTimer timer;
QtInputManager* inputManager;
};
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <App/InputManager.hpp>
#include <QMouseEvent>
#include <QKeyEvent>
namespace RNR
{
class OgreWidget;
class QtInputManager : public RNR::IInputManager
{
private:
QPointF last_position;
OgreWidget* widget;
bool reset;
public:
QtInputManager(OgreWidget* widget);
void keyEvent(QKeyEvent* e);
void mouseEvent(QMouseEvent* e);
virtual void resetMouse();
};
}

View File

@ -24,9 +24,11 @@ namespace RNR
this->setAttribute(Qt::WA_OpaquePaintEvent);
this->setAttribute(Qt::WA_PaintOnScreen);
this->setMouseTracking(true);
this->setCursor(QCursor(Qt::BlankCursor));
//this->setCursor(QCursor(Qt::BlankCursor));
this->setFocusPolicy(Qt::StrongFocus);
this->selectedInstance = 0;
inputManager = new QtInputManager(this);
}
void OgreWidget::initializeOgre()
@ -168,8 +170,29 @@ namespace RNR
//
}
void OgreWidget::keyPressEvent(QKeyEvent *e)
{
inputManager->keyEvent(e);
}
void OgreWidget::keyReleaseEvent(QKeyEvent *e)
{
inputManager->keyEvent(e);
}
void OgreWidget::mousePressEvent(QMouseEvent *e)
{
inputManager->mouseEvent(e);
}
void OgreWidget::mouseReleaseEvent(QMouseEvent *e)
{
inputManager->mouseEvent(e);
}
void OgreWidget::mouseMoveEvent(QMouseEvent *mEvent)
{
inputManager->mouseEvent(mEvent);
}
void OgreWidget::closeEvent(QCloseEvent* event)

View File

@ -0,0 +1,63 @@
#include <QtInputManager.hpp>
#include <OgreWidget.hpp>
namespace RNR
{
QtInputManager::QtInputManager(OgreWidget* widget)
{
last_position = QPointF();
this->widget = widget;
}
void QtInputManager::keyEvent(QKeyEvent* e)
{
if(e->type() == QEvent::KeyPress)
keyDown(e->key());
else if(e->type() == QEvent::KeyRelease)
keyUp(e->key());
}
void QtInputManager::mouseEvent(QMouseEvent* e)
{
QPointF position = e->position();
mouseMoveAbsolute(position.x(), position.y());
mouseMoveRelative(position.x() - last_position.x(), last_position.y() - position.y());
if(!reset)
{
last_position = position;
reset = false;
}
if(e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease)
{
bool down = (e->type() == QEvent::MouseButtonPress);
Qt::MouseButton button = e->button();
switch(button)
{
case Qt::LeftButton:
mousePrimaryState(down);
break;
case Qt::RightButton:
mouseSecondaryState(down);
break;
case Qt::MiddleButton:
mouseMiddleState(down);
break;
}
}
}
void QtInputManager::resetMouse()
{
widget->clearFocus();
QPoint glob = widget->mapToGlobal(QPoint(widget->width()/2,widget->height()/2));
QCursor::setPos(glob);
last_position = QPoint(widget->width()/2,widget->height()/2);
widget->setFocus();
reset = true;
}
}

View File

@ -32,7 +32,7 @@ int main(int argc, char** argv)
RNR::World* world = new RNR::World(window.ogreWidget->ogreRoot, window.ogreWidget->ogreSceneManager);
window.updateTree(world->getDatamodel());
window.ogreWidget->world = world;
window.ogreWidget->setWorld(world);
while (window.isVisible())
{

View File

@ -23,6 +23,7 @@ add_library(Engine STATIC
Header/App/V8/World/World.hpp
Header/App/CoordinateFrame.hpp
Header/App/BrickColor.hpp
Header/App/InputManager.hpp
Header/Network/GUID.hpp
Header/Rendering/Adorn.hpp
@ -49,6 +50,7 @@ add_library(Engine STATIC
Source/App/V8/Tree/ModelInstance.cpp
Source/App/CoordinateFrame.cpp
Source/App/BrickColor.cpp
Source/App/InputManager.cpp
Source/App/V8/World/World.cpp
Source/Network/GUID.cpp
Source/Rendering/Adorn.cpp

View File

@ -0,0 +1,37 @@
#pragma once
#include <App/V8/World/World.hpp>
namespace RNR
{
struct MouseState
{
bool mouse_primary;
bool mouse_secondary;
bool mouse_middle;
float mouse_scroll;
};
class IInputManager
{
World* m_world;
protected:
MouseState state;
public:
IInputManager();
virtual void resetMouse() {};
void setWorld(World* world) { m_world = world; }
void keyDown(int scancode);
void keyUp(int scancode);
void mouseMoveRelative(float x, float y);
void mouseMoveAbsolute(float x, float y);
void mousePrimaryState(bool down);
void mouseSecondaryState(bool down);
void mouseMiddleState(bool down);
void mouseScrollState(float scroll);
};
}

View File

@ -12,15 +12,23 @@ namespace RNR
{
private:
CoordinateFrame m_cframe;
CoordinateFrame m_focus;
virtual void deserializeProperty(char* prop_name, pugi::xml_node prop);
virtual void addProperties(std::vector<ReflectionProperty>& properties);
float m_cf_yaw;
float m_cf_pitch;
public:
Camera();
~Camera();
void cameraFrame(float xd, float yd);
virtual std::string getClassName() { return "Camera"; }
CoordinateFrame& getCFrame() { return m_cframe; };
CoordinateFrame& getFocus() { return m_focus; }
void setCFrame(CoordinateFrame cframe) { m_cframe = cframe; };
void setFocus(CoordinateFrame focus) { m_focus = focus; }
bool zoom(float distance);
};
}

View File

@ -31,6 +31,7 @@ namespace RNR
Ogre::SceneManager* m_ogreSceneManager;
TopMenuBar* m_tmb;
InstanceFactory* m_instanceFactory;
float m_lastDelta;
void xmlAddItem(pugi::xml_node node, Instance* parent);
public:
@ -45,8 +46,7 @@ namespace RNR
double step(float timestep);
void update();
float getLastDelta() { return m_lastDelta; }
DataModel* getDatamodel() { return m_datamodel; }
void setDatamodel(DataModel* instance) { m_datamodel = instance; }
Workspace* getWorkspace() { return m_workspace; }

View File

@ -0,0 +1,67 @@
#include <App/InputManager.hpp>
#include <App/V8/DataModel/Camera.hpp>
#include <stdio.h>
namespace RNR
{
IInputManager::IInputManager()
{
state.mouse_primary = false;
state.mouse_secondary = false;
state.mouse_middle = false;
state.mouse_scroll = 0;
}
void IInputManager::keyDown(int scancode)
{
}
void IInputManager::keyUp(int scancode)
{
}
void IInputManager::mouseMoveAbsolute(float x, float y)
{
}
void IInputManager::mouseMoveRelative(float x, float y)
{
if(m_world)
{
float xd = x * m_world->getLastDelta();
float yd = y * m_world->getLastDelta();
Workspace* workspace = m_world->getWorkspace();
Camera* camera = workspace->getCurrentCamera();
if(camera && state.mouse_secondary)
{
camera->cameraFrame(xd, yd);
resetMouse();
}
}
}
void IInputManager::mousePrimaryState(bool down)
{
state.mouse_primary = down;
}
void IInputManager::mouseSecondaryState(bool down)
{
state.mouse_secondary = down;
}
void IInputManager::mouseMiddleState(bool down)
{
state.mouse_middle = down;
}
void IInputManager::mouseScrollState(float scroll)
{
state.mouse_scroll = scroll;
}
}

View File

@ -5,7 +5,8 @@ namespace RNR
{
Camera::Camera()
{
//
m_cf_yaw = 0.f;
m_cf_pitch = 0.f;
}
Camera::~Camera()
@ -19,6 +20,29 @@ namespace RNR
{
setCFrame(XML::getCFrame(node));
}
else if(prop_name == std::string("Focus"))
{
setFocus(XML::getCFrame(node));
}
}
void Camera::cameraFrame(float xd, float yd)
{
Ogre::Radian pitch = Ogre::Radian(yd);
Ogre::Radian yaw = Ogre::Radian(xd);
Ogre::Radian old_pitch;
Ogre::Radian old_yaw;
Ogre::Radian old_roll;
getCFrame().getRotation().ToEulerAnglesZXY(old_yaw, old_pitch, old_roll);
pitch = old_pitch + pitch;
yaw = old_yaw - yaw;
Ogre::Matrix3 rotation;
rotation.FromEulerAnglesZXY(yaw, pitch, Ogre::Radian(0));
getCFrame().setRotation(rotation);
}
void Camera::addProperties(std::vector<ReflectionProperty>& properties)
@ -28,6 +52,10 @@ namespace RNR
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_CFRAME,
REFLECTION_GETTER(Camera* instance = (Camera*)object; return &instance->m_cframe; ),
REFLECTION_SETTER(Camera* instance = (Camera*)object; instance->setCFrame(*(CoordinateFrame*)value); ) },
{ this, std::string("Target"), std::string(""),
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_CFRAME,
REFLECTION_GETTER(Camera* instance = (Camera*)object; return &instance->m_focus; ),
REFLECTION_SETTER(Camera* instance = (Camera*)object; instance->setFocus(*(CoordinateFrame*)value); ) },
};
properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty)));

View File

@ -122,6 +122,7 @@ namespace RNR
{
if(m_runService && m_runService->getRunning())
m_runService->step(timestep);
m_lastDelta = timestep;
return 0.0;
}