mirror of https://github.com/AxioDL/zeus.git
* Add CFrustum and SBoundingBox
This commit is contained in:
parent
bc1ff31cfb
commit
b9c8268b37
|
@ -0,0 +1,127 @@
|
|||
#ifndef CFRUSTUM_HPP
|
||||
#define CFRUSTUM_HPP
|
||||
|
||||
#include <MathLib.hpp>
|
||||
#include "SBoundingBox.hpp"
|
||||
|
||||
class CFrustum
|
||||
{
|
||||
CPlane m_planes[6];
|
||||
public:
|
||||
|
||||
inline void updatePlanes(const CTransform& modelview, const CProjection& projection)
|
||||
{
|
||||
CMatrix4f mv;
|
||||
modelview.toMatrix4f(mv);
|
||||
CMatrix4f mvp = projection.getCachedMatrix() * mv;
|
||||
CMatrix4f mvp_rm = mvp.transposed();
|
||||
|
||||
#if __SSE__
|
||||
|
||||
/* Left */
|
||||
m_planes[0].mVec128 = _mm_add_ps(mvp_rm.vec[0].mVec128, mvp_rm.vec[3].mVec128);
|
||||
|
||||
/* Right */
|
||||
m_planes[1].mVec128 = _mm_add_ps(_mm_sub_ps(CVector3f::skZero.mVec128, mvp_rm.vec[0].mVec128), mvp_rm.vec[3].mVec128);
|
||||
|
||||
/* Bottom */
|
||||
m_planes[2].mVec128 = _mm_add_ps(mvp_rm.vec[1].mVec128, mvp_rm.vec[3].mVec128);
|
||||
|
||||
/* Top */
|
||||
m_planes[3].mVec128 = _mm_add_ps(_mm_sub_ps(CVector3f::skZero.mVec128, mvp_rm.vec[1].mVec128), mvp_rm.vec[3].mVec128);
|
||||
|
||||
/* Near */
|
||||
m_planes[4].mVec128 = _mm_add_ps(mvp_rm.vec[2].mVec128, mvp_rm.vec[3].mVec128);
|
||||
|
||||
/* Far */
|
||||
m_planes[5].mVec128 = _mm_add_ps(_mm_sub_ps(CVector3f::skZero.mVec128, mvp_rm.vec[2].mVec128), mvp_rm.vec[3].mVec128);
|
||||
|
||||
#else
|
||||
/* Left */
|
||||
m_planes[0].a = mvp_rm.m[0][0] + mvp_rm.m[3][0];
|
||||
m_planes[0].b = mvp_rm.m[0][1] + mvp_rm.m[3][1];
|
||||
m_planes[0].c = mvp_rm.m[0][2] + mvp_rm.m[3][2];
|
||||
m_planes[0].d = mvp_rm.m[0][3] + mvp_rm.m[3][3];
|
||||
|
||||
/* Right */
|
||||
m_planes[1].a = -mvp_rm.m[0][0] + mvp_rm.m[3][0];
|
||||
m_planes[1].b = -mvp_rm.m[0][1] + mvp_rm.m[3][1];
|
||||
m_planes[1].c = -mvp_rm.m[0][2] + mvp_rm.m[3][2];
|
||||
m_planes[1].d = -mvp_rm.m[0][3] + mvp_rm.m[3][3];
|
||||
|
||||
/* Bottom */
|
||||
m_planes[2].a = mvp_rm.m[1][0] + mvp_rm.m[3][0];
|
||||
m_planes[2].b = mvp_rm.m[1][1] + mvp_rm.m[3][1];
|
||||
m_planes[2].c = mvp_rm.m[1][2] + mvp_rm.m[3][2];
|
||||
m_planes[2].d = mvp_rm.m[1][3] + mvp_rm.m[3][3];
|
||||
|
||||
/* Top */
|
||||
m_planes[3].a = -mvp_rm.m[1][0] + mvp_rm.m[3][0];
|
||||
m_planes[3].b = -mvp_rm.m[1][1] + mvp_rm.m[3][1];
|
||||
m_planes[3].c = -mvp_rm.m[1][2] + mvp_rm.m[3][2];
|
||||
m_planes[3].d = -mvp_rm.m[1][3] + mvp_rm.m[3][3];
|
||||
|
||||
/* Near */
|
||||
m_planes[4].a = mvp_rm.m[2][0] + mvp_rm.m[3][0];
|
||||
m_planes[4].b = mvp_rm.m[2][1] + mvp_rm.m[3][1];
|
||||
m_planes[4].c = mvp_rm.m[2][2] + mvp_rm.m[3][2];
|
||||
m_planes[4].d = mvp_rm.m[2][3] + mvp_rm.m[3][3];
|
||||
|
||||
/* Far */
|
||||
m_planes[5].a = -mvp_rm.m[2][0] + mvp_rm.m[3][0];
|
||||
m_planes[5].b = -mvp_rm.m[2][1] + mvp_rm.m[3][1];
|
||||
m_planes[5].c = -mvp_rm.m[2][2] + mvp_rm.m[3][2];
|
||||
m_planes[5].d = -mvp_rm.m[2][3] + mvp_rm.m[3][3];
|
||||
|
||||
#endif
|
||||
|
||||
m_planes[0].normalize();
|
||||
m_planes[1].normalize();
|
||||
m_planes[2].normalize();
|
||||
m_planes[3].normalize();
|
||||
m_planes[4].normalize();
|
||||
m_planes[5].normalize();
|
||||
|
||||
}
|
||||
|
||||
inline bool aabbFrustumTest(const SBoundingBox& aabb) const
|
||||
{
|
||||
CVector3f vmin, vmax;
|
||||
int i;
|
||||
for (i=0 ; i<6 ; ++i) {
|
||||
const CPlane& plane = m_planes[i];
|
||||
|
||||
/* X axis */
|
||||
if (plane.a >= 0) {
|
||||
vmin[0] = aabb.m_min[0];
|
||||
vmax[0] = aabb.m_max[0];
|
||||
} else {
|
||||
vmin[0] = aabb.m_max[0];
|
||||
vmax[0] = aabb.m_min[0];
|
||||
}
|
||||
/* Y axis */
|
||||
if (plane.b >= 0) {
|
||||
vmin[1] = aabb.m_min[1];
|
||||
vmax[1] = aabb.m_max[1];
|
||||
} else {
|
||||
vmin[1] = aabb.m_max[1];
|
||||
vmax[1] = aabb.m_min[1];
|
||||
}
|
||||
/* Z axis */
|
||||
if (plane.c >= 0) {
|
||||
vmin[2] = aabb.m_min[2];
|
||||
vmax[2] = aabb.m_max[2];
|
||||
} else {
|
||||
vmin[2] = aabb.m_max[2];
|
||||
vmax[2] = aabb.m_min[2];
|
||||
}
|
||||
float dadot = plane.vec.dot(vmax);
|
||||
if (dadot + plane.d < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // CFRUSTUM_HPP
|
|
@ -0,0 +1,92 @@
|
|||
#ifndef BOUNDINGBOX_HPP
|
||||
#define BOUNDINGBOX_HPP
|
||||
#include <MathLib.hpp>
|
||||
#include <Athena/IStreamReader.hpp>
|
||||
|
||||
struct SBoundingBox
|
||||
{
|
||||
CVector3f m_min;
|
||||
CVector3f m_max;
|
||||
|
||||
inline SBoundingBox() {}
|
||||
|
||||
SBoundingBox(const CVector3f& min, const CVector3f& max)
|
||||
: m_min(min),
|
||||
m_max(max)
|
||||
{
|
||||
}
|
||||
|
||||
SBoundingBox(const float& minX,const float& minY,const float& minZ,
|
||||
const float& maxX,const float& maxY,const float& maxZ)
|
||||
: m_min(minX, minY, minZ),
|
||||
m_max(maxX, maxY, maxZ)
|
||||
{
|
||||
}
|
||||
|
||||
inline void readBoundingBox(Athena::io::IStreamReader& in)
|
||||
{
|
||||
m_min[0] = in.readFloat();
|
||||
m_min[1] = in.readFloat();
|
||||
m_min[2] = in.readFloat();
|
||||
m_max[0] = in.readFloat();
|
||||
m_max[1] = in.readFloat();
|
||||
m_max[2] = in.readFloat();
|
||||
}
|
||||
SBoundingBox(Athena::io::IStreamReader& in) {readBoundingBox(in);}
|
||||
|
||||
inline bool intersects(SBoundingBox& other) const
|
||||
{
|
||||
if (m_max[0] < other.m_min[0]) return false;
|
||||
if (m_min[0] > other.m_max[0]) return false;
|
||||
if (m_max[1] < other.m_min[1]) return false;
|
||||
if (m_min[1] > other.m_max[1]) return false;
|
||||
if (m_max[2] < other.m_min[2]) return false;
|
||||
if (m_min[2] > other.m_max[2]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void splitX(SBoundingBox& posX, SBoundingBox& negX) const
|
||||
{
|
||||
float midX = (m_max.x - m_min.x) / 2.0 + m_min.x;
|
||||
posX.m_max = m_max;
|
||||
posX.m_min = m_min;
|
||||
posX.m_min.x = midX;
|
||||
negX.m_max = m_max;
|
||||
negX.m_max.x = midX;
|
||||
negX.m_min = m_min;
|
||||
}
|
||||
|
||||
inline void splitY(SBoundingBox& posY, SBoundingBox& negY) const
|
||||
{
|
||||
float midY = (m_max.y - m_min.y) / 2.0 + m_min.y;
|
||||
posY.m_max = m_max;
|
||||
posY.m_min = m_min;
|
||||
posY.m_min.y = midY;
|
||||
negY.m_max = m_max;
|
||||
negY.m_max.y = midY;
|
||||
negY.m_min = m_min;
|
||||
}
|
||||
|
||||
inline void splitZ(SBoundingBox& posZ, SBoundingBox& negZ) const
|
||||
{
|
||||
float midZ = (m_max.z - m_min.z) / 2.0 + m_min.z;
|
||||
posZ.m_max = m_max;
|
||||
posZ.m_min = m_min;
|
||||
posZ.m_min.z = midZ;
|
||||
negZ.m_max = m_max;
|
||||
negZ.m_max.z = midZ;
|
||||
negZ.m_min = m_min;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator ==(const SBoundingBox& left, const SBoundingBox& right)
|
||||
{
|
||||
return (left.m_min == right.m_min && left.m_max == right.m_max);
|
||||
}
|
||||
inline bool operator !=(const SBoundingBox& left, const SBoundingBox& right)
|
||||
{
|
||||
return (left.m_min != right.m_min || left.m_max != right.m_max);
|
||||
|
||||
}
|
||||
|
||||
#endif // BOUNDINGBOX_HPP
|
Loading…
Reference in New Issue