123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #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
|