class CCamera;
Cry_Camera.h
Implements essential operations like calculation of a view-matrix and frustum-culling with simple geometric primitives (Point, Sphere, AABB, OBB). All calculation are based on the CryENGINE coordinate-system
We are using a "right-handed" coordinate systems, where the positive X-Axis points to the right, the positive Y-Axis points away from the viewer and the positive Z-Axis points up. The following illustration shows our coordinate system.
z-axis ^ | | y-axis | / | / |/ +----------------> x-axis
This same system is also used in 3D-Studio-MAX. It is not unusual for 3D-APIs like D3D9 or OpenGL to use a different coordinate system. Currently in D3D9 we use a coordinate system in which the X-Axis points to the right, the Y-Axis points down and the Z-Axis points away from the viewer. To convert from the CryEngine system into D3D9 we are just doing a clockwise rotation of pi/2 about the X-Axis. This conversion happens in the renderer.
The 6 DOFs (degrees-of-freedom) are stored in one single 3x4 matrix ("m_Matrix"). The 3 orientation-DOFs are stored in the 3x3 part and the 3 position-DOFs are stored in the translation- vector. You can use the member-functions "GetMatrix()" or "SetMatrix(Matrix34(orientation,positon))" to change or access the 6 DOFs.
There are helper-function in Cry_Math.h to create the orientation:
This function builds a 3x3 orientation matrix using a view-direction and a radiant to rotate about Y-axis. Matrix33 orientation=Matrix33::CreateOrientation( Vec3(0,1,0), 0 );
This function builds a 3x3 orientation matrix using Yaw-Pitch-Roll angles. Matrix33 orientation=CCamera::CreateOrientationYPR( Ang3(1.234f,0.342f,0) );
Cry_Camera.h
uint16 x1;
uint16 x2;
uint16 y1;
uint16 y2;
ScissorInfo();
int m_JustActivated;
Camera activated in this frame, used for disabling motion blur effect at camera changes in movies
Vec3 m_OccPosition;
Position for calculate occlusions (needed for portals rendering)
class PodArray<CCamera> * m_pMultiCamera;
maybe used for culling instead of this camera
struct IVisArea* m_pPortal;
pointer to portal used to create this camera
ScissorInfo m_ScissorInfo;
~CCamera();
void CalcScreenBounds(int * vOut, const AABB * pAABB, int nWidth, int nHeight) const;
CCamera();
static Ang3 CreateAnglesYPR(const Matrix33& m);
x-YAW y-PITCH (negative=looking down / positive=looking up) z-ROLL
If we are looking along the z-axis, its not possible to specify the x and z-angle
static Ang3 CreateAnglesYPR(const Vec3& vdir, f32 r = 0);
x-YAW y-PITCH (negative=looking down / positive=looking up) z-ROLL (its not possile to extract a "roll" from a view-vector)
if we are looking along the z-axis, its not possible to specify the rotation about the z-axis
static Matrix33 CreateOrientationYPR(const Ang3& ypr);
This function builds a 3x3 orientation matrix using YPR-angles Rotation order for the orientation-matrix is Z-X-Y. (Zaxis=YAW / Xaxis=PITCH / Yaxis=ROLL)
COORDINATE-SYSTEM z-axis ^ | | y-axis | / | / |/ +---------------> x-axis
Matrix33 orientation=CCamera::CreateOrientationYPR( Ang3(1,2,3) );
static Vec3 CreateViewdir(const Ang3& ypr);
x=yaw y=pitch z=roll (we ignore this element, since its not possible to convert the roll-component into a vector)
static Vec3 CreateViewdir(const Matrix33& m);
inline Ang3 GetAngles() const;
f32 GetAngularResolution() const;
f32 GetAsymB() const;
f32 GetAsymL() const;
f32 GetAsymR() const;
f32 GetAsymT() const;
Vec3 GetEdgeF() const;
Vec3 GetEdgeN() const;
Vec3 GetEdgeP() const;
f32 GetFarPlane() const;
f32 GetFov() const;
const Vec3& GetFPVertex(int nId) const;
get far-plane vertices
get far-plane vertices
const Plane* GetFrustumPlane(int numplane) const;
Return frustum vertices in world space
void GetFrustumVertices(Vec3 * pVerts) const;
Takes pointer to array of 8 elements
void GetFrustumVerticesCam(Vec3 * pVerts) const;
float GetHorizontalFov() const;
const Matrix34& GetMatrix() const;
void GetMemoryUsage(ICrySizer * pSizer) const;
f32 GetNearPlane() const;
const Vec3& GetNPVertex(int nId) const;
get near-plane vertices
get near-plane vertices
inline const Vec3& GetOccPos() const;
f32 GetPixelAspectRatio() const;
Vec3 GetPosition() const;
const Vec3& GetPPVertex(int nId) const;
get projection-plane vertices
f32 GetProjRatio() const;
Vec3 GetViewdir() const;
Matrix34 GetViewMatrix() const;
void GetViewPort(int & nPosX, int & nPosY, int & nSizeX, int & nSizeY) const;
int GetViewSurfaceX() const;
int GetViewSurfaceZ() const;
float GetZRangeMax() const;
float GetZRangeMin() const;
bool IsAABBVisible_E(const AABB& aabb) const;
Exact
This function checks if an AABB and the camera-frustum overlap. The AABB is assumed to be in world-space. This test can reject even such AABBs that overlap a frustum-plane far outside the view-frustum. IMPORTANT: This function is only useful if you really need exact-culling. It's about 30% slower then "IsAABBVisible_F(aabb)"
int InOut=camera.IsAABBVisible_E(aabb);
return values: CULL_EXCLUSION = AABB outside of frustum (very fast rejection-test) CULL_OVERLAP = AABB either intersects the borders of the frustum or is totally inside
uint8 IsAABBVisible_EH(const AABB& aabb) const;
Improved approach to check if an AABB and the camera-frustum overlap, or if the AABB is totally inside the camera-frustum. The AABB is assumed to be in world-space. This test can reject even such AABBs that overlap a frustum-plane far outside the view-frustum. IMPORTANT: This function is only useful if you really need exact-culling. It's about 30% slower then "IsAABBVisible_FH(aabb)"
int InOut=camera.IsAABBVisible_EH(aabb);
return values: CULL_EXCLUSION = AABB outside of frustum (very fast rejection-test) CULL_OVERLAP = AABB intersects the borders of the frustum, further checks necessary CULL_INCLUSION = AABB is complete inside the frustum, no further checks necessary
uint8 IsAABBVisible_EH(const AABB& aabb, bool * pAllInside) const;
bool IsAABBVisible_EHM(const AABB& aabb, bool * pAllInside) const;
Multi-camera
Makes culling taking into account presence of m_pMultiCamera If m_pMultiCamera exists - object is visible if at least one of cameras see's it
return values: true - box visible true - not visible
bool IsAABBVisible_EM(const AABB& aabb) const;
Makes culling taking into account presence of m_pMultiCamera If m_pMultiCamera exists - object is visible if at least one of cameras see's it
return values: true - box visible true - not visible
bool IsAABBVisible_F(const AABB& aabb) const;
AABB-frustum test Fast
Simple approach to check if an AABB and the camera-frustum overlap. The AABB is assumed to be in world-space. This is a very fast method, just one single dot-product is necessary to check an AABB against a plane. Actually there is no significant speed-different between culling a sphere or an AABB.
bool InOut=camera.IsAABBVisible_F(aabb);
return values CULL_EXCLUSION = AABB outside of frustum (very fast rejection-test) CULL_OVERLAP = AABB either intersects the borders of the frustum or is totally inside
uint8 IsAABBVisible_FH(const AABB& aabb) const;
Hierarchical approach to check if an AABB and the camera-frustum overlap, or if the AABB is totally inside the camera-frustum. The AABB is assumed to be in world-space.
int InOut=camera.IsAABBVisible_FH(aabb);
return values CULL_EXCLUSION = AABB outside of frustum (very fast rejection-test) CULL_OVERLAP = AABB intersects the borders of the frustum, further checks necessary CULL_INCLUSION = AABB is complete inside the frustum, no further checks necessary
uint8 IsAABBVisible_FH(const AABB& aabb, bool * pAllInside) const;
Hierarchical approach to check if an AABB and the camera-frustum overlap, or if the AABB is totally inside the camera-frustum. The AABB is assumed to be in world-space.
int InOut=camera.IsAABBVisible_FH(aabb);
return values CULL_EXCLUSION = AABB outside of frustum (very fast rejection-test) CULL_OVERLAP = AABB intersects the borders of the frustum, further checks necessary CULL_INCLUSION = AABB is complete inside the frustum, no further checks necessary
bool IsAABBVisible_FM(const AABB& aabb) const;
Makes culling taking into account presence of m_pMultiCamera If m_pMultiCamera exists - object is visible if at least one of cameras see's it
return values: true - box visible true - not visible
bool IsJustActivated() const;
bool IsOBBVisible_E(const Vec3& wpos, const OBB& obb, f32 uscale) const;
This function checks if an OBB and the camera-frustum overlap. This test can reject even such OBBs that overlap a frustum-plane far outside the view-frustum. IMPORTANT: It is about 10% slower then "IsOBBVisibleFast(obb)"
int InOut=camera.IsOBBVisible_E(OBB);
return values: CULL_EXCLUSION = OBB outside of frustum (very fast rejection-test) CULL_OVERLAP = OBB intersects the borders of the frustum or is totally inside
uint8 IsOBBVisible_EH(const Vec3& wpos, const OBB& obb, f32 uscale) const;
Improved approach to check if an OBB and the camera-frustum intersect, or if the OBB is totally inside the camera-frustum. The bounding-box of the OBB is assumed to be in world-space. This test can reject even such OBBs that intersect a frustum-plane far outside the view-frustum
int InOut=camera.IsOBBVisible_EH(obb);
return values: CULL_EXCLUSION = OBB outside of frustum (very fast rejection-test) CULL_OVERLAP = OBB intersects the borders of the frustum, further checks necessary CULL_INCLUSION = OBB is complete inside the frustum, no further checks necessary
bool IsOBBVisible_F(const Vec3& wpos, const OBB& obb) const;
OBB-frustum test
Fast check if an OBB and the camera-frustum overlap, using the separating-axis-theorem (SAT) The center of the OOBB is assumed to be in world-space.
even if the OBB is totally inside the frustum, this function returns CULL_OVERLAP For hierarchical frustum-culling this function is not perfect.
bool InOut=camera.IsOBBVisibleFast(obb);
return values: CULL_EXCLUSION = OBB outside of frustum (very fast rejection-test) CULL_OVERLAP = OBB and frustum intersects or OBB in totally inside frustum
uint8 IsOBBVisible_FH(const Vec3& wpos, const OBB& obb) const;
bool IsPointVisible(const Vec3& p) const;
Check if a point lies within camera's frustum
bool IsSphereVisible_F(const Sphere & s) const;
sphere-frustum test
Conventional method to check if a sphere and the camera-frustum overlap The center of the sphere is assumed to be in world-space.
u8 InOut=camera.IsSphereVisible_F(sphere);
return values CULL_EXCLUSION = sphere outside of frustum (very fast rejection-test) CULL_INTERSECT = sphere and frustum intersects or sphere in completely inside frustum
uint8 IsSphereVisible_FH(const Sphere & s) const;
this is going to be the exact version of sphere-culling
Conventional method to check if a sphere and the camera-frustum overlap, or if the sphere is completely inside the camera-frustum. The center of the sphere is assumed to be in world-space.
u8 InOut=camera.IsSphereVisible_FH(sphere);
return values CULL_EXCLUSION = sphere outside of frustum (very fast rejection-test) CULL_INTERSECT = sphere intersects the borders of the frustum, further checks necessary CULL_INCLUSION = sphere is complete inside the frustum, no further checks necessary
bool Project(const Vec3& p, Vec3& result, Vec2i topLeft = Vec2i(0,0), Vec2i widthHeight = Vec2i(0,0)) const;
p=world space position result=spreen space pos retval=is visible on screen
void SetAngles(const Ang3 & angles);
void SetAsymmetry(float l, float r, float b, float t);
void SetFrustum(int nWidth, int nHeight, f32 FOV = DEFAULT_FOV, f32 nearplane = DEFAULT_NEAR, f32 farpane = DEFAULT_FAR, f32 fPixelAspectRatio = 1.0f);
inline void SetFrustumPlane(int i, const Plane & plane);
void SetFrustumVertices(Vec3 * arrvVerts);
OLD STUFF
void SetJustActivated(const bool justActivated);
void SetMatrix(const Matrix34& mat);
void SetMatrixNoUpdate(const Matrix34& mat);
void SetPosition(const Vec3& p);
void SetPositionNoUpdate(const Vec3& p);
void SetPPVertex(int nId, const Vec3 & vVert);
void SetViewPort(int nPosX, int nPosY, int nSizeX, int nSizeY);
void SetZRange(float zmin, float zmax);
Z-Buffer ranges. This values are defining near/far clipping plane, it only used to specify z-buffer range. Use it only when you want to override default z-buffer range. Valid values for are: 0 <= zrange <= 1
bool Unproject(const Vec3& viewportPos, Vec3& result, Vec2i topLeft = Vec2i(0,0), Vec2i widthHeight = Vec2i(0,0)) const;
void UpdateFrustum();
! *
*