Solve merge conflict for interaction.

This commit is contained in:
Kalle Bladin
2016-05-25 13:20:12 -04:00
12 changed files with 1077 additions and 473 deletions
@@ -41,62 +41,44 @@ class SceneGraphNode;
namespace interaction {
//#define USE_OLD_INTERACTIONHANDLER
#ifdef USE_OLD_INTERACTIONHANDLER
class InteractionHandler : public properties::PropertyOwner {
public:
InteractionHandler();
~InteractionHandler();
// Mutators
void setKeyboardController(KeyboardController* controller);
void setMouseController(MouseController* controller);
void setFocusNode(SceneGraphNode* node);
void setCamera(Camera* camera);
void setInteractionSensitivity(float sensitivity);
void resetKeyBindings();
void setInvertRoll(bool invert);
void setInvertRotation(bool invert);
void addController(Controller* controller);
void addKeyframe(const network::datamessagestructures::PositionKeyframe &kf);
void clearKeyframes();
void bindKey(Key key, KeyModifier modifier, std::string lua);
void lockControls();
void unlockControls();
void update(double deltaTime);
void setFocusNode(SceneGraphNode* node);
// Accessors
const SceneGraphNode* const focusNode() const;
void setCamera(Camera* camera);
const Camera* const camera() const;
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
void mouseButtonCallback(MouseButton button, MouseAction action);
void mousePositionCallback(double x, double y);
void mouseScrollWheelCallback(double pos);
double deltaTime() const;
void orbitDelta(const glm::quat& rotation);
void orbit(const float &dx, const float &dy, const float &dz, const float &dist);
//void distance(const float &d);
void rotateDelta(const glm::quat& rotation);
void distanceDelta(const PowerScaledScalar& distance, size_t iterations = 0);
void lookAt(const glm::quat& rotation);
void setRotation(const glm::quat& rotation);
void resetKeyBindings();
void bindKey(Key key, KeyModifier modifier, std::string lua);
void setInteractionSensitivity(float sensitivity);
float interactionSensitivity() const;
void setInvertRoll(bool invert);
bool invertRoll() const;
void setInvertRotation(bool invert);
bool invertRotation() const;
void addKeyframe(const network::datamessagestructures::PositionKeyframe &kf);
void clearKeyframes();
/**
* Returns the Lua library that contains all Lua functions available to affect the
* interaction. The functions contained are
@@ -106,28 +88,45 @@ public:
*/
static scripting::ScriptEngine::LuaLibrary luaLibrary();
private:
friend class Controller;
// Callback functions
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
void mouseButtonCallback(MouseButton button, MouseAction action);
void mousePositionCallback(double x, double y);
void mouseScrollWheelCallback(double pos);
// Interaction functions
void orbitDelta(const glm::quat& rotation);
void orbit(const float &dx, const float &dy, const float &dz, const float &dist);
void rotateDelta(const glm::quat& rotation);
void distanceDelta(const PowerScaledScalar& distance, size_t iterations = 0);
void lookAt(const glm::quat& rotation);
void setRotation(const glm::quat& rotation);
private:
// Remove copy and move constructors
InteractionHandler(const InteractionHandler&) = delete;
InteractionHandler& operator=(const InteractionHandler&) = delete;
InteractionHandler(InteractionHandler&&) = delete;
InteractionHandler& operator=(InteractionHandler&&) = delete;
Camera* _camera;
SceneGraphNode* _focusNode;
double _deltaTime;
std::mutex _mutex;
bool _validKeyLua;
std::multimap<KeyWithModifier, std::string > _keyLua;
// Settings
float _controllerSensitivity;
bool _invertRoll;
bool _invertRotation;
// Pointers to entities to affect
Camera* _camera;
SceneGraphNode* _focusNode;
// Cached data
double _deltaTime;
std::mutex _mutex;
//bool _validKeyLua;
std::multimap<KeyWithModifier, std::string > _keyLua;
KeyboardController* _keyboardController;
MouseController* _mouseController;
std::vector<Controller*> _controllers;
@@ -141,6 +140,170 @@ private:
std::mutex _keyframeMutex;
};
#else // USE_OLD_INTERACTIONHANDLER
class InputState
{
public:
InputState();
~InputState();
// Callback functions
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
void mouseButtonCallback(MouseButton button, MouseAction action);
void mousePositionCallback(double mouseX, double mouseY);
void mouseScrollWheelCallback(double mouseScrollDelta);
// Accessors
const std::list<std::pair<Key, KeyModifier> >& getPressedKeys();
const std::list<MouseButton>& getPressedMouseButtons();
glm::dvec2 getMousePosition();
double getMouseScrollDelta();
bool isKeyPressed(std::pair<Key, KeyModifier> keyModPair);
bool isMouseButtonPressed(MouseButton mouseButton);
private:
std::list<std::pair<Key, KeyModifier> > _keysDown;
std::list<MouseButton> _mouseButtonsDown;
glm::dvec2 _mousePosition;
double _mouseScrollDelta;
};
class InteractionMode
{
public:
InteractionMode(std::shared_ptr<InputState> inputState);
~InteractionMode();
// Mutators
void setFocusNode(SceneGraphNode* focusNode);
void setCamera(Camera* camera);
// Accessors
SceneGraphNode* focusNode();
Camera* camera();
virtual void update(double deltaTime) = 0;
protected:
/**
Inner class that acts as a smoothing filter to a variable. The filter has a step
response on a form that resembles the function y = 1-e^(-t/scale). The variable
will be updates as soon as it is set to a value (calling the set() function).
*/
template <typename T, typename ScaleType>
class delayedVariable {
public:
delayedVariable(ScaleType scale) {
_scale = scale;
}
void set(T value) {
_targetValue = value;
_currentValue = _currentValue + (_targetValue - _currentValue) * _scale;
}
T get() {
return _currentValue;
}
private:
ScaleType _scale;
T _targetValue;
T _currentValue;
};
struct MouseState {
MouseState(double scale)
: velocity(scale)
, previousPosition(0.0, 0.0) {}
glm::dvec2 previousPosition;
delayedVariable<glm::dvec2, double> velocity;
};
std::shared_ptr<InputState> _inputState;
SceneGraphNode* _focusNode;
Camera* _camera;
};
class OrbitalInteractionMode : public InteractionMode
{
public:
OrbitalInteractionMode(
std::shared_ptr<InputState> inputState,
double sensitivity,
double velocityScaleFactor);
~OrbitalInteractionMode();
virtual void update(double deltaTime);
private:
void updateMouseStatesFromInput(double deltaTime);
void updateCameraStateFromMouseStates();
double _sensitivity;
MouseState _globalRotationMouseState;
MouseState _localRotationMouseState;
MouseState _truckMovementMouseState;
MouseState _rollMouseState;
glm::dquat _localCameraRotation;
glm::dquat _globalCameraRotation;
};
class InteractionHandler : public properties::PropertyOwner
{
public:
InteractionHandler();
~InteractionHandler();
// Mutators
void setKeyboardController(KeyboardController* controller);
void setMouseController(MouseController* controller);
void setFocusNode(SceneGraphNode* node);
void setCamera(Camera* camera);
void resetKeyBindings();
void addKeyframe(const network::datamessagestructures::PositionKeyframe &kf);
void clearKeyframes();
void bindKey(Key key, KeyModifier modifier, std::string lua);
void lockControls();
void unlockControls();
void update(double deltaTime);
// Accessors
const SceneGraphNode* const focusNode() const;
const Camera* const camera() const;
/**
* Returns the Lua library that contains all Lua functions available to affect the
* interaction. The functions contained are
* - openspace::luascriptfunctions::setOrigin
* \return The Lua library that contains all Lua functions available to affect the
* interaction
*/
static scripting::ScriptEngine::LuaLibrary luaLibrary();
// Callback functions
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
void mouseButtonCallback(MouseButton button, MouseAction action);
void mousePositionCallback(double x, double y);
void mouseScrollWheelCallback(double pos);
private:
std::multimap<KeyWithModifier, std::string > _keyLua;
std::shared_ptr<InteractionMode> _interactor;
std::shared_ptr<InputState> _inputState;
// Properties
properties::StringProperty _origin;
properties::StringProperty _coordinateSystem;
};
#endif // USE_OLD_INTERACTIONHANDLER
} // namespace interaction
} // namespace openspace
+155 -151
View File
@@ -39,171 +39,175 @@
#include <glm/gtc/quaternion.hpp>
namespace openspace {
/**
This class still needs some more love. Suggested improvements:
- Remove psc from the camera class interface.
- Accessors should return constant references to double precision class members.
- Remove the scaling variable (What is it used for?)
- Remove the maxFov and sinMaxfov variables. Redundant since the fov is embedded
within the perspective projection matrix.
- Remove focusposition, part of the integration with the scale graph. The
"focus position" should not be needed since we assume the camera is always
positioned relative to its origin. When orbiting another object (not in origin),
the focus position should probably be handled outside the camera class
(interaction handler) since it does not affect the state of the camera
(only how it interacts).
- The class might need some more reasonable accessors depending on use cases.
(up vector world space?)
- Make clear which function returns a combined view matrix (things that are
dependent on the separate sgct nodes).
*/
class Camera {
/**
Used to explicitly show which variables within the Camera class that are used
for caching.
*/
template<typename T>
struct Cached
{
Cached() { isDirty = true; }
T datum;
bool isDirty;
};
class Camera {
public:
Camera();
Camera(const Camera& o)
: sgctInternal(o.sgctInternal)
, _viewDirectionInCameraSpace(o._viewDirectionInCameraSpace)
, _focusPosition(o._focusPosition)
, _viewDirection(o._viewDirection)
, _lookUp(o._lookUp)
, _viewRotationMatrix(o._viewRotationMatrix)
, _scaling(o._scaling)
, _position(o._position)
, _maxFov(o._maxFov)
, _sinMaxFov(o._sinMaxFov)
{ }
~Camera();
// MUTATORS (SETTERS)
void setPosition(psc pos);
void setFocusPosition(psc pos);
void setRotation(glm::quat rotation);
void setLookUpVector(glm::vec3 lookUp);
void setScaling(glm::vec2 scaling);
void setMaxFov(float fov);
// RELATIVE MUTATORS
void rotate(const glm::quat& rotation);
// ACCESSORS (GETTERS)
const psc& position() const;
const psc& unsynchedPosition() const;
const psc& focusPosition() const;
const glm::vec3& viewDirection() const;
const glm::vec3& lookUpVector() const;
const glm::vec2& scaling() const;
float maxFov() const;
float sinMaxFov() const;
const glm::mat4& viewRotationMatrix() const;
//@TODO this should simply be called viewMatrix!
//Rename after removing deprecated methods
const glm::mat4& combinedViewMatrix() const;
// DEPRECATED ACCESSORS (GETTERS)
// @TODO use Camera::SgctInternal interface instead
[[deprecated("Replaced by Camera::SgctInternal::viewMatrix()")]]
const glm::mat4& viewMatrix() const;
[[deprecated("Replaced by Camera::SgctInternal::projectionMatrix()")]]
const glm::mat4& projectionMatrix() const;
[[deprecated("Replaced by Camera::SgctInternal::viewProjectionMatrix()")]]
const glm::mat4& viewProjectionMatrix() const;
// SYNCHRONIZATION
void postSynchronizationPreDraw();
void preSynchronization();
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
// Handles SGCT's internal matrices. Also caches a calculated viewProjection matrix.
class SgctInternal {
friend class Camera;
// now working with float precision. To be changed to double later.
// The reason double does not work yet is because of the setUniform function
// in ghoul::opengl
typedef glm::quat Quat;
typedef glm::mat4 Mat4;
typedef glm::vec3 Vec3;
// Static constants
static const Vec3 _VIEW_DIRECTION_CAMERA_SPACE;
static const Vec3 _LOOKUP_VECTOR_CAMERA_SPACE;
public:
Camera();
Camera(const Camera& o);
~Camera();
// Mutators
void setPositionVec3(Vec3 pos);
void setFocusPositionVec3(Vec3 pos);
void setRotation(Quat rotation);
void setScaling(glm::vec2 scaling);
void setMaxFov(float fov);
// Relative mutators
void rotate(Quat rotation);
// Accessors
// Remove Vec3 from the name when psc is gone
const Vec3& positionVec3() const;
const Vec3& unsynchedPositionVec3() const;
const Vec3& focusPositionVec3() const;
// Should return const refs
const Vec3& viewDirectionWorldSpace() const;
const Vec3& lookUpVectorCameraSpace() const;
const Vec3& lookUpVectorWorldSpace() const;
const glm::vec2& scaling() const;
const Mat4& viewRotationMatrix() const;
const Quat& rotationQuaternion() const;
float maxFov() const;
float sinMaxFov() const;
// @TODO this should simply be called viewMatrix!
// Or it needs to be changed so that it actually is combined. Right now it is
// only the view matrix that is the same for all SGCT cameras.
const Mat4& combinedViewMatrix() const;
void setViewMatrix(glm::mat4 viewMatrix);
void setProjectionMatrix(glm::mat4 projectionMatrix);
// Synchronization
void postSynchronizationPreDraw();
void preSynchronization();
void serialize(SyncBuffer* syncBuffer);
void deserialize(SyncBuffer* syncBuffer);
/**
Handles SGCT's internal matrices. Also caches a calculated viewProjection
matrix. This is the data that is different for different cameras within
SGCT.
*/
class SgctInternal {
friend class Camera;
public:
void setViewMatrix(glm::mat4 viewMatrix);
void setProjectionMatrix(glm::mat4 projectionMatrix);
const glm::mat4& viewMatrix() const;
const glm::mat4& projectionMatrix() const;
const glm::mat4& viewProjectionMatrix() const;
private:
SgctInternal();
SgctInternal(const SgctInternal& o)
: _viewMatrix(o._viewMatrix)
, _projectionMatrix(o._projectionMatrix)
, _cachedViewProjectionMatrix(o._cachedViewProjectionMatrix)
{}
// State
glm::mat4 _viewMatrix;
glm::mat4 _projectionMatrix;
// Cache
mutable Cached<glm::mat4> _cachedViewProjectionMatrix;
mutable std::mutex _mutex;
} sgctInternal;
// Deprecated
[[deprecated("Replaced by Camera::setPositionVec3()")]]
void setPosition(psc pos);
[[deprecated("Replaced by Camera::setFocusPositionVec3()")]]
void setFocusPosition(psc pos);
[[deprecated("Replaced by Camera::positionVec3()")]]
psc position() const;
[[deprecated("Replaced by Camera::unsynchedPositionVec3()")]]
psc unsynchedPosition() const;
[[deprecated("Replaced by Camera::focusPositionVec3()")]]
psc focusPosition() const;
// @TODO use Camera::SgctInternal interface instead
[[deprecated("Replaced by Camera::SgctInternal::viewMatrix()")]]
const glm::mat4& viewMatrix() const;
[[deprecated("Replaced by Camera::SgctInternal::projectionMatrix()")]]
const glm::mat4& projectionMatrix() const;
[[deprecated("Replaced by Camera::SgctInternal::viewProjectionMatrix()")]]
const glm::mat4& viewProjectionMatrix() const;
private:
SgctInternal();
SgctInternal(const SgctInternal& o)
: _viewMatrix(o._viewMatrix)
, _projectionMatrix(o._projectionMatrix)
, _dirtyViewProjectionMatrix(o._dirtyViewProjectionMatrix)
, _viewProjectionMatrix(o._viewProjectionMatrix)
{}
/**
Class encapsulating data that needs to be synched between SGCT nodes.
Are all three variables (i.e. local, shared, synced) really neccessary? /EB
*/
template <typename T>
struct SyncData {
SyncData() {}
SyncData(const SyncData& d)
: local(d.local), shared(d.shared), synced(d.synced) {}
glm::mat4 _viewMatrix;
glm::mat4 _projectionMatrix;
void serialize(SyncBuffer* syncBuffer) { syncBuffer->encode(shared); }
void deserialize(SyncBuffer* syncBuffer) { syncBuffer->decode(shared); }
void postSynchronizationPreDraw() { synced = shared; }
void preSynchronization() { shared = local; }
T local;
T shared;
T synced;
};
// State of the camera
SyncData<Vec3> _position;
SyncData<Quat> _rotation;
SyncData<glm::vec2> _scaling;
// _focusPosition to be removed
Vec3 _focusPosition;
float _maxFov;
// Cached data
mutable Cached<Vec3> _cachedViewDirection;
mutable Cached<Mat4> _cachedViewRotationMatrix;
mutable Cached<Mat4> _cachedCombinedViewMatrix;
mutable Cached<float> _cachedSinMaxFov;
mutable bool _dirtyViewProjectionMatrix;
mutable glm::mat4 _viewProjectionMatrix;
mutable std::mutex _mutex;
} sgctInternal;
private:
// Defines what direction in local camera space the camera is looking in.
const glm::vec3 _viewDirectionInCameraSpace;
psc _focusPosition;
glm::vec3 _viewDirection;
glm::vec3 _lookUp;
// Class encapsulating the synced data. Are all three variables
// (i.e. local, shared, synced) really neccessary? /EB
template <typename T>
struct SyncData {
SyncData() {}
// copy constructor
SyncData(const SyncData& d)
: local(d.local), shared(d.shared), synced(d.synced) {}
void serialize(SyncBuffer* syncBuffer) { syncBuffer->encode(shared); }
void deserialize(SyncBuffer* syncBuffer) { syncBuffer->decode(shared); }
void postSynchronizationPreDraw() { synced = shared; }
void preSynchronization() { shared = local; }
T local;
T shared;
T synced;
};
SyncData<glm::mat4> _viewRotationMatrix;
SyncData<glm::vec2> _scaling;
SyncData<psc> _position;
float _maxFov;
float _sinMaxFov;
mutable std::mutex _mutex;
};
} // namespace openspace
#endif // __CAMERA_H__
#endif // __CAMERA_H__
@@ -347,7 +347,6 @@ void RenderableModelProjection::render(const RenderData& data) {
_frameCount++;
_camScaling = data.camera.scaling();
_up = data.camera.lookUpVector();
if (_capture && _performProjection)
project();
@@ -575,7 +575,6 @@ void RenderablePlanetProjection::render(const RenderData& data) {
clearAllProjections();
_camScaling = data.camera.scaling();
_up = data.camera.lookUpVector();
if (_capture && _performProjection)
project();
+436 -16
View File
@@ -34,6 +34,8 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/interpolator.h>
#include <glm/gtx/quaternion.hpp>
namespace {
const std::string _loggerCat = "InteractionHandler";
}
@@ -43,12 +45,15 @@ namespace {
namespace openspace {
namespace interaction {
#ifdef USE_OLD_INTERACTIONHANDLER
InteractionHandler::InteractionHandler()
: properties::PropertyOwner()
, _camera(nullptr)
, _focusNode(nullptr)
, _deltaTime(0.0)
, _validKeyLua(false)
//, _validKeyLua(false)
, _controllerSensitivity(1.f)
, _invertRoll(true)
, _invertRotation(false)
@@ -160,9 +165,9 @@ void InteractionHandler::update(double deltaTime) {
_keyframeMutex.unlock();
if(hasKeys){
_camera->setPosition(pos);
_camera->setRotation(q);
if (hasKeys) {
_camera->setPosition(pos);
_camera->setRotation(q);
}
@@ -183,7 +188,7 @@ void InteractionHandler::setFocusNode(SceneGraphNode* node) {
psc focusPos = node->worldPosition();
psc camToFocus = focusPos - _camera->position();
glm::vec3 viewDir = glm::normalize(camToFocus.vec3());
glm::vec3 cameraView = glm::normalize(_camera->viewDirection());
glm::vec3 cameraView = glm::normalize(_camera->viewDirectionWorldSpace());
//set new focus position
_camera->setFocusPosition(node->worldPosition());
float dot = glm::dot(viewDir, cameraView);
@@ -240,10 +245,15 @@ void InteractionHandler::mouseScrollWheelCallback(double pos) {
void InteractionHandler::orbit(const float &dx, const float &dy, const float &dz, const float &dist){
lockControls();
glm::vec3 cameraUp = glm::normalize((glm::inverse(_camera->viewRotationMatrix()) * glm::vec4(_camera->lookUpVector(), 0))).xyz();
glm::vec3 cameraRight = glm::cross(_camera->viewDirection(), cameraUp);
lockControls();
glm::vec3 cameraUp = glm::normalize((glm::inverse(_camera->viewRotationMatrix()) * glm::vec4(_camera->lookUpVectorCameraSpace(), 0))).xyz();
glm::vec3 cameraRight = glm::cross(glm::vec3(_camera->viewDirectionWorldSpace()), cameraUp);
glm::mat4 transform;
transform = glm::rotate(glm::radians(dx * 100.f), cameraUp) * transform;
transform = glm::rotate(glm::radians(dy * 100.f), cameraRight) * transform;
transform = glm::rotate(glm::radians(dz * 100.f), glm::vec3(_camera->viewDirectionWorldSpace())) * transform;
//get "old" focus position
@@ -342,7 +352,7 @@ void InteractionHandler::orbitDelta(const glm::quat& rotation)
//relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation);
relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4();
relative = relative_origin_coordinate + origin;
glm::mat4 la = glm::lookAt(_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _camera->lookUpVector()));
glm::mat4 la = glm::lookAt(_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, glm::vec3(_camera->lookUpVectorCameraSpace())));
unlockControls();
@@ -351,7 +361,7 @@ void InteractionHandler::orbitDelta(const glm::quat& rotation)
//camera_->setRotation(glm::mat4_cast(rotation));
_camera->setRotation(la);
_camera->setRotation(glm::quat_cast(la));
//camera_->setLookUpVector();
@@ -456,21 +466,21 @@ void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActi
}
// iterate over key bindings
_validKeyLua = true;
//_validKeyLua = true;
auto ret = _keyLua.equal_range({ key, modifier });
for (auto it = ret.first; it != ret.second; ++it) {
//OsEng.scriptEngine()->runScript(it->second);
OsEng.scriptEngine().queueScript(it->second);
if (!_validKeyLua) {
break;
}
//if (!_validKeyLua) {
// break;
//}
}
}
}
void InteractionHandler::resetKeyBindings() {
_keyLua.clear();
_validKeyLua = false;
//_validKeyLua = false;
}
void InteractionHandler::bindKey(Key key, KeyModifier modifier, std::string lua) {
@@ -601,5 +611,415 @@ void InteractionHandler::clearKeyframes(){
_keyframeMutex.unlock();
}
#else // USE_OLD_INTERACTIONHANDLER
// InputState
InputState::InputState() {
}
InputState::~InputState() {
}
void InputState::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) {
if (action == KeyAction::Press) {
_keysDown.push_back(std::pair<Key, KeyModifier>(key, modifier));
}
else if (action == KeyAction::Release) {
// Remove all key pressings for 'key'
_keysDown.remove_if([key](std::pair<Key, KeyModifier> keyModPair)
{ return keyModPair.first == key; });
}
}
void InputState::mouseButtonCallback(MouseButton button, MouseAction action) {
if (action == MouseAction::Press) {
_mouseButtonsDown.push_back(button);
}
else if (action == MouseAction::Release) {
// Remove all key pressings for 'button'
_mouseButtonsDown.remove_if([button](MouseButton buttonInList)
{ return button == buttonInList; });
}
}
void InputState::mousePositionCallback(double mouseX, double mouseY) {
_mousePosition = glm::dvec2(mouseX, mouseY);
}
void InputState::mouseScrollWheelCallback(double mouseScrollDelta) {
_mouseScrollDelta = mouseScrollDelta;
}
const std::list<std::pair<Key, KeyModifier> >& InputState::getPressedKeys() {
return _keysDown;
}
const std::list<MouseButton>& InputState::getPressedMouseButtons() {
return _mouseButtonsDown;
}
glm::dvec2 InputState::getMousePosition() {
return _mousePosition;
}
double InputState::getMouseScrollDelta() {
return _mouseScrollDelta;
}
bool InputState::isKeyPressed(std::pair<Key, KeyModifier> keyModPair) {
for (auto it = _keysDown.begin(); it != _keysDown.end(); it++) {
if (*it == keyModPair) {
return true;
}
}
return false;
}
bool InputState::isMouseButtonPressed(MouseButton mouseButton) {
for (auto it = _mouseButtonsDown.begin(); it != _mouseButtonsDown.end(); it++) {
if (*it == mouseButton) {
return true;
}
}
return false;
}
// InteractionMode
InteractionMode::InteractionMode(std::shared_ptr<InputState> inputState)
: _inputState(inputState)
, _focusNode(nullptr)
, _camera(nullptr) {
}
InteractionMode::~InteractionMode() {
}
void InteractionMode::setFocusNode(SceneGraphNode* focusNode) {
_focusNode = focusNode;
}
void InteractionMode::setCamera(Camera* camera) {
_camera = camera;
}
SceneGraphNode* InteractionMode::focusNode() {
return _focusNode;
}
Camera* InteractionMode::camera() {
return _camera;
}
// OrbitalInteractionMode
OrbitalInteractionMode::OrbitalInteractionMode(
std::shared_ptr<InputState> inputState,
double sensitivity,
double velocityScaleFactor)
: InteractionMode(inputState)
, _sensitivity(sensitivity)
, _globalRotationMouseState(velocityScaleFactor)
, _localRotationMouseState(velocityScaleFactor)
, _truckMovementMouseState(velocityScaleFactor)
, _rollMouseState(velocityScaleFactor) {
}
OrbitalInteractionMode::~OrbitalInteractionMode() {
}
void OrbitalInteractionMode::updateMouseStatesFromInput(double deltaTime) {
glm::dvec2 mousePosition = _inputState->getMousePosition();
bool button1Pressed = _inputState->isMouseButtonPressed(MouseButton::Button1);
bool button2Pressed = _inputState->isMouseButtonPressed(MouseButton::Button2);
bool button3Pressed = _inputState->isMouseButtonPressed(MouseButton::Button3);
bool keyCtrlPressed = _inputState->isKeyPressed(
std::pair<Key, KeyModifier>(Key::LeftControl, KeyModifier::Control));
// Update the mouse states
if (button1Pressed) {
if (keyCtrlPressed) {
glm::dvec2 mousePositionDelta =
_localRotationMouseState.previousPosition - mousePosition;
_localRotationMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity);
}
else {
glm::dvec2 mousePositionDelta =
_globalRotationMouseState.previousPosition - mousePosition;
_globalRotationMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity);
}
}
else { //!button1Pressed
_globalRotationMouseState.previousPosition = mousePosition;
_localRotationMouseState.previousPosition = mousePosition;
_globalRotationMouseState.velocity.set(glm::dvec2(0, 0));
_localRotationMouseState.velocity.set(glm::dvec2(0, 0));
}
if (button2Pressed) {
glm::dvec2 mousePositionDelta =
_truckMovementMouseState.previousPosition - mousePosition;
_truckMovementMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity);
}
else { // !button2Pressed
_truckMovementMouseState.previousPosition = mousePosition;
_truckMovementMouseState.velocity.set(glm::dvec2(0, 0));
}
if (button3Pressed) {
glm::dvec2 mousePositionDelta =
_rollMouseState.previousPosition - mousePosition;
_rollMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity);
}
else { // !button3Pressed
_rollMouseState.previousPosition = mousePosition;
_rollMouseState.velocity.set(glm::dvec2(0, 0));
}
}
void OrbitalInteractionMode::updateCameraStateFromMouseStates() {
if (_focusNode) {
// Declare variables to use in interaction calculations
glm::dvec3 centerPos = _focusNode->worldPosition().dvec3();
glm::dvec3 camPos = _camera->positionVec3();
glm::dvec3 posDiff = camPos - centerPos;
glm::dvec3 newPosition = camPos;
{ // Do local rotation
glm::dvec3 eulerAngles(_localRotationMouseState.velocity.get().y, 0, 0);
glm::dquat rotationDiff = glm::dquat(eulerAngles);
_localCameraRotation = _localCameraRotation * rotationDiff;
}
{ // Do global rotation
glm::dvec3 eulerAngles(
-_globalRotationMouseState.velocity.get().y,
-_globalRotationMouseState.velocity.get().x,
0);
glm::dquat rotationDiffCamSpace = glm::dquat(eulerAngles);
glm::dquat newRotationCamspace =
_globalCameraRotation * rotationDiffCamSpace;
glm::dquat rotationDiffWorldSpace =
newRotationCamspace * glm::inverse(_globalCameraRotation);
glm::dvec3 rotationDiffVec3 = posDiff * rotationDiffWorldSpace - posDiff;
newPosition = camPos + rotationDiffVec3;
glm::dvec3 lookUp = _camera->lookUpVectorWorldSpace();
glm::dmat4 lookAtMat = glm::lookAt(
glm::dvec3(0, 0, 0),
glm::normalize(centerPos - newPosition),
lookUp);
_globalCameraRotation =
glm::normalize(glm::quat_cast(glm::inverse(lookAtMat)));
}
{ // Move position towards or away from focus node
newPosition += -posDiff * _truckMovementMouseState.velocity.get().y;
}
{ // Do roll
glm::dquat cameraRollRotation =
glm::angleAxis(_rollMouseState.velocity.get().x, glm::normalize(posDiff));
_globalCameraRotation = cameraRollRotation * _globalCameraRotation;
}
// Update the camera state
_camera->setRotation(_globalCameraRotation * _localCameraRotation);
_camera->setPositionVec3(newPosition);
}
}
void OrbitalInteractionMode::update(double deltaTime) {
updateMouseStatesFromInput(deltaTime);
updateCameraStateFromMouseStates();
}
// InteractionHandler
InteractionHandler::InteractionHandler()
: _origin("origin", "Origin", "")
, _coordinateSystem("coordinateSystem", "Coordinate System", "") {
setName("Interaction");
_origin.onChange([this]() {
SceneGraphNode* node = sceneGraphNode(_origin.value());
if (!node) {
LWARNING("Could not find a node in scenegraph called '" << _origin.value() << "'");
return;
}
setFocusNode(node);
});
addProperty(_origin);
_coordinateSystem.onChange([this]() {
OsEng.renderEngine().changeViewPoint(_coordinateSystem.value());
});
addProperty(_coordinateSystem);
_inputState = std::shared_ptr<InputState>(new InputState());
_interactor = std::shared_ptr<InteractionMode>(
new OrbitalInteractionMode(_inputState, 0.002, 0.02));
}
InteractionHandler::~InteractionHandler() {
}
void InteractionHandler::setKeyboardController(KeyboardController* controller) {
//_interactor->setKeyboardController(controller);
}
void InteractionHandler::setMouseController(MouseController* controller) {
//_interactor->setMouseController(controller);
}
void InteractionHandler::setFocusNode(SceneGraphNode* node) {
_interactor->setFocusNode(node);
}
void InteractionHandler::setCamera(Camera* camera) {
_interactor->setCamera(camera);
}
void InteractionHandler::lockControls() {
}
void InteractionHandler::unlockControls() {
}
void InteractionHandler::update(double deltaTime) {
_interactor->update(deltaTime);
}
const SceneGraphNode* const InteractionHandler::focusNode() const {
return _interactor->focusNode();
}
const Camera* const InteractionHandler::camera() const {
return _interactor->camera();
}
void InteractionHandler::mouseButtonCallback(MouseButton button, MouseAction action) {
_inputState->mouseButtonCallback(button, action);
}
void InteractionHandler::mousePositionCallback(double x, double y) {
_inputState->mousePositionCallback(x, y);
}
void InteractionHandler::mouseScrollWheelCallback(double pos) {
_inputState->mouseScrollWheelCallback(pos);
}
void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) {
_inputState->keyboardCallback(key, modifier, action);
if (action == KeyAction::Press || action == KeyAction::Repeat) {
// iterate over key bindings
auto ret = _keyLua.equal_range({ key, modifier });
for (auto it = ret.first; it != ret.second; ++it) {
//OsEng.scriptEngine()->runScript(it->second);
OsEng.scriptEngine().queueScript(it->second);
}
}
}
void InteractionHandler::resetKeyBindings() {
_keyLua.clear();
}
void InteractionHandler::bindKey(Key key, KeyModifier modifier, std::string lua) {
_keyLua.insert({
{ key, modifier },
lua
});
}
scripting::ScriptEngine::LuaLibrary InteractionHandler::luaLibrary() {
return{
"",
{
{
"clearKeys",
&luascriptfunctions::clearKeys,
"",
"Clear all key bindings"
},
{
"bindKey",
&luascriptfunctions::bindKey,
"string, string",
"Binds a key by name to a lua string command"
},
{
"dt",
&luascriptfunctions::dt,
"",
"Get current frame time"
},
{
"distance",
&luascriptfunctions::distance,
"number",
"Change distance to origin",
true
},
{
"setInteractionSensitivity",
&luascriptfunctions::setInteractionSensitivity,
"number",
"Sets the global interaction sensitivity"
},
{
"interactionSensitivity",
&luascriptfunctions::interactionSensitivity,
"",
"Gets the current global interaction sensitivity"
},
{
"setInvertRoll",
&luascriptfunctions::setInvertRoll,
"bool",
"Sets the setting if roll movements are inverted"
},
{
"invertRoll",
&luascriptfunctions::invertRoll,
"",
"Returns the status of roll movement inversion"
},
{
"setInvertRotation",
&luascriptfunctions::setInvertRotation,
"bool",
"Sets the setting if rotation movements are inverted"
},
{
"invertRotation",
&luascriptfunctions::invertRotation,
"",
"Returns the status of rotation movement inversion"
}
}
};
}
void InteractionHandler::addKeyframe(const network::datamessagestructures::PositionKeyframe &kf) {
}
void InteractionHandler::clearKeyframes() {
}
#endif // USE_OLD_INTERACTIONHANDLER
} // namespace interaction
} // namespace openspace
+13 -10
View File
@@ -117,12 +117,13 @@ int clearKeys(lua_State* L) {
* Get current frame time
*/
int dt(lua_State* L) {
/*
int nArguments = lua_gettop(L);
if (nArguments != 0)
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
lua_pushnumber(L,OsEng.interactionHandler().deltaTime());
return 1;
*/return 1;
}
/**
@@ -131,6 +132,7 @@ int dt(lua_State* L) {
* Change distance to origin
*/
int distance(lua_State* L) {
/*
int nArguments = lua_gettop(L);
if (nArguments != 2)
return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments);
@@ -139,6 +141,7 @@ int distance(lua_State* L) {
double d2 = luaL_checknumber(L, -1);
PowerScaledScalar dist(static_cast<float>(d1), static_cast<float>(d2));
OsEng.interactionHandler().distanceDelta(dist);
*/
return 0;
}
@@ -153,7 +156,7 @@ int setInteractionSensitivity(lua_State* L) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
float sensitivity = static_cast<float>(luaL_checknumber(L, -1));
OsEng.interactionHandler().setInteractionSensitivity(sensitivity);
//OsEng.interactionHandler().setInteractionSensitivity(sensitivity);
return 0;
}
@@ -163,8 +166,8 @@ int setInteractionSensitivity(lua_State* L) {
* Returns the current, global interaction sensitivity
*/
int interactionSensitivity(lua_State* L) {
float sensitivity = OsEng.interactionHandler().interactionSensitivity();
lua_pushnumber(L, sensitivity);
//float sensitivity = OsEng.interactionHandler().interactionSensitivity();
//lua_pushnumber(L, sensitivity);
return 1;
}
@@ -179,7 +182,7 @@ int setInvertRoll(lua_State* L) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
bool invert = lua_toboolean(L, -1) == 1;
OsEng.interactionHandler().setInvertRoll(invert);
//OsEng.interactionHandler().setInvertRoll(invert);
return 0;
}
@@ -189,8 +192,8 @@ int setInvertRoll(lua_State* L) {
* Returns the current setting for inversion of roll movement
*/
int invertRoll(lua_State* L) {
bool invert = OsEng.interactionHandler().invertRoll();
lua_pushboolean(L, invert);
//bool invert = OsEng.interactionHandler().invertRoll();
//lua_pushboolean(L, invert);
return 1;
}
@@ -205,7 +208,7 @@ int setInvertRotation(lua_State* L) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
bool invert = lua_toboolean(L, -1) == 1;
OsEng.interactionHandler().setInvertRotation(invert);
//OsEng.interactionHandler().setInvertRotation(invert);
return 0;
}
@@ -215,8 +218,8 @@ int setInvertRotation(lua_State* L) {
* Returns the current setting for inversion of rotation movement
*/
int invertRotation(lua_State* L) {
bool invert = OsEng.interactionHandler().invertRotation();
lua_pushboolean(L, invert);
//bool invert = OsEng.interactionHandler().invertRotation();
//lua_pushboolean(L, invert);
return 1;
}
+2
View File
@@ -44,6 +44,7 @@ namespace interaction {
void KeyboardControllerFixed::keyPressed(KeyAction action, Key key, KeyModifier modifier) {
// TODO package in script
/*
const float dt = static_cast<float>( _handler->deltaTime());
if(action == KeyAction::Press|| action == KeyAction::Repeat) {
const float speed = 2.75;
@@ -127,6 +128,7 @@ void KeyboardControllerFixed::keyPressed(KeyAction action, Key key, KeyModifier
OsEng.renderEngine().camera()->setScaling(s);
}
}
*/
/*
if (key == '1') {
SceneGraphNode* node = getSceneGraphNode("sun");
+7 -3
View File
@@ -57,7 +57,7 @@ glm::vec3 MouseController::mapToTrackball(glm::vec2 mousePos) {
glm::vec3 MouseController::mapToCamera(glm::vec3 trackballPos) {
//Get x,y,z axis vectors of current camera view
glm::vec3 currentViewYaxis = glm::normalize(_handler->camera()->lookUpVector());
glm::vec3 currentViewYaxis = glm::normalize(_handler->camera()->lookUpVectorCameraSpace());
psc viewDir = _handler->camera()->position() - _handler->focusNode()->worldPosition();
glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3());
glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis));
@@ -89,7 +89,7 @@ void MouseController::trackballRotate(int x, int y) {
if (curTrackballPos != _lastTrackballPos) {
// calculate rotation angle (in radians)
float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos);
rotationAngle *= static_cast<float>(_handler->deltaTime()) * 100.0f;
//rotationAngle *= static_cast<float>(_handler->deltaTime()) * 100.0f;
// Map trackballpos to camera
// glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos);
@@ -102,7 +102,7 @@ void MouseController::trackballRotate(int x, int y) {
glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis);
// Apply quaternion to camera
_handler->orbitDelta(quaternion);
//_handler->orbitDelta(quaternion);
_lastTrackballPos = curTrackballPos;
}
@@ -129,6 +129,7 @@ void TrackballMouseController::move(float x, float y) {
}
void TrackballMouseController::scrollWheel(int pos) {
/*
const float speed = 4.75f;
const float dt = static_cast<float>(_handler->deltaTime());
if (pos < 0) {
@@ -139,6 +140,7 @@ void TrackballMouseController::scrollWheel(int pos) {
PowerScaledScalar dist(-speed * dt, 0.0f);
_handler->distanceDelta(dist);
}
*/
}
void TrackballMouseController::update(const double& dt){
@@ -219,6 +221,7 @@ void OrbitalMouseController::scrollWheel(int pos) {
}
void OrbitalMouseController::update(const double& dt){
/*
const float interactionSpeed = OsEng.interactionHandler().interactionSensitivity();
const bool rotationInvert = OsEng.interactionHandler().invertRotation();
const bool rollInvert = OsEng.interactionHandler().invertRoll();
@@ -230,6 +233,7 @@ void OrbitalMouseController::update(const double& dt){
static_cast<float>(_middleMouseButtonDown) * static_cast<float>(dt) * _currentCursorDiff[MouseButtons::ButtonMiddle].x * interactionSpeed * (rollInvert ? -1.f : 1.f),
static_cast<float>(_rightMouseButtonDown) * static_cast<float>(dt) * _currentCursorDiff[MouseButtons::ButtonRight].y * _navigationSpeed);
//}
*/
// if (_leftMouseButtonDown){
// _handler->orbit(static_cast<float>(dt)* _currentCursorDiff[MouseButtons::ButtonLeft].x * _rotationSpeed, static_cast<float>(dt)* _currentCursorDiff[MouseButtons::ButtonLeft].y * _rotationSpeed, 0.f);
+9 -8
View File
@@ -282,10 +282,11 @@ bool RenderEngine::initializeGL() {
//const glm::vec3 upVector = corners[0] - corners[1];
//_mainCamera->setCameraDirection(glm::normalize(-viewdir));
//_mainCamera->setLookUpVector(glm::normalize(upVector));
_mainCamera->setLookUpVector(glm::vec3(0.f, 1.f, 0.f));
//_mainCamera->setCameraDirection(glm::normalize(-viewdir));
//_mainCamera->setCameraDirection(glm::vec3(0.f, 0.f, -1.f));
//_mainCamera->setLookUpVector(glm::normalize(upVector));
//_mainCamera->setLookUpVector(glm::vec3(0.f, 1.f, 0.f));
// set the initial fov to be 0.0 which means everything will be culled
//float maxFov = 0.0f;
@@ -347,9 +348,9 @@ void RenderEngine::postSynchronizationPreDraw() {
ghoul::fontrendering::FontRenderer::defaultRenderer().setWindowSize(glm::vec2(res));
}
// update and evaluate the scene starting from the root node
_sceneGraph->update({
Time::ref().currentTime(),
// update and evaluate the scene starting from the root node
_sceneGraph->update({
Time::ref().currentTime(),
Time::ref().timeJumped(),
Time::ref().deltaTime(),
_doPerformanceMeasurements
@@ -373,8 +374,8 @@ void RenderEngine::postSynchronizationPreDraw() {
}
void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix) {
_mainCamera->sgctInternal.setViewMatrix(viewMatrix);
_mainCamera->sgctInternal.setProjectionMatrix(projectionMatrix);
_mainCamera->sgctInternal.setViewMatrix(viewMatrix);
_mainCamera->sgctInternal.setProjectionMatrix(projectionMatrix);
if (!(OsEng.isMaster() && _disableMasterRendering)) {
_renderer->render(_globalBlackOutFactor, _doPerformanceMeasurements);
+4 -4
View File
@@ -301,11 +301,11 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
if (!fn) {
throw ghoul::RuntimeError("Could not find focus node");
}
// Check crash for when fn == nullptr
glm::mat4 la = glm::lookAt(glm::vec3(0,0,0), fn->worldPosition().vec3() - cameraPosition.vec3(), c->lookUpVector());
// Check crash for when fn == nullptr
glm::mat4 la = glm::lookAt(glm::vec3(0,0,0), fn->worldPosition().vec3() - cameraPosition.vec3(), c->lookUpVectorCameraSpace());
//glm::mat4 la = glm::lookAt(cameraPosition.vec3(), fn->worldPosition().vec3(), glm::vec3(c->lookUpVectorCameraSpace()));
c->setRotation(la);
c->setRotation(glm::quat_cast(la));
c->setPosition(cameraPosition);
c->setScaling(cameraScaling);
+1 -1
View File
@@ -380,7 +380,7 @@ bool SceneGraphNode::sphereInsideFrustum(const psc& s_pos, const PowerScaledScal
const Camera* camera)
{
// direction the camera is looking at in power scale
psc psc_camdir = psc(camera->viewDirection());
psc psc_camdir = psc(camera->viewDirectionWorldSpace());
// the position of the camera, moved backwards in the view direction to encapsulate
// the sphere radius
+239 -230
View File
@@ -30,235 +30,244 @@
#include <glm/gtx/vector_angle.hpp>
namespace openspace {
Camera::Camera()
: _maxFov(0.f)
, _sinMaxFov(0.f)
, _viewDirection(0,0,-1)
, _viewDirectionInCameraSpace(0.f, 0.f, -1.f)
, _focusPosition()
{
_scaling.local = glm::vec2(1.f, 0.f);
_viewRotationMatrix.local = glm::mat4(1.0f);
_position.local = psc();
}
Camera::~Camera() { }
//////////////////////////////////////////////////////////////////////////////////////////
// CAMERA MUTATORS (SETTERS) //
//////////////////////////////////////////////////////////////////////////////////////////
void Camera::setPosition(psc pos){
std::lock_guard<std::mutex> _lock(_mutex);
_position.local = std::move(pos);
}
void Camera::setFocusPosition(psc pos) {
std::lock_guard<std::mutex> _lock(_mutex);
_focusPosition = pos;
}
void Camera::setRotation(glm::quat rotation) {
std::lock_guard<std::mutex> _lock(_mutex);
_viewRotationMatrix.local = glm::mat4_cast(glm::normalize(rotation));
}
void Camera::setLookUpVector(glm::vec3 lookUp) {
std::lock_guard<std::mutex> _lock(_mutex);
_lookUp = std::move(lookUp);
}
void Camera::setScaling(glm::vec2 scaling) {
std::lock_guard<std::mutex> _lock(_mutex);
_scaling.local = std::move(scaling);
}
void Camera::setMaxFov(float fov) {
std::lock_guard<std::mutex> _lock(_mutex);
_maxFov = fov;
_sinMaxFov = sin(_maxFov);
}
//////////////////////////////////////////////////////////////////////////////////////////
// CAMERA ACCESSORS (GETTERS) //
//////////////////////////////////////////////////////////////////////////////////////////
const psc& Camera::position() const {
return _position.synced;
}
const psc& Camera::unsynchedPosition() const {
return _position.local;
}
const psc& Camera::focusPosition() const {
return _focusPosition;
}
const glm::vec3& Camera::viewDirection() const {
return _viewDirection;
}
const glm::vec3& Camera::lookUpVector() const {
return _lookUp;
}
const glm::vec2& Camera::scaling() const {
return _scaling.synced;
}
float Camera::maxFov() const {
return _maxFov;
}
float Camera::sinMaxFov() const {
return _sinMaxFov;
}
const glm::mat4& Camera::viewRotationMatrix() const {
return _viewRotationMatrix.synced;
}
const glm::mat4& Camera::combinedViewMatrix() const {
glm::vec3 cameraPosition = position().vec3();
glm::mat4 viewTransform = glm::inverse(glm::translate(glm::mat4(1.0), cameraPosition));
viewTransform = glm::mat4(viewRotationMatrix()) * viewTransform;
return viewTransform;
}
//////////////////////////////////////////////////////////////////////////////////////////
// DEPRECATED CAMERA ACCESSORS (GETTERS) //
//////////////////////////////////////////////////////////////////////////////////////////
const glm::mat4& Camera::viewMatrix() const {
return sgctInternal.viewMatrix();
}
const glm::mat4& Camera::projectionMatrix() const {
return sgctInternal.projectionMatrix();
}
const glm::mat4& Camera::viewProjectionMatrix() const {
return sgctInternal.viewProjectionMatrix();
}
//////////////////////////////////////////////////////////////////////////////////////////
// CAMERA RELATICVE MUTATORS //
//////////////////////////////////////////////////////////////////////////////////////////
void Camera::rotate(const glm::quat& rotation) {
std::lock_guard<std::mutex> _lock(_mutex);
glm::mat4 tmp = glm::mat4_cast(rotation);
_viewRotationMatrix.local = _viewRotationMatrix.local * tmp;
}
//////////////////////////////////////////////////////////////////////////////////////////
// CAMERA SYNCHRONIZATION //
//////////////////////////////////////////////////////////////////////////////////////////
void Camera::serialize(SyncBuffer* syncBuffer){
_mutex.lock();
_viewRotationMatrix.serialize(syncBuffer);
_position.serialize(syncBuffer);
_scaling.serialize(syncBuffer);
_mutex.unlock();
}
void Camera::deserialize(SyncBuffer* syncBuffer){
_mutex.lock();
_viewRotationMatrix.deserialize(syncBuffer);
_position.deserialize(syncBuffer);
_scaling.deserialize(syncBuffer);
_mutex.unlock();
}
void Camera::postSynchronizationPreDraw(){
_mutex.lock();
_viewRotationMatrix.postSynchronizationPreDraw();
_position.postSynchronizationPreDraw();
_scaling.postSynchronizationPreDraw();
glm::vec4 localViewDir = glm::vec4(_viewDirectionInCameraSpace, 0.f);
_viewDirection = (glm::inverse(_viewRotationMatrix.local) * localViewDir).xyz();
_viewDirection = glm::normalize(_viewDirection);
_mutex.unlock();
}
void Camera::preSynchronization(){
_mutex.lock();
_viewRotationMatrix.preSynchronization();
_position.preSynchronization();
_scaling.preSynchronization();
_mutex.unlock();
}
//////////////////////////////////////////////////////////////////////////////////////////
// SGCT NODE DEPENTENT //
//////////////////////////////////////////////////////////////////////////////////////////
Camera::SgctInternal::SgctInternal()
: _viewMatrix()
, _projectionMatrix()
, _dirtyViewProjectionMatrix(true)
{
}
void Camera::SgctInternal::setViewMatrix(glm::mat4 viewMatrix) {
std::lock_guard<std::mutex> _lock(_mutex);
_viewMatrix = std::move(viewMatrix);
_dirtyViewProjectionMatrix = true;
}
void Camera::SgctInternal::setProjectionMatrix(glm::mat4 projectionMatrix) {
std::lock_guard<std::mutex> _lock(_mutex);
_projectionMatrix = std::move(projectionMatrix);
_dirtyViewProjectionMatrix = true;
}
const glm::mat4& Camera::SgctInternal::viewMatrix() const {
return _viewMatrix;
}
const glm::mat4& Camera::SgctInternal::projectionMatrix() const {
return _projectionMatrix;
}
const glm::mat4& Camera::SgctInternal::viewProjectionMatrix() const {
if (_dirtyViewProjectionMatrix) {
std::lock_guard<std::mutex> _lock(_mutex);
_viewProjectionMatrix = _projectionMatrix * _viewMatrix;
_dirtyViewProjectionMatrix = false;
}
return _viewProjectionMatrix;
}
//////////////////////////////////////////////////////////////////////////////////////
// CAMERA //
//////////////////////////////////////////////////////////////////////////////////////
const Camera::Vec3 Camera::_VIEW_DIRECTION_CAMERA_SPACE = Camera::Vec3(0, 0, -1);
const Camera::Vec3 Camera::_LOOKUP_VECTOR_CAMERA_SPACE = Camera::Vec3(0, 1, 0);
Camera::Camera()
: _maxFov(0.f)
, _focusPosition()
{
_scaling.local = glm::vec2(1.f, 0.f);
_position.local = Vec3(0, 0, 0);
Vec3 eulerAngles(0, 0, 0);
_rotation.local = Quat(eulerAngles);
}
Camera::Camera(const Camera& o)
: sgctInternal(o.sgctInternal)
, _focusPosition(o._focusPosition)
, _cachedViewDirection(o._cachedViewDirection)
, _rotation(o._rotation)
, _scaling(o._scaling)
, _position(o._position)
, _maxFov(o._maxFov)
{ }
Camera::~Camera() { }
// Mutators
void Camera::setPositionVec3(Vec3 pos) {
std::lock_guard<std::mutex> _lock(_mutex);
_position.local = pos;
}
void Camera::setFocusPositionVec3(Vec3 pos) {
std::lock_guard<std::mutex> _lock(_mutex);
_focusPosition = pos;
}
void Camera::setRotation(Quat rotation) {
std::lock_guard<std::mutex> _lock(_mutex);
_rotation.local = rotation;
_cachedViewRotationMatrix.isDirty = true;
_cachedCombinedViewMatrix.isDirty = true;
}
void Camera::setScaling(glm::vec2 scaling) {
std::lock_guard<std::mutex> _lock(_mutex);
_scaling.local = std::move(scaling);
}
void Camera::setMaxFov(float fov) {
std::lock_guard<std::mutex> _lock(_mutex);
_maxFov = fov;
_cachedSinMaxFov.isDirty = true;
}
// Relative mutators
void Camera::rotate(Quat rotation) {
std::lock_guard<std::mutex> _lock(_mutex);
_rotation.local = rotation * _rotation.local;
}
// Accessors
const Camera::Vec3& Camera::positionVec3() const{
return _position.synced;
}
const Camera::Vec3& Camera::unsynchedPositionVec3() const{
return _position.local;
}
const Camera::Vec3& Camera::focusPositionVec3() const{
return _focusPosition;
}
const Camera::Vec3& Camera::viewDirectionWorldSpace() const {
if (_cachedViewDirection.isDirty) {
_cachedViewDirection.datum =
_rotation.synced * Vec3(_VIEW_DIRECTION_CAMERA_SPACE);
_cachedViewDirection.datum = glm::normalize(_cachedViewDirection.datum);
}
return _cachedViewDirection.datum;
}
const Camera::Vec3& Camera::lookUpVectorCameraSpace() const {
return _LOOKUP_VECTOR_CAMERA_SPACE;
}
const Camera::Vec3& Camera::lookUpVectorWorldSpace() const {
return glm::normalize(_rotation.synced * Vec3(_LOOKUP_VECTOR_CAMERA_SPACE));
}
const glm::vec2& Camera::scaling() const {
return _scaling.synced;
}
float Camera::maxFov() const {
return _maxFov;
}
float Camera::sinMaxFov() const {
if (_cachedSinMaxFov.isDirty) {
_cachedSinMaxFov.datum = sin(_maxFov);
}
return _cachedSinMaxFov.datum;
}
const Camera::Mat4& Camera::viewRotationMatrix() const {
if (_cachedViewRotationMatrix.isDirty) {
_cachedViewRotationMatrix.datum = glm::mat4_cast(glm::inverse(_rotation.synced));
}
return _cachedViewRotationMatrix.datum;
}
const Camera::Quat& Camera::rotationQuaternion() const {
return _rotation.synced;
}
const Camera::Mat4& Camera::combinedViewMatrix() const {
if (_cachedCombinedViewMatrix.isDirty) {
glm::vec3 cameraPosition = position().vec3();
glm::mat4 cameraTranslation =
glm::inverse(glm::translate(glm::mat4(1.0), cameraPosition));
_cachedCombinedViewMatrix.datum =
glm::mat4(viewRotationMatrix()) * cameraTranslation;
}
return _cachedCombinedViewMatrix.datum;
}
// Synchronization
void Camera::serialize(SyncBuffer* syncBuffer) {
std::lock_guard<std::mutex> _lock(_mutex);
_rotation.serialize(syncBuffer);
_position.serialize(syncBuffer);
_scaling.serialize(syncBuffer);
}
void Camera::deserialize(SyncBuffer* syncBuffer) {
std::lock_guard<std::mutex> _lock(_mutex);
_rotation.deserialize(syncBuffer);
_position.deserialize(syncBuffer);
_scaling.deserialize(syncBuffer);
}
void Camera::postSynchronizationPreDraw() {
std::lock_guard<std::mutex> _lock(_mutex);
_rotation.postSynchronizationPreDraw();
_position.postSynchronizationPreDraw();
_scaling.postSynchronizationPreDraw();
_cachedViewDirection.isDirty = true;
}
void Camera::preSynchronization() {
std::lock_guard<std::mutex> _lock(_mutex);
_rotation.preSynchronization();
_position.preSynchronization();
_scaling.preSynchronization();
}
//////////////////////////////////////////////////////////////////////////////////////
// SGCT INTERNAL //
//////////////////////////////////////////////////////////////////////////////////////
Camera::SgctInternal::SgctInternal()
: _viewMatrix()
, _projectionMatrix()
{ }
void Camera::SgctInternal::setViewMatrix(glm::mat4 viewMatrix) {
std::lock_guard<std::mutex> _lock(_mutex);
_viewMatrix = std::move(viewMatrix);
_cachedViewProjectionMatrix.isDirty = true;
}
void Camera::SgctInternal::setProjectionMatrix(glm::mat4 projectionMatrix) {
std::lock_guard<std::mutex> _lock(_mutex);
_projectionMatrix = std::move(projectionMatrix);
_cachedViewProjectionMatrix.isDirty = true;
}
const glm::mat4& Camera::SgctInternal::viewMatrix() const {
return _viewMatrix;
}
const glm::mat4& Camera::SgctInternal::projectionMatrix() const {
return _projectionMatrix;
}
const glm::mat4& Camera::SgctInternal::viewProjectionMatrix() const {
if (_cachedViewProjectionMatrix.isDirty) {
std::lock_guard<std::mutex> _lock(_mutex);
_cachedViewProjectionMatrix.datum = _projectionMatrix * _viewMatrix;
_cachedViewProjectionMatrix.isDirty = false;
}
return _cachedViewProjectionMatrix.datum;
}
// Deprecated
void Camera::setPosition(psc pos) {
std::lock_guard<std::mutex> _lock(_mutex);
_position.local = pos.dvec3();
}
void Camera::setFocusPosition(psc pos) {
std::lock_guard<std::mutex> _lock(_mutex);
_focusPosition = pos.dvec3();
}
psc Camera::position() const {
return psc(_position.synced);
}
psc Camera::unsynchedPosition() const {
return psc(_position.local);
}
psc Camera::focusPosition() const {
return psc(_focusPosition);
}
const glm::mat4& Camera::viewMatrix() const {
return sgctInternal.viewMatrix();
}
const glm::mat4& Camera::projectionMatrix() const {
return sgctInternal.projectionMatrix();
}
const glm::mat4& Camera::viewProjectionMatrix() const {
return sgctInternal.viewProjectionMatrix();
}
} // namespace openspace