Commit 944ba6ee authored by Robert Menzel's avatar Robert Menzel

added moveableobject, cameras should be based on this (TODO)

parent 5948eb2d
/***********************************************************************
* Copyright 2014 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
/*
* A moveable object is an interface for something that can be moved around and has an orientation.
* This means it has access functions for a modelmatrix containing a position and orientation as
* well as just getting the position or the rotation.
* It can be moved relative to its own orientation.
*
*
* ModelMatrix = Rotation * Translation
* ( it is translated in space and then rotated around that spot )
*
*/
#pragma once
#include <ACGL/ACGL.hh>
#include <ACGL/Math/Math.hh>
#include <glm/gtx/quaternion.hpp>
namespace ACGL{
namespace Scene{
class MoveableObject
{
public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Constructor / Destructor / save&store
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Default Constructor.
*/
MoveableObject();
/**
* Destructor.
*/
~MoveableObject() {}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set / Get the matrices:
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//
// Generic rotation and translation matrices.
//
/// Gets the orthonormal rotation matrix (mat3)
const glm::mat3 &getRotationMatrix3() const { return mRotationMatrix; }
/// Gets the inverse orthonormal rotation matrix (mat3)
glm::mat3 getInverseRotationMatrix3() const { return glm::transpose(mRotationMatrix); }
/// Gets the orthonormal rotation matrix as a mat4
glm::mat4 getRotationMatrix4() const { return glm::mat4(mRotationMatrix); }
/// Sets the rotation matrix (mat3)
void setRotationMatrix( glm::mat3 _matrix );
/// Sets the rotation matrix (mat3-part of a mat4)
void setRotationMatrix( glm::mat4 _matrix );
/// Sets the complete lookat (position and rotation)
void setLookAtMatrix( const glm::vec3 &_position, const glm::vec3 &_target, const glm::vec3 &_up );
/// Gets the translation matrix of this object (no rotational element)
glm::mat4 getTranslationMatrix4() const;
///////////////////////////////////////////////////////////////////////////////////////////
//
// Generic model matrices.
//
/// Gets the currently active view matrix (depends on stereo mode and current eye)
glm::mat4 getModelMatrix() const;
/// Gets the currently active view matrix (depends on stereo mode and current eye)
glm::mat4 getInverseModelMatrix() const;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set / Get properties that move the object around (or rotate etc.)
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Set the position of the camera.
* @param _position New position of the object.
*/
void setPosition( const glm::vec3 &_position ) { mPosition = _position; }
glm::vec3 getPosition() const { return mPosition; }
/// Moves the object by a given vector (relative to own orientation)
void move( const glm::vec3 &_vector );
void moveRight( float _distance ) { move( glm::vec3(_distance,0,0) ); }
void moveBack( float _distance ) { move( glm::vec3(0,0,_distance) ); }
void moveUp( float _distance ) { move( glm::vec3(0,_distance,0) ); }
void moveLeft( float _distance ) { move( glm::vec3(-_distance,0,0) ); }
void moveForward( float _distance ) { move( glm::vec3(0,0,-_distance) ); }
void moveDown( float _distance ) { move( glm::vec3(0,-_distance,0) ); }
/**
* Set the distance of the object to the object it's looking at.
* Will change the target!
* @param _distance New distance of the object this is pointed at.
*/
void setLookAtDistance( float _distance );
/// Gets the look-at distance
float getLookAtDistance() const { return mLookAtDistance; }
/// Will change the look at distance!
/// Will change the rotation!
/// Uses stored up-vector as reference
void setTarget( const glm::vec3 &_target ) { setTarget(_target, getUpDirection()); }
/// Will change the look at distance!
/// Will change the rotation!
/// Uses given up-vector as reference
void setTarget( const glm::vec3 &_target, const glm::vec3 &_up );
/// Gets the reconstructed target
glm::vec3 getTarget() const { return mPosition + getForwardDirection() * getLookAtDistance(); }
/// Get the unit up direction
glm::vec3 getUpDirection () const;
/// Get the unit right direction
glm::vec3 getRightDirection () const;
/// Get the unit forward direction
glm::vec3 getForwardDirection() const;
private:
/// Current position
glm::vec3 mPosition;
/// Current rotation
glm::mat3 mRotationMatrix;
/// might be used later to rotate around this position:
float mLookAtDistance;
};
} // Scene
} // ACGL
/***********************************************************************
* Copyright 2014 Computer Graphics Group RWTH Aachen University. *
* All rights reserved. *
* Distributed under the terms of the MIT License (see LICENSE.TXT). *
**********************************************************************/
#include <ACGL/Scene/MoveableObject.hh>
#include <cassert>
#include <ACGL/Math/Math.hh>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/euler_angles.hpp>
using namespace ACGL;
using namespace ACGL::Math::Functions;
using namespace ACGL::Scene;
using namespace std;
void MoveableObject::setRotationMatrix(glm::mat3 _matrix)
{
mRotationMatrix = _matrix;
assert(isOrthonormalMatrix(mRotationMatrix));
}
void MoveableObject::setRotationMatrix(glm::mat4 _matrix)
{
mRotationMatrix = glm::mat3(_matrix);
assert(isOrthonormalMatrix(mRotationMatrix));
}
void MoveableObject::setLookAtMatrix(const glm::vec3 &_position, const glm::vec3 &_target, const glm::vec3 &_up)
{
setPosition(_position);
setTarget(_target, _up);
}
glm::mat4 MoveableObject::getTranslationMatrix4() const
{
glm::mat4 trans;
trans[3][0] = -mPosition.x;
trans[3][1] = -mPosition.y;
trans[3][2] = -mPosition.z;
return trans;
}
glm::vec3 MoveableObject::getUpDirection () const
{
glm::vec3 up(mRotationMatrix[0][1], mRotationMatrix[1][1], mRotationMatrix[2][1]);
assert(glm::distance(getInverseRotationMatrix3() * glm::vec3(0.0f, 1.0f, 0.0f), up) < .01);
return up;
}
glm::vec3 MoveableObject::getRightDirection () const
{
glm::vec3 right(mRotationMatrix[0][0], mRotationMatrix[1][0], mRotationMatrix[2][0]);
assert(glm::distance(getInverseRotationMatrix3() * glm::vec3(1.0f, 0.0f, 0.0f), right) < .01);
return right;
}
glm::vec3 MoveableObject::getForwardDirection() const
{
glm::vec3 forward(-mRotationMatrix[0][2], -mRotationMatrix[1][2], -mRotationMatrix[2][2]);
assert(glm::distance(getInverseRotationMatrix3() * glm::vec3(0.0f, 0.0f, -1.0f), forward) < .01);
return forward;
}
void MoveableObject::setTarget(const glm::vec3 &_target, const glm::vec3 &_up)
{
glm::vec3 forwardVector = _target - mPosition;
mLookAtDistance = glm::length( forwardVector );
forwardVector = forwardVector / (float)mLookAtDistance; // normalize
glm::vec3 rightVector = glm::normalize(glm::cross( forwardVector, _up ));
glm::vec3 upVector = glm::cross( rightVector, forwardVector );
glm::mat3 rotMatrix;
rotMatrix[0][0] = rightVector.x;
rotMatrix[0][1] = upVector.x;
rotMatrix[0][2] = -forwardVector.x;
rotMatrix[1][0] = rightVector.y;
rotMatrix[1][1] = upVector.y;
rotMatrix[1][2] = -forwardVector.y;
rotMatrix[2][0] = rightVector.z;
rotMatrix[2][1] = upVector.z;
rotMatrix[2][2] = -forwardVector.z;
setRotationMatrix( rotMatrix );
}
void MoveableObject::setLookAtDistance(float _distance)
{
assert (_distance > 0.0f);
mLookAtDistance = _distance;
}
glm::mat4 MoveableObject::getModelMatrix() const
{
glm::mat4 m(mRotationMatrix);
m[3][0] = -(m[0][0] * mPosition.x + m[1][0] * mPosition.y + m[2][0] * mPosition.z);
m[3][1] = -(m[0][1] * mPosition.x + m[1][1] * mPosition.y + m[2][1] * mPosition.z);
m[3][2] = -(m[0][2] * mPosition.x + m[1][2] * mPosition.y + m[2][2] * mPosition.z);
assert( isApproxEqual( getRotationMatrix4() * getTranslationMatrix4(), m ) );
return m;
}
glm::mat4 MoveableObject::getInverseModelMatrix() const
{
glm::mat4 modelMatrix = getModelMatrix();
return glm::inverse( modelMatrix );
}
void MoveableObject::move( const glm::vec3 &_vector )
{
glm::mat3 inverseRotation = getInverseRotationMatrix3();
mPosition += (inverseRotation * _vector);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment