/* * * * * * * * * * * * * Author's note * * * * * * * * * * * *\ * _ _ _ _ _ _ _ _ _ _ _ _ * * |_| |_| |_| |_| |_|_ _|_| |_| |_| _|_|_|_|_| * * |_|_ _ _|_| |_| |_| |_|_|_|_|_| |_| |_| |_|_ _ _ * * |_|_|_|_|_| |_| |_| |_| |_| |_| |_| |_| |_|_|_|_ * * |_| |_| |_|_ _ _|_| |_| |_| |_|_ _ _|_| _ _ _ _|_| * * |_| |_| |_|_|_| |_| |_| |_|_|_| |_|_|_|_| * * * * http://www.humus.name * * * * This file is a part of the work done by Humus. You are free to * * use the code in any way you like, modified, unmodified or copied * * into your own work. However, I expect you to respect these points: * * - If you use this file and its contents unmodified, or use a major * * part of this file, please credit the author and leave this note. * * - For use in anything commercial, please request my approval. * * - Share your work and ideas too as much as you can. * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // I would like to thank Humus for giving away this code, it // is very generous and makes my life easier. // - Bill Whitacre #include "frustum.h" void Projection::ToMatrix(Matrix4x4 &mat) { float top,bot,lft,rgt; top=(float)(znear*tan(180.0/(PI*(double)yfov))); bot=-top; lft=bot*aspect; rgt=top*aspect; mat.rows[0]=Vector4((2*znear)/(rgt-lft),0.0,(rgt+lft)/(rgt-lft),0.0); mat.rows[1]=Vector4(0.0,(2*znear)/(top-bot),(top+bot)/(top-bot),0.0); mat.rows[2]=Vector4(0.0,0.0,-((zfar+znear)/(zfar-znear)),-((2*zfar*znear)/(zfar-znear))); mat.rows[3]=Vector4(0.0,0.0,-1.0,0.0); /*return Matrix4x4( Vector4((2*znear)/(rgt-lft),0.0,(rgt+lft)/(rgt-lft),0.0), Vector4(0.0,(2*znear)/(top-bot),(top+bot)/(top-bot),0.0), Vector4(0.0,0.0,-((zfar+znear)/(zfar-znear)),-((2*zfar*znear)/(zfar-znear))), Vector4(0.0,0.0,-1.0,0.0));*/ } void Frustum::LoadFrustum(const Matrix4x4 &mvp){ planes[_FRUSTUM_LEFT ] = Plane(mvp[12] - mvp[0], mvp[13] - mvp[1], mvp[14] - mvp[2], mvp[15] - mvp[3]); planes[_FRUSTUM_RIGHT ] = Plane(mvp[12] + mvp[0], mvp[13] + mvp[1], mvp[14] + mvp[2], mvp[15] + mvp[3]); planes[_FRUSTUM_TOP ] = Plane(mvp[12] - mvp[4], mvp[13] - mvp[5], mvp[14] - mvp[6], mvp[15] - mvp[7]); planes[_FRUSTUM_BOTTOM] = Plane(mvp[12] + mvp[4], mvp[13] + mvp[5], mvp[14] + mvp[6], mvp[15] + mvp[7]); planes[_FRUSTUM_FAR ] = Plane(mvp[12] - mvp[8], mvp[13] - mvp[9], mvp[14] - mvp[10], mvp[15] - mvp[11]); planes[_FRUSTUM_NEAR ] = Plane(mvp[12] + mvp[8], mvp[13] + mvp[9], mvp[14] + mvp[10], mvp[15] + mvp[11]); } bool Frustum::PointInFrustum(const Vector3 &pos) const { for (int i = 0; i < 6; i++){ if (planes[i].dist(pos) <= 0) return false; } return true; } bool Frustum::SphereInFrustum(const Vector3 &pos, const float radius) const { for (int i = 0; i < 6; i++){ if (planes[i].dist(pos) <= -radius) return false; } return true; } bool Frustum::CubeInFrustum(const float minX, const float maxX, const float minY, const float maxY, const float minZ, const float maxZ) const { for (int i = 0; i < 6; i++){ if (planes[i].dist(Vector3(minX, minY, minZ)) > 0) continue; if (planes[i].dist(Vector3(minX, minY, maxZ)) > 0) continue; if (planes[i].dist(Vector3(minX, maxY, minZ)) > 0) continue; if (planes[i].dist(Vector3(minX, maxY, maxZ)) > 0) continue; if (planes[i].dist(Vector3(maxX, minY, minZ)) > 0) continue; if (planes[i].dist(Vector3(maxX, minY, maxZ)) > 0) continue; if (planes[i].dist(Vector3(maxX, maxY, minZ)) > 0) continue; if (planes[i].dist(Vector3(maxX, maxY, maxZ)) > 0) continue; return false; } return true; }