Commit 7f7c8e01 authored by Robert Menzel's avatar Robert Menzel

added more string operations and GLM type from and to string conversion. added...

added more string operations and GLM type from and to string conversion. added camera load store to string
parent d97edad4
......@@ -13,6 +13,7 @@
*/
#include <ACGL/ACGL.hh>
#include <ACGL/Math/Math.hh>
#include <sstream>
#include <vector>
......@@ -23,14 +24,25 @@ namespace Base{
namespace StringOperations
{
//! splits the filename _full into the filename without the extension and just the extension
bool splitFileExtension (const std::string& _full, std::string& _file, std::string& _extension );
bool splitLastFileOrFolder (const std::string& _full, std::string& _path, std::string& _fileOrFolder);
//! returns true iff the _string starts with a given prefix
bool startsWith (const std::string& _string, const std::string& _prefix);
//! returns true iff the _string starts with a given single char prefix (quicker than the string version above)
bool startsWith (const std::string& _string, const char _prefix);
std::vector<std::string> split (const std::string& _string, char _splitChar, bool _skipEmptyStrings = true);
//! Convert a primitive type to a string (e.g. string s = toString(1.5f))
//! strips a string of all leading and trailing whitespaces (but leaves the ones in between)
std::string stripOfWhiteSpaces( const std::string &_string );
//! strips a string of all leading and trailing characters out of a given list (but leaves the ones in between)
std::string stripOfCharacters( const std::string &_string, const std::string &_charsToStrip );
//! Convert a primitive type to a string (e.g. string s = toString(1.5f)), also supports some GLM types (but not complete)
template<class T>
std::string toString(const T& _t);
......@@ -45,6 +57,14 @@ namespace StringOperations
*_OK = !stream.fail();
return t;
}
glm::uvec2 toUvec2( const std::string& _string );
glm::vec2 toVec2( const std::string& _string );
glm::vec3 toVec3( const std::string& _string );
glm::vec4 toVec4( const std::string& _string );
glm::mat3 toMat3( const std::string& _string );
}
} // Base
......
......@@ -274,6 +274,13 @@ class GenericCamera
/// Sets new viewport size and calculates new aspect ratio
void resize(int _newWidth, int _newHeight) { setViewportSize(_newWidth, _newHeight); setAspectRatio(_newWidth / (float)_newHeight); }
/// Writes all internal state to one string
std::string storeStateToString() const;
/// Sets all internal state from a string
void setStateFromString( const std::string &_state );
private:
/// the Matrix with the camera position/orientation.
/// eyeShift is the half of the eyeDistance (can be 0 if we don't want stereo)
......@@ -285,6 +292,12 @@ class GenericCamera
/// this is used for off-axis projections (value in meters, negativ for the left eye)
//glm::mat4 getPerspectiveProjectionMatrix( double _eyeShift = 0.0f );
///
/// States: update the storeStateToString() & setStateFromString() functions whenever adding a new state!
///
/// Current camera position
glm::vec3 mPosition;
......
......@@ -76,6 +76,25 @@ namespace StringOperations
return stringList;
}
std::string stripOfCharacters( const std::string &_string, const std::string &_charsToStrip )
{
size_t posOfLastNonStripChar = _string.find_last_not_of( _charsToStrip );
if ( posOfLastNonStripChar == std::string::npos ) {
return ""; // the string was empty or had only _charsToStrip!
}
size_t posOfFirstNonStripChar = _string.find_first_not_of( _charsToStrip );
// can't be npos
return _string.substr( posOfFirstNonStripChar, posOfLastNonStripChar-posOfFirstNonStripChar+1 );
}
std::string stripOfWhiteSpaces( const std::string &_string )
{
std::string whitespaces(" \t\f\v\n\r");
return stripOfCharacters( _string, whitespaces );
}
template<class T>
std::string toString(const T& _t)
{
......@@ -96,6 +115,7 @@ namespace StringOperations
template std::string toString<long_t>(const long_t& _t);
template std::string toString<ulong_t>(const ulong_t& _t);
// float vectors:
template<> std::string toString(const glm::vec2& _t)
{
std::ostringstream stream;
......@@ -116,6 +136,147 @@ namespace StringOperations
stream << "(" << _t.x << "," << _t.y << "," << _t.z << "," << _t.w << ")";
return stream.str();
}
// unsigned int vectors:
template<> std::string toString(const glm::uvec2& _t)
{
std::ostringstream stream;
stream << "(" << _t.x << "," << _t.y << ")";
return stream.str();
}
template<> std::string toString(const glm::uvec3& _t)
{
std::ostringstream stream;
stream << "(" << _t.x << "," << _t.y << "," << _t.z << ")";
return stream.str();
}
template<> std::string toString(const glm::uvec4& _t)
{
std::ostringstream stream;
stream << "(" << _t.x << "," << _t.y << "," << _t.z << "," << _t.w << ")";
return stream.str();
}
// square matrices:
template<> std::string toString(const glm::mat2& _t)
{
std::ostringstream stream;
stream << "(" << toString<glm::vec2>(_t[0]) << "," << toString<glm::vec2>(_t[1]) << ")";
return stream.str();
}
template<> std::string toString(const glm::mat3& _t)
{
std::ostringstream stream;
stream << "(" << toString<glm::vec3>(_t[0]) << "," << toString<glm::vec3>(_t[1]) << "," << toString<glm::vec3>(_t[2]) << ")";
return stream.str();
}
template<> std::string toString(const glm::mat4& _t)
{
std::ostringstream stream;
stream << "(" << toString<glm::vec4>(_t[0]) << "," << toString<glm::vec4>(_t[1]) << "," << toString<glm::vec4>(_t[2]) << "," << toString<glm::vec4>(_t[3]) << ")";
return stream.str();
}
// removes the brackets, removes whitespaces and splits at the colons:
std::vector< std::string > glmStringParserHelper( const std::string& _string )
{
std::vector< std::string > token = split( _string, ',' ); // split at ','
for (size_t i = 0; i < token.size(); i++) {
token[i] = stripOfCharacters( token[i], " \t\f\v\n\r()" ); // strip of spaces and characters in one go
}
return token;
}
// parsing of glm types:
glm::uvec2 toUvec2( const std::string& _string )
{
std::vector< std::string > token = glmStringParserHelper( _string );
if (token.size() == 2) {
unsigned int x = to<unsigned int>( token[0] );
unsigned int y = to<unsigned int>( token[1] );
return glm::uvec2( x,y );
}
ACGL::Utils::error() << "could not parse uvec2 " << _string << std::endl;
return glm::uvec2(0);
}
glm::vec2 toVec2( const std::string& _string )
{
std::vector< std::string > token = glmStringParserHelper( _string );
if (token.size() == 2) {
float x = to<float>( token[0] );
float y = to<float>( token[1] );
return glm::vec2( x,y );
}
ACGL::Utils::error() << "could not parse vec2 " << _string << std::endl;
return glm::vec2(0);
}
glm::vec3 toVec3( const std::string& _string )
{
std::vector< std::string > token = glmStringParserHelper( _string );
if (token.size() == 3) {
float x = to<float>( token[0] );
float y = to<float>( token[1] );
float z = to<float>( token[2] );
return glm::vec3( x,y,z );
}
ACGL::Utils::error() << "could not parse vec3 " << _string << std::endl;
return glm::vec3(0);
}
glm::vec4 toVec4( const std::string& _string )
{
std::vector< std::string > token = glmStringParserHelper( _string );
if (token.size() == 4) {
float x = to<float>( token[0] );
float y = to<float>( token[1] );
float z = to<float>( token[2] );
float w = to<float>( token[3] );
return glm::vec4( x,y,z,w );
}
ACGL::Utils::error() << "could not parse vec4 " << _string << std::endl;
return glm::vec4(0);
}
glm::mat3 toMat3( const std::string& _string )
{
std::vector< std::string > token = glmStringParserHelper( _string );
if (token.size() == 9) {
glm::vec3 a,b,c;
{
float x = to<float>( token[0] );
float y = to<float>( token[1] );
float z = to<float>( token[2] );
a = glm::vec3( x,y,z );
}
{
float x = to<float>( token[3] );
float y = to<float>( token[4] );
float z = to<float>( token[5] );
b = glm::vec3( x,y,z );
}
{
float x = to<float>( token[6] );
float y = to<float>( token[7] );
float z = to<float>( token[8] );
c = glm::vec3( x,y,z );
}
return glm::mat3( a,b,c );
}
ACGL::Utils::error() << "could not parse mat3 " << _string << std::endl;
return glm::mat3(0);
}
}
} // Base
......
......@@ -5,6 +5,7 @@
**********************************************************************/
#include <ACGL/Scene/GenericCamera.hh>
#include <ACGL/Base/StringOperations.hh>
#include <cassert>
......@@ -16,6 +17,7 @@
using namespace ACGL;
using namespace ACGL::Math::Functions;
using namespace ACGL::Scene;
using namespace ACGL::Base::StringOperations;
using namespace std;
GenericCamera::GenericCamera() :
......@@ -358,7 +360,7 @@ glm::mat4 GenericCamera::getMonoInverseViewMatrix() const
return m;
}
/*
glm::mat4 FrescoCamera::getStereoProjectionMatrix( bool _leftEye, StereoMode _stereoMode )
glm::mat4 GenericCamera::getStereoProjectionMatrix( bool _leftEye, StereoMode _stereoMode )
{
// ToeIn with parallel projection could work, but all the other modes wouldn't.
// But even this cambination would be very unusual, so it's not implemented.
......@@ -406,13 +408,83 @@ glm::mat4 FrescoCamera::getStereoProjectionMatrix( bool _leftEye, StereoMode _st
return projectionMatrix;
}
glm::mat4 FrescoCamera::getStereoViewMatrix( bool _leftEye, StereoMode _stereoMode )
glm::mat4 GenericCamera::getStereoViewMatrix( bool _leftEye, StereoMode _stereoMode )
{
return glm::mat4();
}
*/
/// Writes all internal state to one string
/// Elements are seperated by pipes ('|'), spaces can get ignored.
std::string GenericCamera::storeStateToString() const
{
std::string state;
state = "ACGL_GenericCamera | "; // "magic number", for every version the same
state += "1 | "; // version, always an integer
state += toString( mPosition ) + " | ";
state += toString( mRotationMatrix ) + " | ";
if ( mProjectionMode == ISOMETRIC_PROJECTION ) state += "ISOMETRIC_PROJECTION | ";
if ( mProjectionMode == PERSPECTIVE_PROJECTION ) state += "PERSPECTIVE_PROJECTION | ";
if ( mStereoMode == MONO) state += "MONO | ";
if ( mStereoMode == PARALLEL_SHIFT) state += "PARALLEL_SHIFT | ";
if ( mStereoMode == OFF_AXIS) state += "OFF_AXIS | ";
if ( mStereoMode == TOE_IN) state += "TOE_IN | ";
if ( mCurrentEye == EYE_LEFT) state += "EYE_LEFT | ";
if ( mCurrentEye == EYE_RIGHT) state += "EYE_RIGHT | ";
state += toString( mHorizontalFieldOfView ) + " | ";
state += toString( mAspectRatio ) + " | ";
state += toString( mEyeDistance ) + " | ";
state += toString( mNearClippingPlane ) + " | ";
state += toString( mFarClippingPlane ) + " | ";
state += toString( mLookAtDistance ) + " | ";
state += toString( mViewportSize );
return state;
}
/// Sets all internal state from a string
void GenericCamera::setStateFromString( const std::string &_state )
{
vector< string > token = split( _state, '|' );
for (size_t i = 0; i < token.size(); i++) {
token[i] = stripOfWhiteSpaces( token[i] );
}
if ((token.size() < 14) || (token[0] != "ACGL_GenericCamera")) {
ACGL::Utils::error() << "Generic camera state string is invalid: " << _state << std::endl;
return;
}
if ( to<int>(token[1]) != 1) {
ACGL::Utils::error() << "Generic camera state version not supported: " << to<int>(token[1]) << std::endl;
return;
}
int pos = 2;
mPosition = toVec3( token[pos++] );
mRotationMatrix = toMat3( token[pos++] );
if ( token[pos] == "ISOMETRIC_PROJECTION" ) mProjectionMode = ISOMETRIC_PROJECTION;
if ( token[pos] == "PERSPECTIVE_PROJECTION" ) mProjectionMode = PERSPECTIVE_PROJECTION;
pos++;
if ( token[pos] == "MONO") mStereoMode = MONO;
if ( token[pos] == "PARALLEL_SHIFT") mStereoMode = PARALLEL_SHIFT;
if ( token[pos] == "OFF_AXIS") mStereoMode = OFF_AXIS;
if ( token[pos] == "TOE_IN") mStereoMode = TOE_IN;
pos++;
if ( token[pos] == "EYE_LEFT") mCurrentEye = EYE_LEFT;
if ( token[pos] == "EYE_RIGHT") mCurrentEye = EYE_RIGHT;
pos++;
mHorizontalFieldOfView = to<double>( token[pos++] );
mAspectRatio = to<double>( token[pos++] );
mEyeDistance = to<float>( token[pos++] );
mNearClippingPlane = to<double>( token[pos++] );
mFarClippingPlane = to<double>( token[pos++] );
mLookAtDistance = to<double>( token[pos++] );
mViewportSize = toUvec2( token[pos++] );
}
/////////////// TESTS /////////////
......
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