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
							 |