Blender V2.61 - r43446
|
00001 #ifndef GIM_CLIP_POLYGON_H_INCLUDED 00002 #define GIM_CLIP_POLYGON_H_INCLUDED 00003 00007 /* 00008 ----------------------------------------------------------------------------- 00009 This source file is part of GIMPACT Library. 00010 00011 For the latest info, see http://gimpact.sourceforge.net/ 00012 00013 Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. 00014 email: projectileman@yahoo.com 00015 00016 This library is free software; you can redistribute it and/or 00017 modify it under the terms of EITHER: 00018 (1) The GNU Lesser General Public License as published by the Free 00019 Software Foundation; either version 2.1 of the License, or (at 00020 your option) any later version. The text of the GNU Lesser 00021 General Public License is included with this library in the 00022 file GIMPACT-LICENSE-LGPL.TXT. 00023 (2) The BSD-style license that is included with this library in 00024 the file GIMPACT-LICENSE-BSD.TXT. 00025 (3) The zlib/libpng license that is included with this library in 00026 the file GIMPACT-LICENSE-ZLIB.TXT. 00027 00028 This library is distributed in the hope that it will be useful, 00029 but WITHOUT ANY WARRANTY; without even the implied warranty of 00030 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files 00031 GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. 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 //clip first point 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 //RETURN TO FIRST point 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 //clip first point 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 // point 1 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 // point 2 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 //RETURN TO FIRST point 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