]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Frustum.cc
initial working frustum culling implementation
[chaz/yoink] / src / Moof / Frustum.cc
diff --git a/src/Moof/Frustum.cc b/src/Moof/Frustum.cc
new file mode 100644 (file)
index 0000000..4dc6340
--- /dev/null
@@ -0,0 +1,109 @@
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+ Redistribution   and   use  in  source  and  binary  forms,  with  or  without
+ modification, are permitted provided that the following conditions are met:
+   * Redistributions  of  source  code  must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+   * Redistributions  in binary form must reproduce the above copyright notice,
+     this  list of conditions and the following disclaimer in the documentation
+     and/or other materials provided with the distribution.
+ THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include <Moof/Aabb.hh>
+#include <Moof/Frustum.hh>
+#include <Moof/Sphere.hh>
+
+
+namespace Mf {
+
+
+void Frustum::init(const Matrix4& modelview, const Matrix4& projection)
+{
+       Scalar planes[6][4];
+
+       cml::extract_frustum_planes(modelview, projection, planes,
+                       cml::z_clip_neg_one);
+
+       planes_[0] = Plane(planes[0][0], planes[0][1], planes[0][2], planes[0][3]);
+       planes_[1] = Plane(planes[1][0], planes[1][1], planes[1][2], planes[1][3]);
+       planes_[2] = Plane(planes[2][0], planes[2][1], planes[2][2], planes[2][3]);
+       planes_[3] = Plane(planes[3][0], planes[3][1], planes[3][2], planes[3][3]);
+       planes_[4] = Plane(planes[4][0], planes[4][1], planes[4][2], planes[4][3]);
+       planes_[5] = Plane(planes[5][0], planes[5][1], planes[5][2], planes[5][3]);
+}
+
+void Frustum::init(const Matrix4& modelview, Scalar fovy, Scalar aspect,
+               Scalar near, Scalar far)
+{
+       Matrix4 projection;
+
+       cml::matrix_perspective_yfov_RH(projection, fovy, aspect, near, far,
+                       cml::z_clip_neg_one);
+
+       init(modelview, projection);
+}
+
+Frustum::Collision Frustum::containsAabb(const Aabb& aabb) const
+{
+       Vector3 corners[8];
+       int nTotalInside = 0;
+
+       aabb.getCorners(corners);
+
+       for (int i = 0; i < 6; ++i)
+       {
+               int nInside = 8;
+
+               for (int j = 0; j < 8; ++j)
+               {
+                       if (planes_[i].intersectsPoint(corners[j]) ==
+                                       Plane::NEGATIVE)
+                       {
+                               --nInside;
+                       }
+               }
+
+               if (nInside == 0)      return OUTSIDE;
+               else if (nInside == 8) ++nTotalInside;
+       }
+
+       if (nTotalInside == 6) return INSIDE;
+       else                   return INTERSECT;
+}
+
+
+Frustum::Collision Frustum::containsSphere(const Sphere& sphere) const
+{
+       for (int i = 0; i < 6; ++i)
+       {
+               Plane::Halfspace halfspace = planes_[i].intersectsSphere(sphere);
+               
+               if (halfspace == Plane::NEGATIVE)       return OUTSIDE;
+               else if (halfspace == Plane::INTERSECT) return INTERSECT;
+       }
+
+       return INSIDE;
+}
+
+
+} // namespace Mf
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
This page took 0.025344 seconds and 4 git commands to generate.