AI_SDB_PlaneClipper.h
Go to the documentation of this file.00001 #ifndef AI_SDB_PLANECLIPPER_H
00002 #define AI_SDB_PLANECLIPPER_H
00003
00045 #include "../math/AI_Plane.h"
00046 #include "../math/AI_Sphere.h"
00047 #include "../math/AI_BBox.h"
00048
00049
00050
00051 #define AI_SDB_PLANECLIPPER_MAXPLANES 16
00052
00053 class AI_SDB_PlaneClipper {
00054 public:
00056 AI_SDB_PlaneClipper();
00058 AI_SDB_PlaneClipper(const AI_SDB_PlaneClipper ©me);
00060 AI_SDB_PlaneClipper(const AI_Plane *clipplanes, int numplanes);
00061
00067 AI_SDB_VisitorFlags TestBBox(const AI_BBox &boxtest, AI_SDB_VisitorFlags in);
00068
00074 AI_SDB_VisitorFlags TestSphere(const AI_Sphere &spheretest, AI_SDB_VisitorFlags in);
00075
00078 AI_SDB_VisitorFlags TestPoint(const AI_Vector3 &pointtest, AI_SDB_VisitorFlags in);
00079
00080 protected:
00081 AI_Plane m_planes[AI_SDB_PLANECLIPPER_MAXPLANES];
00082 int m_numplanes;
00083 };
00084
00085 inline
00086 AI_SDB_PlaneClipper::AI_SDB_PlaneClipper()
00087 {
00088 }
00089
00090 inline
00091 AI_SDB_PlaneClipper::AI_SDB_PlaneClipper(const AI_SDB_PlaneClipper ©me)
00092 {
00093 m_numplanes = copyme.m_numplanes;
00094
00095 for (int i=0; i < copyme.m_numplanes; i++)
00096 m_planes[i] = copyme.m_planes[i];
00097 }
00098
00099
00100 inline
00101 AI_SDB_PlaneClipper::AI_SDB_PlaneClipper(const AI_Plane *clipplanes, int numplanes)
00102 : m_numplanes(numplanes)
00103 {
00104
00105 for (int i=0; i < numplanes; i++)
00106 {
00107 m_planes[i] = clipplanes[i];
00108 }
00109 }
00110
00111 inline
00112 AI_SDB_VisitorFlags AI_SDB_PlaneClipper::TestBBox(const AI_BBox &boxtest, AI_SDB_VisitorFlags in)
00113 {
00114
00115
00116
00117
00118 AI_Vector3 center = boxtest.center();
00119 AI_Vector3 extent = boxtest.extents();
00120
00121
00122 int bit = 1;
00123 int allplanebits( (1<<m_numplanes) - 1 );
00124 for (int i = 0; i < m_numplanes; i++, bit <<= 1)
00125 {
00126
00127 if ((bit & in.m_activeflags) != 0)
00128 {
00129 const AI_Plane& p = m_planes[i];
00130 const AI_Vector3 normal = p.normal();
00131
00132
00133 float d = normal % center + p.d;
00134 float extent_toward_plane = ai_abs(extent.x * normal.x)
00135 + ai_abs(extent.y * normal.y)
00136 + ai_abs(extent.z * normal.z);
00137 if (d < 0)
00138 {
00139 if (-d > extent_toward_plane)
00140 {
00141
00142 return AI_SDB_VisitorFlags(false,true);
00143 }
00144 } else {
00145 if (d > extent_toward_plane)
00146 {
00147
00148
00149
00150
00151 in.m_activeflags &= ~bit;
00152 if ( (in.m_activeflags & allplanebits) == 0)
00153 {
00154
00155
00156 return AI_SDB_VisitorFlags(true,false);
00157 }
00158 }
00159 }
00160 }
00161 }
00162
00163 return in;
00164 }
00165
00166 inline
00167 AI_SDB_VisitorFlags AI_SDB_PlaneClipper::TestSphere(const AI_Sphere &spheretest, AI_SDB_VisitorFlags ri)
00168 {
00169
00170 AI_BBox mybbox(spheretest.p, AI_Vector3(spheretest.r, spheretest.r, spheretest.r));
00171 return TestBBox(mybbox, ri);
00172 }
00173
00174 inline
00175 AI_SDB_VisitorFlags AI_SDB_PlaneClipper::TestPoint(const AI_Vector3 &pointtest, AI_SDB_VisitorFlags ri)
00176 {
00177
00178 AI_BBox mybbox(pointtest, AI_Vector3(0,0,0));
00179 return TestBBox(mybbox, ri);
00180 }
00181
00182 #endif