00001 #ifndef GIM_CLIP_POLYGON_H_INCLUDED
00002 #define GIM_CLIP_POLYGON_H_INCLUDED
00003
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00038 class DISTANCE_PLANE_3D_FUNC
00039 {
00040 public:
00041 template<typename CLASS_POINT,typename CLASS_PLANE>
00042 inline GREAL operator()(const CLASS_PLANE & plane, const CLASS_POINT & point)
00043 {
00044 return DISTANCE_PLANE_POINT(plane, point);
00045 }
00046 };
00047
00048
00049
00050 template<typename CLASS_POINT>
00051 SIMD_FORCE_INLINE void PLANE_CLIP_POLYGON_COLLECT(
00052 const CLASS_POINT & point0,
00053 const CLASS_POINT & point1,
00054 GREAL dist0,
00055 GREAL dist1,
00056 CLASS_POINT * clipped,
00057 GUINT & clipped_count)
00058 {
00059 GUINT _prevclassif = (dist0>G_EPSILON);
00060 GUINT _classif = (dist1>G_EPSILON);
00061 if(_classif!=_prevclassif)
00062 {
00063 GREAL blendfactor = -dist0/(dist1-dist0);
00064 VEC_BLEND(clipped[clipped_count],point0,point1,blendfactor);
00065 clipped_count++;
00066 }
00067 if(!_classif)
00068 {
00069 VEC_COPY(clipped[clipped_count],point1);
00070 clipped_count++;
00071 }
00072 }
00073
00074
00076
00079 template<typename CLASS_POINT,typename CLASS_PLANE, typename DISTANCE_PLANE_FUNC>
00080 SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON_GENERIC(
00081 const CLASS_PLANE & plane,
00082 const CLASS_POINT * polygon_points,
00083 GUINT polygon_point_count,
00084 CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func)
00085 {
00086 GUINT clipped_count = 0;
00087
00088
00089
00090 GREAL firstdist = distance_func(plane,polygon_points[0]);;
00091 if(!(firstdist>G_EPSILON))
00092 {
00093 VEC_COPY(clipped[clipped_count],polygon_points[0]);
00094 clipped_count++;
00095 }
00096
00097 GREAL olddist = firstdist;
00098 for(GUINT _i=1;_i<polygon_point_count;_i++)
00099 {
00100 GREAL dist = distance_func(plane,polygon_points[_i]);
00101
00102 PLANE_CLIP_POLYGON_COLLECT(
00103 polygon_points[_i-1],polygon_points[_i],
00104 olddist,
00105 dist,
00106 clipped,
00107 clipped_count);
00108
00109
00110 olddist = dist;
00111 }
00112
00113
00114
00115 PLANE_CLIP_POLYGON_COLLECT(
00116 polygon_points[polygon_point_count-1],polygon_points[0],
00117 olddist,
00118 firstdist,
00119 clipped,
00120 clipped_count);
00121
00122 return clipped_count;
00123 }
00124
00126
00129 template<typename CLASS_POINT,typename CLASS_PLANE, typename DISTANCE_PLANE_FUNC>
00130 SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE_GENERIC(
00131 const CLASS_PLANE & plane,
00132 const CLASS_POINT & point0,
00133 const CLASS_POINT & point1,
00134 const CLASS_POINT & point2,
00135 CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func)
00136 {
00137 GUINT clipped_count = 0;
00138
00139
00140 GREAL firstdist = distance_func(plane,point0);;
00141 if(!(firstdist>G_EPSILON))
00142 {
00143 VEC_COPY(clipped[clipped_count],point0);
00144 clipped_count++;
00145 }
00146
00147
00148 GREAL olddist = firstdist;
00149 GREAL dist = distance_func(plane,point1);
00150
00151 PLANE_CLIP_POLYGON_COLLECT(
00152 point0,point1,
00153 olddist,
00154 dist,
00155 clipped,
00156 clipped_count);
00157
00158 olddist = dist;
00159
00160
00161
00162 dist = distance_func(plane,point2);
00163
00164 PLANE_CLIP_POLYGON_COLLECT(
00165 point1,point2,
00166 olddist,
00167 dist,
00168 clipped,
00169 clipped_count);
00170 olddist = dist;
00171
00172
00173
00174
00175 PLANE_CLIP_POLYGON_COLLECT(
00176 point2,point0,
00177 olddist,
00178 firstdist,
00179 clipped,
00180 clipped_count);
00181
00182 return clipped_count;
00183 }
00184
00185
00186 template<typename CLASS_POINT,typename CLASS_PLANE>
00187 SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON3D(
00188 const CLASS_PLANE & plane,
00189 const CLASS_POINT * polygon_points,
00190 GUINT polygon_point_count,
00191 CLASS_POINT * clipped)
00192 {
00193 return PLANE_CLIP_POLYGON_GENERIC<CLASS_POINT,CLASS_PLANE>(plane,polygon_points,polygon_point_count,clipped,DISTANCE_PLANE_3D_FUNC());
00194 }
00195
00196
00197 template<typename CLASS_POINT,typename CLASS_PLANE>
00198 SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE3D(
00199 const CLASS_PLANE & plane,
00200 const CLASS_POINT & point0,
00201 const CLASS_POINT & point1,
00202 const CLASS_POINT & point2,
00203 CLASS_POINT * clipped)
00204 {
00205 return PLANE_CLIP_TRIANGLE_GENERIC<CLASS_POINT,CLASS_PLANE>(plane,point0,point1,point2,clipped,DISTANCE_PLANE_3D_FUNC());
00206 }
00207
00208
00209
00210 #endif // GIM_TRI_COLLISION_H_INCLUDED