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
 |