183 lines
4.3 KiB
C
183 lines
4.3 KiB
C
#ifndef BT_CLIP_POLYGON_H_INCLUDED
|
|
#define BT_CLIP_POLYGON_H_INCLUDED
|
|
|
|
/*! \file btClipPolygon.h
|
|
\author Francisco Leon Najera
|
|
*/
|
|
/*
|
|
This source file is part of GIMPACT Library.
|
|
|
|
For the latest info, see http://gimpact.sourceforge.net/
|
|
|
|
Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
|
|
email: projectileman@yahoo.com
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied warranty.
|
|
In no event will the authors be held liable for any damages arising from the use of this software.
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it freely,
|
|
subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
|
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
*/
|
|
|
|
#include "LinearMath/btTransform.h"
|
|
#include "LinearMath/btGeometryUtil.h"
|
|
|
|
|
|
SIMD_FORCE_INLINE btScalar bt_distance_point_plane(const btVector4 & plane,const btVector3 &point)
|
|
{
|
|
return point.dot(plane) - plane[3];
|
|
}
|
|
|
|
/*! Vector blending
|
|
Takes two vectors a, b, blends them together*/
|
|
SIMD_FORCE_INLINE void bt_vec_blend(btVector3 &vr, const btVector3 &va,const btVector3 &vb, btScalar blend_factor)
|
|
{
|
|
vr = (1-blend_factor)*va + blend_factor*vb;
|
|
}
|
|
|
|
//! This function calcs the distance from a 3D plane
|
|
SIMD_FORCE_INLINE void bt_plane_clip_polygon_collect(
|
|
const btVector3 & point0,
|
|
const btVector3 & point1,
|
|
btScalar dist0,
|
|
btScalar dist1,
|
|
btVector3 * clipped,
|
|
int & clipped_count)
|
|
{
|
|
bool _prevclassif = (dist0>SIMD_EPSILON);
|
|
bool _classif = (dist1>SIMD_EPSILON);
|
|
if(_classif!=_prevclassif)
|
|
{
|
|
btScalar blendfactor = -dist0/(dist1-dist0);
|
|
bt_vec_blend(clipped[clipped_count],point0,point1,blendfactor);
|
|
clipped_count++;
|
|
}
|
|
if(!_classif)
|
|
{
|
|
clipped[clipped_count] = point1;
|
|
clipped_count++;
|
|
}
|
|
}
|
|
|
|
|
|
//! Clips a polygon by a plane
|
|
/*!
|
|
*\return The count of the clipped counts
|
|
*/
|
|
SIMD_FORCE_INLINE int bt_plane_clip_polygon(
|
|
const btVector4 & plane,
|
|
const btVector3 * polygon_points,
|
|
int polygon_point_count,
|
|
btVector3 * clipped)
|
|
{
|
|
int clipped_count = 0;
|
|
|
|
|
|
//clip first point
|
|
btScalar firstdist = bt_distance_point_plane(plane,polygon_points[0]);;
|
|
if(!(firstdist>SIMD_EPSILON))
|
|
{
|
|
clipped[clipped_count] = polygon_points[0];
|
|
clipped_count++;
|
|
}
|
|
|
|
btScalar olddist = firstdist;
|
|
for(int i=1;i<polygon_point_count;i++)
|
|
{
|
|
btScalar dist = bt_distance_point_plane(plane,polygon_points[i]);
|
|
|
|
bt_plane_clip_polygon_collect(
|
|
polygon_points[i-1],polygon_points[i],
|
|
olddist,
|
|
dist,
|
|
clipped,
|
|
clipped_count);
|
|
|
|
|
|
olddist = dist;
|
|
}
|
|
|
|
//RETURN TO FIRST point
|
|
|
|
bt_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
|
|
/*!
|
|
*\param clipped must be an array of 16 points.
|
|
*\return The count of the clipped counts
|
|
*/
|
|
SIMD_FORCE_INLINE int bt_plane_clip_triangle(
|
|
const btVector4 & plane,
|
|
const btVector3 & point0,
|
|
const btVector3 & point1,
|
|
const btVector3& point2,
|
|
btVector3 * clipped // an allocated array of 16 points at least
|
|
)
|
|
{
|
|
int clipped_count = 0;
|
|
|
|
//clip first point0
|
|
btScalar firstdist = bt_distance_point_plane(plane,point0);;
|
|
if(!(firstdist>SIMD_EPSILON))
|
|
{
|
|
clipped[clipped_count] = point0;
|
|
clipped_count++;
|
|
}
|
|
|
|
// point 1
|
|
btScalar olddist = firstdist;
|
|
btScalar dist = bt_distance_point_plane(plane,point1);
|
|
|
|
bt_plane_clip_polygon_collect(
|
|
point0,point1,
|
|
olddist,
|
|
dist,
|
|
clipped,
|
|
clipped_count);
|
|
|
|
olddist = dist;
|
|
|
|
|
|
// point 2
|
|
dist = bt_distance_point_plane(plane,point2);
|
|
|
|
bt_plane_clip_polygon_collect(
|
|
point1,point2,
|
|
olddist,
|
|
dist,
|
|
clipped,
|
|
clipped_count);
|
|
olddist = dist;
|
|
|
|
|
|
|
|
//RETURN TO FIRST point0
|
|
bt_plane_clip_polygon_collect(
|
|
point2,point0,
|
|
olddist,
|
|
firstdist,
|
|
clipped,
|
|
clipped_count);
|
|
|
|
return clipped_count;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif // GIM_TRI_COLLISION_H_INCLUDED
|