Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ACGL
acgl
Commits
26d2c589
Commit
26d2c589
authored
Nov 23, 2015
by
Robert Menzel
Browse files
added more projection matrix types
parent
b2ab869d
Changes
5
Hide whitespace changes
Inline
Side-by-side
include/ACGL/Scene/CameraBase.hh
View file @
26d2c589
...
...
@@ -45,6 +45,17 @@ public:
* @return the 2-dimensional size of the viewport
*/
virtual
glm
::
uvec2
getViewportSize
()
const
=
0
;
/**
* @brief Gets the near clipping plane as a distance from the camera.
* @return the near clipping plane
*/
virtual
float
getNearClippingPlane
()
const
=
0
;
/**
* @brief Gets the far clipping plane as a distance from the camera. Note that it could be inf!
* Not all projection matrices have a real far plane but some are unlimited!
* @return the near clipping plane
*/
virtual
float
getFarClippingPlane
()
const
=
0
;
};
}
...
...
include/ACGL/Scene/FixedCamera.hh
View file @
26d2c589
...
...
@@ -6,7 +6,8 @@ namespace ACGL{
namespace
Scene
{
/**
* @brief A fixed camera
* @brief A fixed camera where all attributes are set explicitly except for the near/far plane
* which are derrived from the projection matrix.
*/
class
FixedCamera
:
public
CameraBase
{
...
...
@@ -17,6 +18,11 @@ private:
glm
::
mat4
mProjectionMatrix
;
glm
::
uvec2
mViewportSize
;
// will get calculated based on the projection matrix
// so there are no explicit setters for this!
float
mNearPlane
;
float
mFarPlane
;
public:
/// CAUTION: default ctor with zero values
FixedCamera
();
...
...
@@ -32,11 +38,15 @@ public:
// Getter, Setter for Camera ProjectionMatrix
virtual
glm
::
mat4
getProjectionMatrix
()
const
{
return
mProjectionMatrix
;
}
virtual
void
setProjectionMatrix
(
glm
::
mat4
const
&
_val
)
{
mProjectionMatrix
=
_val
;
}
virtual
void
setProjectionMatrix
(
glm
::
mat4
const
&
_val
)
;
// Getter, Setter for Camera ViewportSize
virtual
glm
::
uvec2
getViewportSize
()
const
{
return
mViewportSize
;
}
virtual
void
setViewportSize
(
glm
::
uvec2
const
&
_val
)
{
mViewportSize
=
_val
;
}
// getters for near/far plane (far can be inf!)
virtual
float
getNearClippingPlane
()
const
{
return
mNearPlane
;
}
virtual
float
getFarClippingPlane
()
const
{
return
mFarPlane
;
}
};
}
...
...
include/ACGL/Scene/GenericCamera.hh
View file @
26d2c589
...
...
@@ -57,10 +57,23 @@ class GenericCamera : public CameraBase, public MoveableObject
// Helping enums:
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// use the DX reverse mode with:
/// * an infinite far plane
/// * a float z-buffer
/// * glClearDepth(0.0)
/// * glDepthFunc(GL_GREATER)
/// * either:
/// * glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE) (DX style mapping of the Z values)
/// or:
/// * glDepthRangedNV(-1.0, 1.0)
///
/// this way near will get mapped to 1.0 and infinite to 0.0
enum
ProjectionMode
{
ISOMETRIC_PROJECTION
=
0
,
PERSPECTIVE_PROJECTION
PERSPECTIVE_PROJECTION_OPENGL
,
// maps to -1..1
PERSPECTIVE_PROJECTION_DX_REVERSE
// maps to 1..0
};
enum
StereoMode
...
...
@@ -172,16 +185,17 @@ class GenericCamera : public CameraBase, public MoveableObject
*/
void
setNearClippingPlane
(
float
_plane
);
/// Gets the near clip distance
float
getNearClippingPlane
()
const
{
return
mNearClippingPlane
;
}
virtual
float
getNearClippingPlane
()
const
{
return
mNearClippingPlane
;
}
/**
* Set the far clipping plane of the camera.
* The plane is defined only by a distance from the camera.
* This distance might be inf!
* @param _plane New far clipping plane of the camera.
*/
void
setFarClippingPlane
(
float
_plane
);
/// Gets the far clip distance
float
getFarClippingPlane
()
const
{
return
mFarClippingPlane
;
}
virtual
float
getFarClippingPlane
()
const
{
return
mFarClippingPlane
;
}
/// Gets size of the viewport
virtual
glm
::
uvec2
getViewportSize
()
const
{
return
mViewportSize
;
}
...
...
@@ -237,7 +251,6 @@ class GenericCamera : public CameraBase, public MoveableObject
/// Gets the currently active projection matrix (depends on stereo mode and current eye)
virtual
glm
::
mat4
getProjectionMatrix
()
const
;
///////////////////////////////////////////////////////////////////////////////////////////
//
// Explicit view and projection matrices. These DON'T obey the set stereo/eye settings.
...
...
src/ACGL/Scene/FixedCamera.cc
View file @
26d2c589
...
...
@@ -16,9 +16,72 @@ FixedCamera::FixedCamera()
FixedCamera
::
FixedCamera
(
const
glm
::
vec3
&
_pos
,
const
glm
::
mat4
&
_view
,
const
glm
::
mat4
&
_proj
,
const
glm
::
uvec2
&
_viewport
)
:
mPosition
(
_pos
),
mViewMatrix
(
_view
),
mProjectionMatrix
(
_proj
),
mViewportSize
(
_viewport
)
{
setProjectionMatrix
(
_proj
);
}
void
FixedCamera
::
setProjectionMatrix
(
glm
::
mat4
const
&
_val
)
{
mProjectionMatrix
=
_val
;
//
// Calculate near and far plane from the matrix
// As the matrix does not have to be a standard OpenGL
// projection matrix, we can't derrive the values from
// the matrix entries directly but we have to reproject
// points from the NDC cube... ...but as some matrices
// project to -1..1 and others to 0..1 we have to figure
// this out first... ...keeping in mind, that some also
// invert the range inside of the Z buffer, so Z=1 might
// be the near plane while Z=0 is the far plane...
// ...oh, and the far plane might be at infinity...
//
//
// First step, figure out which values project to
// -1, 0 and 1:
//
glm
::
mat4
invProj
=
glm
::
inverse
(
mProjectionMatrix
);
glm
::
vec4
tmp
=
invProj
*
glm
::
vec4
(
0.0
f
,
0.0
f
,
-
1.0
f
,
1.0
f
);
float
reproj_minusOne
=
tmp
.
z
/
tmp
.
w
;
tmp
=
invProj
*
glm
::
vec4
(
0.0
f
,
0.0
f
,
0.0
f
,
1.0
f
);
float
reproj_Zero
=
tmp
.
z
/
tmp
.
w
;
tmp
=
invProj
*
glm
::
vec4
(
0.0
f
,
0.0
f
,
1.0
f
,
1.0
f
);
float
reproj_One
=
tmp
.
z
/
tmp
.
w
;
//
// Next step, figure out which value is the near plane and which is the far plane.
//
// right handed coordinate system -> the camera was looking along the negative Z axis
// if it was an OpenGL matrix, the projections will result in -near, -something, -far
// if it was an OpenGL matrix with infinit far plane, the projections will result in -near, -something, -inf
// if it was a reverse DX style matrix it will result in +near, -inf, -near
if
(
reproj_minusOne
>
0.0
f
)
{
// near,far mapped to 1,0 or 0,1 as -1 was mapped to a positive value which is behind the camera
// if we assume we are looking along the negative Z axis!
if
(
-
reproj_Zero
>
-
reproj_One
)
{
// the far plane is mapped to 0 -> inverse DX style
mFarPlane
=
-
reproj_Zero
;
mNearPlane
=
-
reproj_One
;
}
else
{
// the near plane is mapped to zero -> DX style
mFarPlane
=
-
reproj_One
;
mNearPlane
=
-
reproj_Zero
;
}
}
else
{
// OpenGL style, mapping to -1..1 or 1..-1
if
(
-
reproj_minusOne
>
-
reproj_One
)
{
// the far plane is mapped to -1 -> inverse GL style
mFarPlane
=
-
reproj_minusOne
;
mNearPlane
=
-
reproj_One
;
}
else
{
// the near plane is mapped to -1 -> GL style
mFarPlane
=
-
reproj_One
;
mNearPlane
=
-
reproj_minusOne
;
}
}
}
}
...
...
src/ACGL/Scene/GenericCamera.cc
View file @
26d2c589
...
...
@@ -21,7 +21,7 @@ using namespace ACGL::Utils::StringHelpers;
using
namespace
std
;
GenericCamera
::
GenericCamera
()
:
mProjectionMode
(
PERSPECTIVE_PROJECTION
),
mProjectionMode
(
PERSPECTIVE_PROJECTION
_OPENGL
),
mStereoMode
(
MONO
),
mCurrentEye
(
EYE_LEFT
),
mHorizontalFieldOfView
(
75.0
),
...
...
@@ -247,10 +247,42 @@ glm::mat4 GenericCamera::getMonoProjectionMatrix() const
projectionMatrix
[
2
][
3
]
=
-
(
mFarClippingPlane
+
mNearClippingPlane
)
/
(
mFarClippingPlane
-
mNearClippingPlane
);
projectionMatrix
[
3
][
3
]
=
1.0
;
}
else
if
(
mProjectionMode
==
PERSPECTIVE_PROJECTION
)
else
if
(
mProjectionMode
==
PERSPECTIVE_PROJECTION
_OPENGL
)
{
projectionMatrix
=
glm
::
perspective
(
glm
::
radians
(
(
float
)
getHorizontalFieldOfView
()),
(
float
)
getAspectRatio
(),
(
float
)
mNearClippingPlane
,
(
float
)
mFarClippingPlane
);
if
(
std
::
isinf
(
mFarClippingPlane
))
{
float
e
=
1.0
f
/
tan
(
ACGL
::
Math
::
Functions
::
calcDegToRad
(
getVerticalFieldOfView
()
*
0.5
f
));
const
float
a
=
getAspectRatio
();
// infinite Perspective matrix reversed mapping to 1..-1
projectionMatrix
=
{
e
/
a
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
e
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
-
1.0
f
,
-
1.0
f
,
0.0
f
,
0.0
f
,
-
2.0
*
mNearClippingPlane
,
0.0
f
};
}
else
{
projectionMatrix
=
glm
::
perspective
(
glm
::
radians
(
(
float
)
getHorizontalFieldOfView
()),
(
float
)
getAspectRatio
(),
(
float
)
mNearClippingPlane
,
(
float
)
mFarClippingPlane
);
}
}
else
if
(
mProjectionMode
==
PERSPECTIVE_PROJECTION_DX_REVERSE
)
{
if
(
std
::
isinf
(
mFarClippingPlane
))
{
float
e
=
1.0
f
/
tan
(
ACGL
::
Math
::
Functions
::
calcDegToRad
(
getVerticalFieldOfView
()
*
0.5
f
));
const
float
a
=
getAspectRatio
();
// infinite Perspective matrix reversed mapping to 1..0
projectionMatrix
=
{
e
/
a
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
e
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
-
1.0
f
,
0.0
f
,
0.0
f
,
mNearClippingPlane
,
0.0
f
};
}
else
{
assert
(
0
&&
"unsupported projection mode"
);
}
}
else
assert
(
0
&&
"unsupported projection mode"
);
return
projectionMatrix
;
...
...
@@ -320,7 +352,7 @@ std::string GenericCamera::storeStateToString() const
state
+=
toString
(
mPosition
)
+
" | "
;
state
+=
toString
(
mRotationMatrix
)
+
" | "
;
if
(
mProjectionMode
==
ISOMETRIC_PROJECTION
)
state
+=
"ISOMETRIC_PROJECTION | "
;
if
(
mProjectionMode
==
PERSPECTIVE_PROJECTION
)
state
+=
"PERSPECTIVE_PROJECTION | "
;
if
(
mProjectionMode
==
PERSPECTIVE_PROJECTION
_OPENGL
)
state
+=
"PERSPECTIVE_PROJECTION | "
;
if
(
mStereoMode
==
MONO
)
state
+=
"MONO | "
;
if
(
mStereoMode
==
PARALLEL_SHIFT
)
state
+=
"PARALLEL_SHIFT | "
;
if
(
mStereoMode
==
OFF_AXIS
)
state
+=
"OFF_AXIS | "
;
...
...
@@ -358,7 +390,7 @@ void GenericCamera::setStateFromString( const std::string &_state )
mPosition
=
toVec3
(
token
[
pos
++
]
);
mRotationMatrix
=
toMat3
(
token
[
pos
++
]
);
if
(
token
[
pos
]
==
"ISOMETRIC_PROJECTION"
)
mProjectionMode
=
ISOMETRIC_PROJECTION
;
if
(
token
[
pos
]
==
"PERSPECTIVE_PROJECTION"
)
mProjectionMode
=
PERSPECTIVE_PROJECTION
;
if
(
token
[
pos
]
==
"PERSPECTIVE_PROJECTION"
)
mProjectionMode
=
PERSPECTIVE_PROJECTION
_OPENGL
;
pos
++
;
if
(
token
[
pos
]
==
"MONO"
)
mStereoMode
=
MONO
;
if
(
token
[
pos
]
==
"PARALLEL_SHIFT"
)
mStereoMode
=
PARALLEL_SHIFT
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment