forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			211 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			211 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #ifndef GIM_CLIP_POLYGON_H_INCLUDED
 | ||
|  | #define GIM_CLIP_POLYGON_H_INCLUDED
 | ||
|  | 
 | ||
|  | /*! \file gim_tri_collision.h
 | ||
|  | \author Francisco Leon Najera | ||
|  | */ | ||
|  | /*
 | ||
|  | ----------------------------------------------------------------------------- | ||
|  | This source file is part of GIMPACT Library. | ||
|  | 
 | ||
|  | For the latest info, see http://gimpact.sourceforge.net/
 | ||
|  | 
 | ||
|  | Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. | ||
|  | email: projectileman@yahoo.com | ||
|  | 
 | ||
|  |  This library is free software; you can redistribute it and/or | ||
|  |  modify it under the terms of EITHER: | ||
|  |    (1) The GNU Lesser General Public License as published by the Free | ||
|  |        Software Foundation; either version 2.1 of the License, or (at | ||
|  |        your option) any later version. The text of the GNU Lesser | ||
|  |        General Public License is included with this library in the | ||
|  |        file GIMPACT-LICENSE-LGPL.TXT. | ||
|  |    (2) The BSD-style license that is included with this library in | ||
|  |        the file GIMPACT-LICENSE-BSD.TXT. | ||
|  |    (3) The zlib/libpng license that is included with this library in | ||
|  |        the file GIMPACT-LICENSE-ZLIB.TXT. | ||
|  | 
 | ||
|  |  This library is distributed in the hope that it will be useful, | ||
|  |  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
|  |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files | ||
|  |  GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. | ||
|  | 
 | ||
|  | ----------------------------------------------------------------------------- | ||
|  | */ | ||
|  | 
 | ||
|  | 
 | ||
|  | //! This function calcs the distance from a 3D plane
 | ||
|  | class DISTANCE_PLANE_3D_FUNC | ||
|  | { | ||
|  | public: | ||
|  | 	template<typename CLASS_POINT,typename CLASS_PLANE> | ||
|  | 	inline GREAL operator()(const CLASS_PLANE & plane, const CLASS_POINT & point) | ||
|  | 	{ | ||
|  | 		return DISTANCE_PLANE_POINT(plane, point); | ||
|  | 	} | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | template<typename CLASS_POINT> | ||
|  | SIMD_FORCE_INLINE void PLANE_CLIP_POLYGON_COLLECT( | ||
|  | 						const CLASS_POINT & point0, | ||
|  | 						const CLASS_POINT & point1, | ||
|  | 						GREAL dist0, | ||
|  | 						GREAL dist1, | ||
|  | 						CLASS_POINT * clipped, | ||
|  | 						GUINT & clipped_count) | ||
|  | { | ||
|  | 	GUINT _prevclassif = (dist0>G_EPSILON); | ||
|  | 	GUINT _classif = (dist1>G_EPSILON); | ||
|  | 	if(_classif!=_prevclassif) | ||
|  | 	{ | ||
|  | 		GREAL blendfactor = -dist0/(dist1-dist0); | ||
|  | 		VEC_BLEND(clipped[clipped_count],point0,point1,blendfactor); | ||
|  | 		clipped_count++; | ||
|  | 	} | ||
|  | 	if(!_classif) | ||
|  | 	{ | ||
|  | 		VEC_COPY(clipped[clipped_count],point1); | ||
|  | 		clipped_count++; | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | //! Clips a polygon by a plane
 | ||
|  | /*!
 | ||
|  | *\return The count of the clipped counts | ||
|  | */ | ||
|  | template<typename CLASS_POINT,typename CLASS_PLANE, typename DISTANCE_PLANE_FUNC> | ||
|  | SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON_GENERIC( | ||
|  | 						const CLASS_PLANE & plane, | ||
|  | 						const CLASS_POINT * polygon_points, | ||
|  | 						GUINT polygon_point_count, | ||
|  | 						CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func) | ||
|  | { | ||
|  |     GUINT clipped_count = 0; | ||
|  | 
 | ||
|  | 
 | ||
|  |     //clip first point
 | ||
|  | 	GREAL firstdist = distance_func(plane,polygon_points[0]);; | ||
|  | 	if(!(firstdist>G_EPSILON)) | ||
|  | 	{ | ||
|  | 		VEC_COPY(clipped[clipped_count],polygon_points[0]); | ||
|  | 		clipped_count++; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	GREAL olddist = firstdist; | ||
|  | 	for(GUINT _i=1;_i<polygon_point_count;_i++) | ||
|  | 	{		 | ||
|  | 		GREAL dist = distance_func(plane,polygon_points[_i]); | ||
|  | 
 | ||
|  | 		PLANE_CLIP_POLYGON_COLLECT( | ||
|  | 						polygon_points[_i-1],polygon_points[_i], | ||
|  | 						olddist, | ||
|  | 						dist, | ||
|  | 						clipped, | ||
|  | 						clipped_count); | ||
|  | 
 | ||
|  | 
 | ||
|  | 		olddist = dist;		 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	//RETURN TO FIRST  point	
 | ||
|  | 
 | ||
|  | 	PLANE_CLIP_POLYGON_COLLECT( | ||
|  | 					polygon_points[polygon_point_count-1],polygon_points[0], | ||
|  | 					olddist, | ||
|  | 					firstdist, | ||
|  | 					clipped, | ||
|  | 					clipped_count); | ||
|  | 
 | ||
|  | 	return clipped_count; | ||
|  | } | ||
|  | 
 | ||
|  | //! Clips a polygon by a plane
 | ||
|  | /*!
 | ||
|  | *\return The count of the clipped counts | ||
|  | */ | ||
|  | template<typename CLASS_POINT,typename CLASS_PLANE, typename DISTANCE_PLANE_FUNC> | ||
|  | SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE_GENERIC( | ||
|  | 						const CLASS_PLANE & plane, | ||
|  | 						const CLASS_POINT & point0, | ||
|  | 						const CLASS_POINT & point1, | ||
|  | 						const CLASS_POINT & point2, | ||
|  | 						CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func) | ||
|  | { | ||
|  |     GUINT clipped_count = 0; | ||
|  | 
 | ||
|  |     //clip first point
 | ||
|  | 	GREAL firstdist = distance_func(plane,point0);; | ||
|  | 	if(!(firstdist>G_EPSILON)) | ||
|  | 	{ | ||
|  | 		VEC_COPY(clipped[clipped_count],point0); | ||
|  | 		clipped_count++; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// point 1
 | ||
|  | 	GREAL olddist = firstdist; | ||
|  | 	GREAL dist = distance_func(plane,point1); | ||
|  | 
 | ||
|  | 	PLANE_CLIP_POLYGON_COLLECT( | ||
|  | 					point0,point1, | ||
|  | 					olddist, | ||
|  | 					dist, | ||
|  | 					clipped, | ||
|  | 					clipped_count); | ||
|  | 
 | ||
|  | 	olddist = dist; | ||
|  | 
 | ||
|  | 
 | ||
|  | 	// point 2
 | ||
|  | 	dist = distance_func(plane,point2); | ||
|  | 
 | ||
|  | 	PLANE_CLIP_POLYGON_COLLECT( | ||
|  | 					point1,point2, | ||
|  | 					olddist, | ||
|  | 					dist, | ||
|  | 					clipped, | ||
|  | 					clipped_count); | ||
|  | 	olddist = dist; | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 	//RETURN TO FIRST  point
 | ||
|  | 	PLANE_CLIP_POLYGON_COLLECT( | ||
|  | 					point2,point0, | ||
|  | 					olddist, | ||
|  | 					firstdist, | ||
|  | 					clipped, | ||
|  | 					clipped_count); | ||
|  | 
 | ||
|  | 	return clipped_count; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | template<typename CLASS_POINT,typename CLASS_PLANE> | ||
|  | SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON3D( | ||
|  | 						const CLASS_PLANE & plane, | ||
|  | 						const CLASS_POINT * polygon_points, | ||
|  | 						GUINT polygon_point_count, | ||
|  | 						CLASS_POINT * clipped) | ||
|  | { | ||
|  | 	return PLANE_CLIP_POLYGON_GENERIC<CLASS_POINT,CLASS_PLANE>(plane,polygon_points,polygon_point_count,clipped,DISTANCE_PLANE_3D_FUNC()); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | template<typename CLASS_POINT,typename CLASS_PLANE> | ||
|  | SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE3D( | ||
|  | 						const CLASS_PLANE & plane, | ||
|  | 						const CLASS_POINT & point0, | ||
|  | 						const CLASS_POINT & point1, | ||
|  | 						const CLASS_POINT & point2, | ||
|  | 						CLASS_POINT * clipped) | ||
|  | { | ||
|  | 	return PLANE_CLIP_TRIANGLE_GENERIC<CLASS_POINT,CLASS_PLANE>(plane,point0,point1,point2,clipped,DISTANCE_PLANE_3D_FUNC()); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #endif // GIM_TRI_COLLISION_H_INCLUDED
 |