Code-style consistency improvement:
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
This commit is contained in:
@@ -26,27 +26,21 @@ subject to the following restrictions:
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
|
||||
///Swap numbers
|
||||
#define BT_SWAP_NUMBERS(a,b){ \
|
||||
a = a+b; \
|
||||
b = a-b; \
|
||||
a = a-b; \
|
||||
}\
|
||||
|
||||
|
||||
#define BT_MAX(a,b) (a<b?b:a)
|
||||
#define BT_MIN(a,b) (a>b?b:a)
|
||||
|
||||
#define BT_GREATER(x, y) btFabs(x) > (y)
|
||||
|
||||
#define BT_MAX3(a,b,c) BT_MAX(a,BT_MAX(b,c))
|
||||
#define BT_MIN3(a,b,c) BT_MIN(a,BT_MIN(b,c))
|
||||
|
||||
|
||||
#define BT_SWAP_NUMBERS(a, b) \
|
||||
{ \
|
||||
a = a + b; \
|
||||
b = a - b; \
|
||||
a = a - b; \
|
||||
}
|
||||
|
||||
#define BT_MAX(a, b) (a < b ? b : a)
|
||||
#define BT_MIN(a, b) (a > b ? b : a)
|
||||
|
||||
#define BT_GREATER(x, y) btFabs(x) > (y)
|
||||
|
||||
#define BT_MAX3(a, b, c) BT_MAX(a, BT_MAX(b, c))
|
||||
#define BT_MIN3(a, b, c) BT_MIN(a, BT_MIN(b, c))
|
||||
|
||||
enum eBT_PLANE_INTERSECTION_TYPE
|
||||
{
|
||||
@@ -115,152 +109,144 @@ enum eBT_PLANE_INTERSECTION_TYPE
|
||||
// return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1);
|
||||
//}
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, i_dir_0, i_dir_1, i_comp_0, i_comp_1) \
|
||||
{ \
|
||||
const btScalar dir0 = -edge[i_dir_0]; \
|
||||
const btScalar dir1 = edge[i_dir_1]; \
|
||||
btScalar pmin = pointa[i_comp_0] * dir0 + pointa[i_comp_1] * dir1; \
|
||||
btScalar pmax = pointb[i_comp_0] * dir0 + pointb[i_comp_1] * dir1; \
|
||||
if (pmin > pmax) \
|
||||
{ \
|
||||
BT_SWAP_NUMBERS(pmin, pmax); \
|
||||
} \
|
||||
const btScalar abs_dir0 = absolute_edge[i_dir_0]; \
|
||||
const btScalar abs_dir1 = absolute_edge[i_dir_1]; \
|
||||
const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1; \
|
||||
if (pmin > rad || -rad > pmax) return false; \
|
||||
}
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\
|
||||
{\
|
||||
const btScalar dir0 = -edge[i_dir_0];\
|
||||
const btScalar dir1 = edge[i_dir_1];\
|
||||
btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\
|
||||
btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\
|
||||
if(pmin>pmax)\
|
||||
{\
|
||||
BT_SWAP_NUMBERS(pmin,pmax); \
|
||||
}\
|
||||
const btScalar abs_dir0 = absolute_edge[i_dir_0];\
|
||||
const btScalar abs_dir1 = absolute_edge[i_dir_1];\
|
||||
const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\
|
||||
if(pmin>rad || -rad>pmax) return false;\
|
||||
}\
|
||||
#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \
|
||||
{ \
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 2, 1, 1, 2); \
|
||||
}
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \
|
||||
{ \
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 0, 2, 2, 0); \
|
||||
}
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
|
||||
{\
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\
|
||||
}\
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
|
||||
{\
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\
|
||||
}\
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
|
||||
{\
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\
|
||||
}\
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \
|
||||
{ \
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 1, 0, 0, 1); \
|
||||
}
|
||||
|
||||
//! Returns the dot product between a vec3f and the col of a matrix
|
||||
SIMD_FORCE_INLINE btScalar bt_mat3_dot_col(
|
||||
const btMatrix3x3 & mat, const btVector3 & vec3, int colindex)
|
||||
const btMatrix3x3 &mat, const btVector3 &vec3, int colindex)
|
||||
{
|
||||
return vec3[0]*mat[0][colindex] + vec3[1]*mat[1][colindex] + vec3[2]*mat[2][colindex];
|
||||
return vec3[0] * mat[0][colindex] + vec3[1] * mat[1][colindex] + vec3[2] * mat[2][colindex];
|
||||
}
|
||||
|
||||
|
||||
//! Class for transforming a model1 to the space of model0
|
||||
ATTRIBUTE_ALIGNED16 (class) BT_BOX_BOX_TRANSFORM_CACHE
|
||||
ATTRIBUTE_ALIGNED16(class)
|
||||
BT_BOX_BOX_TRANSFORM_CACHE
|
||||
{
|
||||
public:
|
||||
btVector3 m_T1to0;//!< Transforms translation of model1 to model 0
|
||||
btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1
|
||||
btMatrix3x3 m_AR;//!< Absolute value of m_R1to0
|
||||
btVector3 m_T1to0; //!< Transforms translation of model1 to model 0
|
||||
btMatrix3x3 m_R1to0; //!< Transforms Rotation of model1 to model 0, equal to R0' * R1
|
||||
btMatrix3x3 m_AR; //!< Absolute value of m_R1to0
|
||||
|
||||
SIMD_FORCE_INLINE void calc_absolute_matrix()
|
||||
{
|
||||
// static const btVector3 vepsi(1e-6f,1e-6f,1e-6f);
|
||||
// m_AR[0] = vepsi + m_R1to0[0].absolute();
|
||||
// m_AR[1] = vepsi + m_R1to0[1].absolute();
|
||||
// m_AR[2] = vepsi + m_R1to0[2].absolute();
|
||||
// static const btVector3 vepsi(1e-6f,1e-6f,1e-6f);
|
||||
// m_AR[0] = vepsi + m_R1to0[0].absolute();
|
||||
// m_AR[1] = vepsi + m_R1to0[1].absolute();
|
||||
// m_AR[2] = vepsi + m_R1to0[2].absolute();
|
||||
|
||||
int i,j;
|
||||
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
for(j=0;j<3;j++ )
|
||||
{
|
||||
m_AR[i][j] = 1e-6f + btFabs(m_R1to0[i][j]);
|
||||
}
|
||||
}
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
m_AR[i][j] = 1e-6f + btFabs(m_R1to0[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BT_BOX_BOX_TRANSFORM_CACHE()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Calc the transformation relative 1 to 0. Inverts matrics by transposing
|
||||
SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1)
|
||||
SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform &trans0, const btTransform &trans1)
|
||||
{
|
||||
|
||||
btTransform temp_trans = trans0.inverse();
|
||||
temp_trans = temp_trans * trans1;
|
||||
|
||||
m_T1to0 = temp_trans.getOrigin();
|
||||
m_R1to0 = temp_trans.getBasis();
|
||||
|
||||
|
||||
calc_absolute_matrix();
|
||||
}
|
||||
|
||||
//! Calcs the full invertion of the matrices. Useful for scaling matrices
|
||||
SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1)
|
||||
SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform &trans0, const btTransform &trans1)
|
||||
{
|
||||
m_R1to0 = trans0.getBasis().inverse();
|
||||
m_T1to0 = m_R1to0 * (-trans0.getOrigin());
|
||||
|
||||
m_T1to0 += m_R1to0*trans1.getOrigin();
|
||||
m_T1to0 += m_R1to0 * trans1.getOrigin();
|
||||
m_R1to0 *= trans1.getBasis();
|
||||
|
||||
calc_absolute_matrix();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) const
|
||||
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
|
||||
{
|
||||
return point.dot3( m_R1to0[0], m_R1to0[1], m_R1to0[2] ) + m_T1to0;
|
||||
return point.dot3(m_R1to0[0], m_R1to0[1], m_R1to0[2]) + m_T1to0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define BOX_PLANE_EPSILON 0.000001f
|
||||
|
||||
//! Axis aligned box
|
||||
ATTRIBUTE_ALIGNED16 (class) btAABB
|
||||
ATTRIBUTE_ALIGNED16(class)
|
||||
btAABB
|
||||
{
|
||||
public:
|
||||
btVector3 m_min;
|
||||
btVector3 m_max;
|
||||
|
||||
btAABB()
|
||||
{}
|
||||
|
||||
|
||||
btAABB(const btVector3 & V1,
|
||||
const btVector3 & V2,
|
||||
const btVector3 & V3)
|
||||
{
|
||||
m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]);
|
||||
m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]);
|
||||
m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]);
|
||||
|
||||
m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]);
|
||||
m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]);
|
||||
m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]);
|
||||
}
|
||||
|
||||
btAABB(const btVector3 & V1,
|
||||
const btVector3 & V2,
|
||||
const btVector3 & V3,
|
||||
btScalar margin)
|
||||
btAABB(const btVector3 &V1,
|
||||
const btVector3 &V2,
|
||||
const btVector3 &V3)
|
||||
{
|
||||
m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]);
|
||||
m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]);
|
||||
m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]);
|
||||
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
||||
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
||||
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]);
|
||||
m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]);
|
||||
m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]);
|
||||
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
||||
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
||||
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
||||
}
|
||||
|
||||
btAABB(const btVector3 &V1,
|
||||
const btVector3 &V2,
|
||||
const btVector3 &V3,
|
||||
btScalar margin)
|
||||
{
|
||||
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
||||
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
||||
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
||||
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
||||
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_min[0] -= margin;
|
||||
m_min[1] -= margin;
|
||||
@@ -270,13 +256,11 @@ public:
|
||||
m_max[2] += margin;
|
||||
}
|
||||
|
||||
btAABB(const btAABB &other):
|
||||
m_min(other.m_min),m_max(other.m_max)
|
||||
btAABB(const btAABB &other) : m_min(other.m_min), m_max(other.m_max)
|
||||
{
|
||||
}
|
||||
|
||||
btAABB(const btAABB &other,btScalar margin ):
|
||||
m_min(other.m_min),m_max(other.m_max)
|
||||
btAABB(const btAABB &other, btScalar margin) : m_min(other.m_min), m_max(other.m_max)
|
||||
{
|
||||
m_min[0] -= margin;
|
||||
m_min[1] -= margin;
|
||||
@@ -317,34 +301,34 @@ public:
|
||||
m_max[2] = other.m_max[2] + margin;
|
||||
}
|
||||
|
||||
template<typename CLASS_POINT>
|
||||
template <typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void calc_from_triangle(
|
||||
const CLASS_POINT & V1,
|
||||
const CLASS_POINT & V2,
|
||||
const CLASS_POINT & V3)
|
||||
const CLASS_POINT &V1,
|
||||
const CLASS_POINT &V2,
|
||||
const CLASS_POINT &V3)
|
||||
{
|
||||
m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]);
|
||||
m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]);
|
||||
m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]);
|
||||
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
||||
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
||||
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]);
|
||||
m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]);
|
||||
m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]);
|
||||
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
||||
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
||||
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
||||
}
|
||||
|
||||
template<typename CLASS_POINT>
|
||||
template <typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void calc_from_triangle_margin(
|
||||
const CLASS_POINT & V1,
|
||||
const CLASS_POINT & V2,
|
||||
const CLASS_POINT & V3, btScalar margin)
|
||||
const CLASS_POINT &V1,
|
||||
const CLASS_POINT &V2,
|
||||
const CLASS_POINT &V3, btScalar margin)
|
||||
{
|
||||
m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]);
|
||||
m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]);
|
||||
m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]);
|
||||
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
||||
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
||||
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]);
|
||||
m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]);
|
||||
m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]);
|
||||
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
||||
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
||||
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_min[0] -= margin;
|
||||
m_min[1] -= margin;
|
||||
@@ -355,91 +339,89 @@ public:
|
||||
}
|
||||
|
||||
//! Apply a transform to an AABB
|
||||
SIMD_FORCE_INLINE void appy_transform(const btTransform & trans)
|
||||
SIMD_FORCE_INLINE void appy_transform(const btTransform &trans)
|
||||
{
|
||||
btVector3 center = (m_max+m_min)*0.5f;
|
||||
btVector3 center = (m_max + m_min) * 0.5f;
|
||||
btVector3 extends = m_max - center;
|
||||
// Compute new center
|
||||
center = trans(center);
|
||||
|
||||
btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(),
|
||||
trans.getBasis().getRow(1).absolute(),
|
||||
trans.getBasis().getRow(2).absolute());
|
||||
btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(),
|
||||
trans.getBasis().getRow(1).absolute(),
|
||||
trans.getBasis().getRow(2).absolute());
|
||||
|
||||
m_min = center - textends;
|
||||
m_max = center + textends;
|
||||
}
|
||||
|
||||
|
||||
//! Apply a transform to an AABB
|
||||
SIMD_FORCE_INLINE void appy_transform_trans_cache(const BT_BOX_BOX_TRANSFORM_CACHE & trans)
|
||||
SIMD_FORCE_INLINE void appy_transform_trans_cache(const BT_BOX_BOX_TRANSFORM_CACHE &trans)
|
||||
{
|
||||
btVector3 center = (m_max+m_min)*0.5f;
|
||||
btVector3 center = (m_max + m_min) * 0.5f;
|
||||
btVector3 extends = m_max - center;
|
||||
// Compute new center
|
||||
center = trans.transform(center);
|
||||
|
||||
btVector3 textends = extends.dot3(trans.m_R1to0.getRow(0).absolute(),
|
||||
trans.m_R1to0.getRow(1).absolute(),
|
||||
trans.m_R1to0.getRow(2).absolute());
|
||||
|
||||
btVector3 textends = extends.dot3(trans.m_R1to0.getRow(0).absolute(),
|
||||
trans.m_R1to0.getRow(1).absolute(),
|
||||
trans.m_R1to0.getRow(2).absolute());
|
||||
|
||||
m_min = center - textends;
|
||||
m_max = center + textends;
|
||||
}
|
||||
|
||||
//! Merges a Box
|
||||
SIMD_FORCE_INLINE void merge(const btAABB & box)
|
||||
SIMD_FORCE_INLINE void merge(const btAABB &box)
|
||||
{
|
||||
m_min[0] = BT_MIN(m_min[0],box.m_min[0]);
|
||||
m_min[1] = BT_MIN(m_min[1],box.m_min[1]);
|
||||
m_min[2] = BT_MIN(m_min[2],box.m_min[2]);
|
||||
m_min[0] = BT_MIN(m_min[0], box.m_min[0]);
|
||||
m_min[1] = BT_MIN(m_min[1], box.m_min[1]);
|
||||
m_min[2] = BT_MIN(m_min[2], box.m_min[2]);
|
||||
|
||||
m_max[0] = BT_MAX(m_max[0],box.m_max[0]);
|
||||
m_max[1] = BT_MAX(m_max[1],box.m_max[1]);
|
||||
m_max[2] = BT_MAX(m_max[2],box.m_max[2]);
|
||||
m_max[0] = BT_MAX(m_max[0], box.m_max[0]);
|
||||
m_max[1] = BT_MAX(m_max[1], box.m_max[1]);
|
||||
m_max[2] = BT_MAX(m_max[2], box.m_max[2]);
|
||||
}
|
||||
|
||||
//! Merges a point
|
||||
template<typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point)
|
||||
template <typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void merge_point(const CLASS_POINT &point)
|
||||
{
|
||||
m_min[0] = BT_MIN(m_min[0],point[0]);
|
||||
m_min[1] = BT_MIN(m_min[1],point[1]);
|
||||
m_min[2] = BT_MIN(m_min[2],point[2]);
|
||||
m_min[0] = BT_MIN(m_min[0], point[0]);
|
||||
m_min[1] = BT_MIN(m_min[1], point[1]);
|
||||
m_min[2] = BT_MIN(m_min[2], point[2]);
|
||||
|
||||
m_max[0] = BT_MAX(m_max[0],point[0]);
|
||||
m_max[1] = BT_MAX(m_max[1],point[1]);
|
||||
m_max[2] = BT_MAX(m_max[2],point[2]);
|
||||
m_max[0] = BT_MAX(m_max[0], point[0]);
|
||||
m_max[1] = BT_MAX(m_max[1], point[1]);
|
||||
m_max[2] = BT_MAX(m_max[2], point[2]);
|
||||
}
|
||||
|
||||
//! Gets the extend and center
|
||||
SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend) const
|
||||
SIMD_FORCE_INLINE void get_center_extend(btVector3 & center, btVector3 & extend) const
|
||||
{
|
||||
center = (m_max+m_min)*0.5f;
|
||||
center = (m_max + m_min) * 0.5f;
|
||||
extend = m_max - center;
|
||||
}
|
||||
|
||||
//! Finds the intersecting box between this box and the other.
|
||||
SIMD_FORCE_INLINE void find_intersection(const btAABB & other, btAABB & intersection) const
|
||||
SIMD_FORCE_INLINE void find_intersection(const btAABB &other, btAABB &intersection) const
|
||||
{
|
||||
intersection.m_min[0] = BT_MAX(other.m_min[0],m_min[0]);
|
||||
intersection.m_min[1] = BT_MAX(other.m_min[1],m_min[1]);
|
||||
intersection.m_min[2] = BT_MAX(other.m_min[2],m_min[2]);
|
||||
intersection.m_min[0] = BT_MAX(other.m_min[0], m_min[0]);
|
||||
intersection.m_min[1] = BT_MAX(other.m_min[1], m_min[1]);
|
||||
intersection.m_min[2] = BT_MAX(other.m_min[2], m_min[2]);
|
||||
|
||||
intersection.m_max[0] = BT_MIN(other.m_max[0],m_max[0]);
|
||||
intersection.m_max[1] = BT_MIN(other.m_max[1],m_max[1]);
|
||||
intersection.m_max[2] = BT_MIN(other.m_max[2],m_max[2]);
|
||||
intersection.m_max[0] = BT_MIN(other.m_max[0], m_max[0]);
|
||||
intersection.m_max[1] = BT_MIN(other.m_max[1], m_max[1]);
|
||||
intersection.m_max[2] = BT_MIN(other.m_max[2], m_max[2]);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool has_collision(const btAABB & other) const
|
||||
SIMD_FORCE_INLINE bool has_collision(const btAABB &other) const
|
||||
{
|
||||
if(m_min[0] > other.m_max[0] ||
|
||||
m_max[0] < other.m_min[0] ||
|
||||
m_min[1] > other.m_max[1] ||
|
||||
m_max[1] < other.m_min[1] ||
|
||||
m_min[2] > other.m_max[2] ||
|
||||
m_max[2] < other.m_min[2])
|
||||
if (m_min[0] > other.m_max[0] ||
|
||||
m_max[0] < other.m_min[0] ||
|
||||
m_min[1] > other.m_max[1] ||
|
||||
m_max[1] < other.m_min[1] ||
|
||||
m_min[2] > other.m_max[2] ||
|
||||
m_max[2] < other.m_min[2])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -451,35 +433,34 @@ public:
|
||||
\param vorigin A vec3f with the origin of the ray
|
||||
\param vdir A vec3f with the direction of the ray
|
||||
*/
|
||||
SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir) const
|
||||
SIMD_FORCE_INLINE bool collide_ray(const btVector3 &vorigin, const btVector3 &vdir) const
|
||||
{
|
||||
btVector3 extents,center;
|
||||
this->get_center_extend(center,extents);;
|
||||
btVector3 extents, center;
|
||||
this->get_center_extend(center, extents);
|
||||
;
|
||||
|
||||
btScalar Dx = vorigin[0] - center[0];
|
||||
if(BT_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return false;
|
||||
if (BT_GREATER(Dx, extents[0]) && Dx * vdir[0] >= 0.0f) return false;
|
||||
btScalar Dy = vorigin[1] - center[1];
|
||||
if(BT_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return false;
|
||||
if (BT_GREATER(Dy, extents[1]) && Dy * vdir[1] >= 0.0f) return false;
|
||||
btScalar Dz = vorigin[2] - center[2];
|
||||
if(BT_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return false;
|
||||
|
||||
if (BT_GREATER(Dz, extents[2]) && Dz * vdir[2] >= 0.0f) return false;
|
||||
|
||||
btScalar f = vdir[1] * Dz - vdir[2] * Dy;
|
||||
if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false;
|
||||
if (btFabs(f) > extents[1] * btFabs(vdir[2]) + extents[2] * btFabs(vdir[1])) return false;
|
||||
f = vdir[2] * Dx - vdir[0] * Dz;
|
||||
if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false;
|
||||
if (btFabs(f) > extents[0] * btFabs(vdir[2]) + extents[2] * btFabs(vdir[0])) return false;
|
||||
f = vdir[0] * Dy - vdir[1] * Dx;
|
||||
if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false;
|
||||
if (btFabs(f) > extents[0] * btFabs(vdir[1]) + extents[1] * btFabs(vdir[0])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const
|
||||
SIMD_FORCE_INLINE void projection_interval(const btVector3 &direction, btScalar &vmin, btScalar &vmax) const
|
||||
{
|
||||
btVector3 center = (m_max+m_min)*0.5f;
|
||||
btVector3 extend = m_max-center;
|
||||
btVector3 center = (m_max + m_min) * 0.5f;
|
||||
btVector3 extend = m_max - center;
|
||||
|
||||
btScalar _fOrigin = direction.dot(center);
|
||||
btScalar _fOrigin = direction.dot(center);
|
||||
btScalar _fMaximumExtent = extend.dot(direction.absolute());
|
||||
vmin = _fOrigin - _fMaximumExtent;
|
||||
vmax = _fOrigin + _fMaximumExtent;
|
||||
@@ -487,30 +468,30 @@ public:
|
||||
|
||||
SIMD_FORCE_INLINE eBT_PLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const
|
||||
{
|
||||
btScalar _fmin,_fmax;
|
||||
this->projection_interval(plane,_fmin,_fmax);
|
||||
btScalar _fmin, _fmax;
|
||||
this->projection_interval(plane, _fmin, _fmax);
|
||||
|
||||
if(plane[3] > _fmax + BOX_PLANE_EPSILON)
|
||||
if (plane[3] > _fmax + BOX_PLANE_EPSILON)
|
||||
{
|
||||
return BT_CONST_BACK_PLANE; // 0
|
||||
return BT_CONST_BACK_PLANE; // 0
|
||||
}
|
||||
|
||||
if(plane[3]+BOX_PLANE_EPSILON >=_fmin)
|
||||
if (plane[3] + BOX_PLANE_EPSILON >= _fmin)
|
||||
{
|
||||
return BT_CONST_COLLIDE_PLANE; //1
|
||||
return BT_CONST_COLLIDE_PLANE; //1
|
||||
}
|
||||
return BT_CONST_FRONT_PLANE;//2
|
||||
return BT_CONST_FRONT_PLANE; //2
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool overlapping_trans_conservative(const btAABB & box, btTransform & trans1_to_0) const
|
||||
SIMD_FORCE_INLINE bool overlapping_trans_conservative(const btAABB &box, btTransform &trans1_to_0) const
|
||||
{
|
||||
btAABB tbox = box;
|
||||
tbox.appy_transform(trans1_to_0);
|
||||
return has_collision(tbox);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool overlapping_trans_conservative2(const btAABB & box,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE & trans1_to_0) const
|
||||
SIMD_FORCE_INLINE bool overlapping_trans_conservative2(const btAABB &box,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE &trans1_to_0) const
|
||||
{
|
||||
btAABB tbox = box;
|
||||
tbox.appy_transform_trans_cache(trans1_to_0);
|
||||
@@ -519,52 +500,50 @@ public:
|
||||
|
||||
//! transcache is the transformation cache from box to this AABB
|
||||
SIMD_FORCE_INLINE bool overlapping_trans_cache(
|
||||
const btAABB & box,const BT_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest) const
|
||||
const btAABB &box, const BT_BOX_BOX_TRANSFORM_CACHE &transcache, bool fulltest) const
|
||||
{
|
||||
|
||||
//Taken from OPCODE
|
||||
btVector3 ea,eb;//extends
|
||||
btVector3 ca,cb;//extends
|
||||
get_center_extend(ca,ea);
|
||||
box.get_center_extend(cb,eb);
|
||||
|
||||
btVector3 ea, eb; //extends
|
||||
btVector3 ca, cb; //extends
|
||||
get_center_extend(ca, ea);
|
||||
box.get_center_extend(cb, eb);
|
||||
|
||||
btVector3 T;
|
||||
btScalar t,t2;
|
||||
btScalar t, t2;
|
||||
int i;
|
||||
|
||||
// Class I : A's basis vectors
|
||||
for(i=0;i<3;i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i];
|
||||
T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i];
|
||||
t = transcache.m_AR[i].dot(eb) + ea[i];
|
||||
if(BT_GREATER(T[i], t)) return false;
|
||||
if (BT_GREATER(T[i], t)) return false;
|
||||
}
|
||||
// Class II : B's basis vectors
|
||||
for(i=0;i<3;i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
t = bt_mat3_dot_col(transcache.m_R1to0,T,i);
|
||||
t2 = bt_mat3_dot_col(transcache.m_AR,ea,i) + eb[i];
|
||||
if(BT_GREATER(t,t2)) return false;
|
||||
t = bt_mat3_dot_col(transcache.m_R1to0, T, i);
|
||||
t2 = bt_mat3_dot_col(transcache.m_AR, ea, i) + eb[i];
|
||||
if (BT_GREATER(t, t2)) return false;
|
||||
}
|
||||
// Class III : 9 cross products
|
||||
if(fulltest)
|
||||
if (fulltest)
|
||||
{
|
||||
int j,m,n,o,p,q,r;
|
||||
for(i=0;i<3;i++)
|
||||
int j, m, n, o, p, q, r;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
m = (i+1)%3;
|
||||
n = (i+2)%3;
|
||||
o = i==0?1:0;
|
||||
p = i==2?1:2;
|
||||
for(j=0;j<3;j++)
|
||||
m = (i + 1) % 3;
|
||||
n = (i + 2) % 3;
|
||||
o = i == 0 ? 1 : 0;
|
||||
p = i == 2 ? 1 : 2;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
q = j==2?1:2;
|
||||
r = j==0?1:0;
|
||||
t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j];
|
||||
t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] +
|
||||
eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r];
|
||||
if(BT_GREATER(t,t2)) return false;
|
||||
q = j == 2 ? 1 : 2;
|
||||
r = j == 0 ? 1 : 0;
|
||||
t = T[n] * transcache.m_R1to0[m][j] - T[m] * transcache.m_R1to0[n][j];
|
||||
t2 = ea[o] * transcache.m_AR[p][j] + ea[p] * transcache.m_AR[o][j] +
|
||||
eb[r] * transcache.m_AR[i][q] + eb[q] * transcache.m_AR[i][r];
|
||||
if (BT_GREATER(t, t2)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,7 +552,7 @@ public:
|
||||
|
||||
//! Simple test for planes.
|
||||
SIMD_FORCE_INLINE bool collide_plane(
|
||||
const btVector4 & plane) const
|
||||
const btVector4 &plane) const
|
||||
{
|
||||
eBT_PLANE_INTERSECTION_TYPE classify = plane_classify(plane);
|
||||
return (classify == BT_CONST_COLLIDE_PLANE);
|
||||
@@ -581,15 +560,15 @@ public:
|
||||
|
||||
//! test for a triangle, with edges
|
||||
SIMD_FORCE_INLINE bool collide_triangle_exact(
|
||||
const btVector3 & p1,
|
||||
const btVector3 & p2,
|
||||
const btVector3 & p3,
|
||||
const btVector4 & triangle_plane) const
|
||||
const btVector3 &p1,
|
||||
const btVector3 &p2,
|
||||
const btVector3 &p3,
|
||||
const btVector4 &triangle_plane) const
|
||||
{
|
||||
if(!collide_plane(triangle_plane)) return false;
|
||||
if (!collide_plane(triangle_plane)) return false;
|
||||
|
||||
btVector3 center,extends;
|
||||
this->get_center_extend(center,extends);
|
||||
btVector3 center, extends;
|
||||
this->get_center_extend(center, extends);
|
||||
|
||||
const btVector3 v1(p1 - center);
|
||||
const btVector3 v2(p2 - center);
|
||||
@@ -599,47 +578,43 @@ public:
|
||||
btVector3 diff(v2 - v1);
|
||||
btVector3 abs_diff = diff.absolute();
|
||||
//Test With X axis
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends);
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v1, v3, extends);
|
||||
//Test With Y axis
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends);
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v1, v3, extends);
|
||||
//Test With Z axis
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends);
|
||||
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v1, v3, extends);
|
||||
|
||||
diff = v3 - v2;
|
||||
abs_diff = diff.absolute();
|
||||
//Test With X axis
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends);
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v2, v1, extends);
|
||||
//Test With Y axis
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends);
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v2, v1, extends);
|
||||
//Test With Z axis
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends);
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v2, v1, extends);
|
||||
|
||||
diff = v1 - v3;
|
||||
abs_diff = diff.absolute();
|
||||
//Test With X axis
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends);
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v3, v2, extends);
|
||||
//Test With Y axis
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends);
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v3, v2, extends);
|
||||
//Test With Z axis
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends);
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v3, v2, extends);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! Compairison of transformation objects
|
||||
SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2)
|
||||
SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform &t1, const btTransform &t2)
|
||||
{
|
||||
if(!(t1.getOrigin() == t2.getOrigin()) ) return false;
|
||||
if (!(t1.getOrigin() == t2.getOrigin())) return false;
|
||||
|
||||
if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false;
|
||||
if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false;
|
||||
if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false;
|
||||
if (!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0))) return false;
|
||||
if (!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1))) return false;
|
||||
if (!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // GIM_BOX_COLLISION_H_INCLUDED
|
||||
#endif // GIM_BOX_COLLISION_H_INCLUDED
|
||||
|
||||
@@ -27,77 +27,74 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btGeometryUtil.h"
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btScalar bt_distance_point_plane(const btVector4 & plane,const btVector3 &point)
|
||||
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)
|
||||
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;
|
||||
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)
|
||||
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)
|
||||
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);
|
||||
btScalar blendfactor = -dist0 / (dist1 - dist0);
|
||||
bt_vec_blend(clipped[clipped_count], point0, point1, blendfactor);
|
||||
clipped_count++;
|
||||
}
|
||||
if(!_classif)
|
||||
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)
|
||||
const btVector4 &plane,
|
||||
const btVector3 *polygon_points,
|
||||
int polygon_point_count,
|
||||
btVector3 *clipped)
|
||||
{
|
||||
int clipped_count = 0;
|
||||
int clipped_count = 0;
|
||||
|
||||
|
||||
//clip first point
|
||||
btScalar firstdist = bt_distance_point_plane(plane,polygon_points[0]);;
|
||||
if(!(firstdist>SIMD_EPSILON))
|
||||
//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++)
|
||||
for (int i = 1; i < polygon_point_count; i++)
|
||||
{
|
||||
btScalar dist = bt_distance_point_plane(plane,polygon_points[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);
|
||||
|
||||
polygon_points[i - 1], polygon_points[i],
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
|
||||
olddist = dist;
|
||||
}
|
||||
@@ -105,11 +102,11 @@ SIMD_FORCE_INLINE int bt_plane_clip_polygon(
|
||||
//RETURN TO FIRST point
|
||||
|
||||
bt_plane_clip_polygon_collect(
|
||||
polygon_points[polygon_point_count-1],polygon_points[0],
|
||||
olddist,
|
||||
firstdist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
polygon_points[polygon_point_count - 1], polygon_points[0],
|
||||
olddist,
|
||||
firstdist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
|
||||
return clipped_count;
|
||||
}
|
||||
@@ -120,18 +117,19 @@ SIMD_FORCE_INLINE int bt_plane_clip_polygon(
|
||||
*\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
|
||||
)
|
||||
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;
|
||||
int clipped_count = 0;
|
||||
|
||||
//clip first point0
|
||||
btScalar firstdist = bt_distance_point_plane(plane,point0);;
|
||||
if(!(firstdist>SIMD_EPSILON))
|
||||
//clip first point0
|
||||
btScalar firstdist = bt_distance_point_plane(plane, point0);
|
||||
;
|
||||
if (!(firstdist > SIMD_EPSILON))
|
||||
{
|
||||
clipped[clipped_count] = point0;
|
||||
clipped_count++;
|
||||
@@ -139,44 +137,37 @@ SIMD_FORCE_INLINE int bt_plane_clip_triangle(
|
||||
|
||||
// point 1
|
||||
btScalar olddist = firstdist;
|
||||
btScalar dist = bt_distance_point_plane(plane,point1);
|
||||
btScalar dist = bt_distance_point_plane(plane, point1);
|
||||
|
||||
bt_plane_clip_polygon_collect(
|
||||
point0,point1,
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
point0, point1,
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
|
||||
olddist = dist;
|
||||
|
||||
|
||||
// point 2
|
||||
dist = bt_distance_point_plane(plane,point2);
|
||||
dist = bt_distance_point_plane(plane, point2);
|
||||
|
||||
bt_plane_clip_polygon_collect(
|
||||
point1,point2,
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
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);
|
||||
point2, point0,
|
||||
olddist,
|
||||
firstdist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
|
||||
return clipped_count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // GIM_TRI_COLLISION_H_INCLUDED
|
||||
#endif // GIM_TRI_COLLISION_H_INCLUDED
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include "btGImpactShape.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
|
||||
|
||||
ATTRIBUTE_ALIGNED16(class) btCompoundFromGimpactShape : public btCompoundShape
|
||||
ATTRIBUTE_ALIGNED16(class)
|
||||
btCompoundFromGimpactShape : public btCompoundShape
|
||||
{
|
||||
public:
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
@@ -18,92 +19,87 @@ public:
|
||||
delete m_children[i].m_childShape;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct MyCallback : public btTriangleRaycastCallback
|
||||
{
|
||||
int m_ignorePart;
|
||||
int m_ignoreTriangleIndex;
|
||||
|
||||
MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex)
|
||||
: btTriangleRaycastCallback(from, to),
|
||||
m_ignorePart(ignorePart),
|
||||
m_ignoreTriangleIndex(ignoreTriangleIndex)
|
||||
{
|
||||
}
|
||||
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex)
|
||||
{
|
||||
if (partId != m_ignorePart || triangleIndex != m_ignoreTriangleIndex)
|
||||
{
|
||||
int m_ignorePart;
|
||||
int m_ignoreTriangleIndex;
|
||||
|
||||
if (hitFraction < m_hitFraction)
|
||||
return hitFraction;
|
||||
}
|
||||
|
||||
MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex)
|
||||
:btTriangleRaycastCallback(from,to),
|
||||
m_ignorePart(ignorePart),
|
||||
m_ignoreTriangleIndex(ignoreTriangleIndex)
|
||||
{
|
||||
|
||||
}
|
||||
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex)
|
||||
{
|
||||
if (partId!=m_ignorePart || triangleIndex!=m_ignoreTriangleIndex)
|
||||
{
|
||||
if (hitFraction < m_hitFraction)
|
||||
return hitFraction;
|
||||
}
|
||||
return m_hitFraction;
|
||||
}
|
||||
};
|
||||
struct MyInternalTriangleIndexCallback : public btInternalTriangleIndexCallback
|
||||
{
|
||||
const btGImpactMeshShape* m_gimpactShape;
|
||||
btCompoundShape* m_colShape;
|
||||
btScalar m_depth;
|
||||
|
||||
return m_hitFraction;
|
||||
}
|
||||
};
|
||||
struct MyInternalTriangleIndexCallback :public btInternalTriangleIndexCallback
|
||||
MyInternalTriangleIndexCallback(btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth)
|
||||
: m_colShape(colShape),
|
||||
m_gimpactShape(meshShape),
|
||||
m_depth(depth)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
|
||||
{
|
||||
btVector3 scale = m_gimpactShape->getLocalScaling();
|
||||
btVector3 v0 = triangle[0] * scale;
|
||||
btVector3 v1 = triangle[1] * scale;
|
||||
btVector3 v2 = triangle[2] * scale;
|
||||
|
||||
btVector3 centroid = (v0 + v1 + v2) / 3;
|
||||
btVector3 normal = (v1 - v0).cross(v2 - v0);
|
||||
normal.normalize();
|
||||
btVector3 rayFrom = centroid;
|
||||
btVector3 rayTo = centroid - normal * m_depth;
|
||||
|
||||
MyCallback cb(rayFrom, rayTo, partId, triangleIndex);
|
||||
|
||||
m_gimpactShape->processAllTrianglesRay(&cb, rayFrom, rayTo);
|
||||
if (cb.m_hitFraction < 1)
|
||||
{
|
||||
const btGImpactMeshShape* m_gimpactShape;
|
||||
btCompoundShape* m_colShape;
|
||||
btScalar m_depth;
|
||||
rayTo.setInterpolate3(cb.m_from, cb.m_to, cb.m_hitFraction);
|
||||
//rayTo = cb.m_from;
|
||||
//rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction);
|
||||
//gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0));
|
||||
}
|
||||
|
||||
MyInternalTriangleIndexCallback (btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth)
|
||||
:m_colShape(colShape),
|
||||
m_gimpactShape(meshShape),
|
||||
m_depth(depth)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
|
||||
{
|
||||
btVector3 scale = m_gimpactShape->getLocalScaling();
|
||||
btVector3 v0=triangle[0]*scale;
|
||||
btVector3 v1=triangle[1]*scale;
|
||||
btVector3 v2=triangle[2]*scale;
|
||||
|
||||
btVector3 centroid = (v0+v1+v2)/3;
|
||||
btVector3 normal = (v1-v0).cross(v2-v0);
|
||||
normal.normalize();
|
||||
btVector3 rayFrom = centroid;
|
||||
btVector3 rayTo = centroid-normal*m_depth;
|
||||
|
||||
MyCallback cb(rayFrom,rayTo,partId,triangleIndex);
|
||||
|
||||
m_gimpactShape->processAllTrianglesRay(&cb,rayFrom, rayTo);
|
||||
if (cb.m_hitFraction<1)
|
||||
{
|
||||
rayTo.setInterpolate3(cb.m_from,cb.m_to,cb.m_hitFraction);
|
||||
//rayTo = cb.m_from;
|
||||
//rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction);
|
||||
//gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0));
|
||||
}
|
||||
|
||||
btBU_Simplex1to4* tet = new btBU_Simplex1to4(v0, v1, v2, rayTo);
|
||||
btTransform ident;
|
||||
ident.setIdentity();
|
||||
m_colShape->addChildShape(ident, tet);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
btBU_Simplex1to4* tet = new btBU_Simplex1to4(v0,v1,v2,rayTo);
|
||||
btTransform ident;
|
||||
ident.setIdentity();
|
||||
m_colShape->addChildShape(ident,tet);
|
||||
}
|
||||
};
|
||||
|
||||
btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth)
|
||||
btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth)
|
||||
{
|
||||
btCompoundShape* colShape = new btCompoundFromGimpactShape();
|
||||
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
|
||||
MyInternalTriangleIndexCallback cb(colShape,gimpactMesh, depth);
|
||||
btVector3 aabbMin,aabbMax;
|
||||
gimpactMesh->getAabb(tr,aabbMin,aabbMax);
|
||||
gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb,aabbMin,aabbMax);
|
||||
|
||||
return colShape;
|
||||
}
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
|
||||
#endif //BT_COMPOUND_FROM_GIMPACT
|
||||
MyInternalTriangleIndexCallback cb(colShape, gimpactMesh, depth);
|
||||
btVector3 aabbMin, aabbMax;
|
||||
gimpactMesh->getAabb(tr, aabbMin, aabbMax);
|
||||
gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb, aabbMin, aabbMax);
|
||||
|
||||
return colShape;
|
||||
}
|
||||
|
||||
#endif //BT_COMPOUND_FROM_GIMPACT
|
||||
|
||||
@@ -27,54 +27,50 @@ struct CONTACT_KEY_TOKEN
|
||||
unsigned int m_key;
|
||||
int m_value;
|
||||
CONTACT_KEY_TOKEN()
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
CONTACT_KEY_TOKEN(unsigned int key,int token)
|
||||
{
|
||||
m_key = key;
|
||||
m_value = token;
|
||||
}
|
||||
CONTACT_KEY_TOKEN(unsigned int key, int token)
|
||||
{
|
||||
m_key = key;
|
||||
m_value = token;
|
||||
}
|
||||
|
||||
CONTACT_KEY_TOKEN(const CONTACT_KEY_TOKEN& rtoken)
|
||||
{
|
||||
m_key = rtoken.m_key;
|
||||
m_value = rtoken.m_value;
|
||||
}
|
||||
CONTACT_KEY_TOKEN(const CONTACT_KEY_TOKEN& rtoken)
|
||||
{
|
||||
m_key = rtoken.m_key;
|
||||
m_value = rtoken.m_value;
|
||||
}
|
||||
|
||||
inline bool operator <(const CONTACT_KEY_TOKEN& other) const
|
||||
inline bool operator<(const CONTACT_KEY_TOKEN& other) const
|
||||
{
|
||||
return (m_key < other.m_key);
|
||||
}
|
||||
|
||||
inline bool operator >(const CONTACT_KEY_TOKEN& other) const
|
||||
inline bool operator>(const CONTACT_KEY_TOKEN& other) const
|
||||
{
|
||||
return (m_key > other.m_key);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class CONTACT_KEY_TOKEN_COMP
|
||||
{
|
||||
public:
|
||||
|
||||
bool operator() ( const CONTACT_KEY_TOKEN& a, const CONTACT_KEY_TOKEN& b ) const
|
||||
{
|
||||
return ( a < b );
|
||||
}
|
||||
public:
|
||||
bool operator()(const CONTACT_KEY_TOKEN& a, const CONTACT_KEY_TOKEN& b) const
|
||||
{
|
||||
return (a < b);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void btContactArray::merge_contacts(
|
||||
const btContactArray & contacts, bool normal_contact_average)
|
||||
const btContactArray& contacts, bool normal_contact_average)
|
||||
{
|
||||
clear();
|
||||
|
||||
int i;
|
||||
if(contacts.size()==0) return;
|
||||
if (contacts.size() == 0) return;
|
||||
|
||||
|
||||
if(contacts.size()==1)
|
||||
if (contacts.size() == 1)
|
||||
{
|
||||
push_back(contacts[0]);
|
||||
return;
|
||||
@@ -86,16 +82,16 @@ void btContactArray::merge_contacts(
|
||||
|
||||
//fill key contacts
|
||||
|
||||
for ( i = 0;i<contacts.size() ;i++ )
|
||||
for (i = 0; i < contacts.size(); i++)
|
||||
{
|
||||
keycontacts.push_back(CONTACT_KEY_TOKEN(contacts[i].calc_key_contact(),i));
|
||||
keycontacts.push_back(CONTACT_KEY_TOKEN(contacts[i].calc_key_contact(), i));
|
||||
}
|
||||
|
||||
//sort keys
|
||||
keycontacts.quickSort(CONTACT_KEY_TOKEN_COMP());
|
||||
|
||||
// Merge contacts
|
||||
int coincident_count=0;
|
||||
int coincident_count = 0;
|
||||
btVector3 coincident_normals[MAX_COINCIDENT];
|
||||
|
||||
unsigned int last_key = keycontacts[0].m_key;
|
||||
@@ -103,56 +99,56 @@ void btContactArray::merge_contacts(
|
||||
|
||||
push_back(contacts[keycontacts[0].m_value]);
|
||||
|
||||
GIM_CONTACT * pcontact = &(*this)[0];
|
||||
GIM_CONTACT* pcontact = &(*this)[0];
|
||||
|
||||
for( i=1;i<keycontacts.size();i++)
|
||||
for (i = 1; i < keycontacts.size(); i++)
|
||||
{
|
||||
key = keycontacts[i].m_key;
|
||||
const GIM_CONTACT * scontact = &contacts[keycontacts[i].m_value];
|
||||
key = keycontacts[i].m_key;
|
||||
const GIM_CONTACT* scontact = &contacts[keycontacts[i].m_value];
|
||||
|
||||
if(last_key == key)//same points
|
||||
if (last_key == key) //same points
|
||||
{
|
||||
//merge contact
|
||||
if(pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//)
|
||||
if (pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth) //)
|
||||
{
|
||||
*pcontact = *scontact;
|
||||
coincident_count = 0;
|
||||
coincident_count = 0;
|
||||
}
|
||||
else if(normal_contact_average)
|
||||
else if (normal_contact_average)
|
||||
{
|
||||
if(btFabs(pcontact->m_depth - scontact->m_depth)<CONTACT_DIFF_EPSILON)
|
||||
{
|
||||
if(coincident_count<MAX_COINCIDENT)
|
||||
{
|
||||
coincident_normals[coincident_count] = scontact->m_normal;
|
||||
coincident_count++;
|
||||
}
|
||||
}
|
||||
if (btFabs(pcontact->m_depth - scontact->m_depth) < CONTACT_DIFF_EPSILON)
|
||||
{
|
||||
if (coincident_count < MAX_COINCIDENT)
|
||||
{
|
||||
coincident_normals[coincident_count] = scontact->m_normal;
|
||||
coincident_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{//add new contact
|
||||
{ //add new contact
|
||||
|
||||
if(normal_contact_average && coincident_count>0)
|
||||
{
|
||||
pcontact->interpolate_normals(coincident_normals,coincident_count);
|
||||
coincident_count = 0;
|
||||
}
|
||||
if (normal_contact_average && coincident_count > 0)
|
||||
{
|
||||
pcontact->interpolate_normals(coincident_normals, coincident_count);
|
||||
coincident_count = 0;
|
||||
}
|
||||
|
||||
push_back(*scontact);
|
||||
pcontact = &(*this)[this->size()-1];
|
||||
}
|
||||
push_back(*scontact);
|
||||
pcontact = &(*this)[this->size() - 1];
|
||||
}
|
||||
last_key = key;
|
||||
}
|
||||
}
|
||||
|
||||
void btContactArray::merge_contacts_unique(const btContactArray & contacts)
|
||||
void btContactArray::merge_contacts_unique(const btContactArray& contacts)
|
||||
{
|
||||
clear();
|
||||
|
||||
if(contacts.size()==0) return;
|
||||
if (contacts.size() == 0) return;
|
||||
|
||||
if(contacts.size()==1)
|
||||
if (contacts.size() == 1)
|
||||
{
|
||||
push_back(contacts[0]);
|
||||
return;
|
||||
@@ -160,14 +156,14 @@ void btContactArray::merge_contacts_unique(const btContactArray & contacts)
|
||||
|
||||
GIM_CONTACT average_contact = contacts[0];
|
||||
|
||||
for (int i=1;i<contacts.size() ;i++ )
|
||||
for (int i = 1; i < contacts.size(); i++)
|
||||
{
|
||||
average_contact.m_point += contacts[i].m_point;
|
||||
average_contact.m_normal += contacts[i].m_normal * contacts[i].m_depth;
|
||||
}
|
||||
|
||||
//divide
|
||||
btScalar divide_average = 1.0f/((btScalar)contacts.size());
|
||||
btScalar divide_average = 1.0f / ((btScalar)contacts.size());
|
||||
|
||||
average_contact.m_point *= divide_average;
|
||||
|
||||
@@ -176,6 +172,4 @@ void btContactArray::merge_contacts_unique(const btContactArray & contacts)
|
||||
average_contact.m_depth = average_contact.m_normal.length();
|
||||
|
||||
average_contact.m_normal /= average_contact.m_depth;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ subject to the following restrictions:
|
||||
#include "btTriangleShapeEx.h"
|
||||
#include "btContactProcessingStructs.h"
|
||||
|
||||
class btContactArray:public btAlignedObjectArray<GIM_CONTACT>
|
||||
class btContactArray : public btAlignedObjectArray<GIM_CONTACT>
|
||||
{
|
||||
public:
|
||||
btContactArray()
|
||||
@@ -38,28 +38,28 @@ public:
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void push_contact(
|
||||
const btVector3 &point,const btVector3 & normal,
|
||||
const btVector3 &point, const btVector3 &normal,
|
||||
btScalar depth, int feature1, int feature2)
|
||||
{
|
||||
push_back( GIM_CONTACT(point,normal,depth,feature1,feature2) );
|
||||
push_back(GIM_CONTACT(point, normal, depth, feature1, feature2));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void push_triangle_contacts(
|
||||
const GIM_TRIANGLE_CONTACT & tricontact,
|
||||
int feature1,int feature2)
|
||||
const GIM_TRIANGLE_CONTACT &tricontact,
|
||||
int feature1, int feature2)
|
||||
{
|
||||
for(int i = 0;i<tricontact.m_point_count ;i++ )
|
||||
for (int i = 0; i < tricontact.m_point_count; i++)
|
||||
{
|
||||
push_contact(
|
||||
tricontact.m_points[i],
|
||||
tricontact.m_separating_normal,
|
||||
tricontact.m_penetration_depth,feature1,feature2);
|
||||
tricontact.m_penetration_depth, feature1, feature2);
|
||||
}
|
||||
}
|
||||
|
||||
void merge_contacts(const btContactArray & contacts, bool normal_contact_average = true);
|
||||
void merge_contacts(const btContactArray &contacts, bool normal_contact_average = true);
|
||||
|
||||
void merge_contacts_unique(const btContactArray & contacts);
|
||||
void merge_contacts_unique(const btContactArray &contacts);
|
||||
};
|
||||
|
||||
#endif // GIM_CONTACT_H_INCLUDED
|
||||
#endif // GIM_CONTACT_H_INCLUDED
|
||||
|
||||
@@ -28,7 +28,6 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "btTriangleShapeEx.h"
|
||||
|
||||
|
||||
/**
|
||||
Configuration var for applying interpolation of contact normals
|
||||
*/
|
||||
@@ -41,69 +40,66 @@ Configuration var for applying interpolation of contact normals
|
||||
class GIM_CONTACT
|
||||
{
|
||||
public:
|
||||
btVector3 m_point;
|
||||
btVector3 m_normal;
|
||||
btScalar m_depth;//Positive value indicates interpenetration
|
||||
btScalar m_distance;//Padding not for use
|
||||
int m_feature1;//Face number
|
||||
int m_feature2;//Face number
|
||||
btVector3 m_point;
|
||||
btVector3 m_normal;
|
||||
btScalar m_depth; //Positive value indicates interpenetration
|
||||
btScalar m_distance; //Padding not for use
|
||||
int m_feature1; //Face number
|
||||
int m_feature2; //Face number
|
||||
public:
|
||||
GIM_CONTACT()
|
||||
{
|
||||
}
|
||||
GIM_CONTACT()
|
||||
{
|
||||
}
|
||||
|
||||
GIM_CONTACT(const GIM_CONTACT & contact):
|
||||
m_point(contact.m_point),
|
||||
m_normal(contact.m_normal),
|
||||
m_depth(contact.m_depth),
|
||||
m_feature1(contact.m_feature1),
|
||||
m_feature2(contact.m_feature2)
|
||||
{
|
||||
}
|
||||
GIM_CONTACT(const GIM_CONTACT &contact) : m_point(contact.m_point),
|
||||
m_normal(contact.m_normal),
|
||||
m_depth(contact.m_depth),
|
||||
m_feature1(contact.m_feature1),
|
||||
m_feature2(contact.m_feature2)
|
||||
{
|
||||
}
|
||||
|
||||
GIM_CONTACT(const btVector3 &point,const btVector3 & normal,
|
||||
btScalar depth, int feature1, int feature2):
|
||||
m_point(point),
|
||||
m_normal(normal),
|
||||
m_depth(depth),
|
||||
m_feature1(feature1),
|
||||
m_feature2(feature2)
|
||||
{
|
||||
}
|
||||
GIM_CONTACT(const btVector3 &point, const btVector3 &normal,
|
||||
btScalar depth, int feature1, int feature2) : m_point(point),
|
||||
m_normal(normal),
|
||||
m_depth(depth),
|
||||
m_feature1(feature1),
|
||||
m_feature2(feature2)
|
||||
{
|
||||
}
|
||||
|
||||
//! Calcs key for coord classification
|
||||
SIMD_FORCE_INLINE unsigned int calc_key_contact() const
|
||||
{
|
||||
int _coords[] = {
|
||||
(int)(m_point[0]*1000.0f+1.0f),
|
||||
(int)(m_point[1]*1333.0f),
|
||||
(int)(m_point[2]*2133.0f+3.0f)};
|
||||
unsigned int _hash=0;
|
||||
SIMD_FORCE_INLINE unsigned int calc_key_contact() const
|
||||
{
|
||||
int _coords[] = {
|
||||
(int)(m_point[0] * 1000.0f + 1.0f),
|
||||
(int)(m_point[1] * 1333.0f),
|
||||
(int)(m_point[2] * 2133.0f + 3.0f)};
|
||||
unsigned int _hash = 0;
|
||||
unsigned int *_uitmp = (unsigned int *)(&_coords[0]);
|
||||
_hash = *_uitmp;
|
||||
_uitmp++;
|
||||
_hash += (*_uitmp)<<4;
|
||||
_hash += (*_uitmp) << 4;
|
||||
_uitmp++;
|
||||
_hash += (*_uitmp)<<8;
|
||||
_hash += (*_uitmp) << 8;
|
||||
return _hash;
|
||||
}
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void interpolate_normals( btVector3 * normals,int normal_count)
|
||||
{
|
||||
btVector3 vec_sum(m_normal);
|
||||
for(int i=0;i<normal_count;i++)
|
||||
SIMD_FORCE_INLINE void interpolate_normals(btVector3 *normals, int normal_count)
|
||||
{
|
||||
btVector3 vec_sum(m_normal);
|
||||
for (int i = 0; i < normal_count; i++)
|
||||
{
|
||||
vec_sum += normals[i];
|
||||
}
|
||||
|
||||
btScalar vec_sum_len = vec_sum.length2();
|
||||
if(vec_sum_len <CONTACT_DIFF_EPSILON) return;
|
||||
if (vec_sum_len < CONTACT_DIFF_EPSILON) return;
|
||||
|
||||
//GIM_INV_SQRT(vec_sum_len,vec_sum_len); // 1/sqrt(vec_sum_len)
|
||||
|
||||
m_normal = vec_sum/btSqrt(vec_sum_len);
|
||||
}
|
||||
|
||||
m_normal = vec_sum / btSqrt(vec_sum_len);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BT_CONTACT_H_STRUCTS_INCLUDED
|
||||
#endif // BT_CONTACT_H_STRUCTS_INCLUDED
|
||||
|
||||
@@ -30,7 +30,6 @@ btClock g_tree_clock;
|
||||
float g_accum_tree_collision_time = 0;
|
||||
int g_count_traversing = 0;
|
||||
|
||||
|
||||
void bt_begin_gim02_tree_time()
|
||||
{
|
||||
g_tree_clock.reset();
|
||||
@@ -45,7 +44,7 @@ void bt_end_gim02_tree_time()
|
||||
//! Gets the average time in miliseconds of tree collisions
|
||||
float btGImpactBvh::getAverageTreeCollisionTime()
|
||||
{
|
||||
if(g_count_traversing == 0) return 0;
|
||||
if (g_count_traversing == 0) return 0;
|
||||
|
||||
float avgtime = g_accum_tree_collision_time;
|
||||
avgtime /= (float)g_count_traversing;
|
||||
@@ -54,80 +53,76 @@ float btGImpactBvh::getAverageTreeCollisionTime()
|
||||
g_count_traversing = 0;
|
||||
return avgtime;
|
||||
|
||||
// float avgtime = g_count_traversing;
|
||||
// g_count_traversing = 0;
|
||||
// return avgtime;
|
||||
|
||||
// float avgtime = g_count_traversing;
|
||||
// g_count_traversing = 0;
|
||||
// return avgtime;
|
||||
}
|
||||
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
/////////////////////// btBvhTree /////////////////////////////////
|
||||
|
||||
int btBvhTree::_calc_splitting_axis(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
int numIndices = endIndex-startIndex;
|
||||
btVector3 means(btScalar(0.), btScalar(0.), btScalar(0.));
|
||||
btVector3 variance(btScalar(0.), btScalar(0.), btScalar(0.));
|
||||
int numIndices = endIndex - startIndex;
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means+=center;
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means += center;
|
||||
}
|
||||
means *= (btScalar(1.)/(btScalar)numIndices);
|
||||
means *= (btScalar(1.) / (btScalar)numIndices);
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
btVector3 diff2 = center-means;
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
btVector3 diff2 = center - means;
|
||||
diff2 = diff2 * diff2;
|
||||
variance += diff2;
|
||||
}
|
||||
variance *= (btScalar(1.)/ ((btScalar)numIndices-1) );
|
||||
variance *= (btScalar(1.) / ((btScalar)numIndices - 1));
|
||||
|
||||
return variance.maxAxis();
|
||||
}
|
||||
|
||||
|
||||
int btBvhTree::_sort_and_calc_splitting_index(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex,
|
||||
int endIndex, int splitAxis)
|
||||
{
|
||||
int i;
|
||||
int splitIndex =startIndex;
|
||||
int splitIndex = startIndex;
|
||||
int numIndices = endIndex - startIndex;
|
||||
|
||||
// average of centers
|
||||
btScalar splitValue = 0.0f;
|
||||
|
||||
btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
btVector3 means(btScalar(0.), btScalar(0.), btScalar(0.));
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means+=center;
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means += center;
|
||||
}
|
||||
means *= (btScalar(1.)/(btScalar)numIndices);
|
||||
means *= (btScalar(1.) / (btScalar)numIndices);
|
||||
|
||||
splitValue = means[splitAxis];
|
||||
|
||||
|
||||
//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
if (center[splitAxis] > splitValue)
|
||||
{
|
||||
//swap
|
||||
primitive_boxes.swap(i,splitIndex);
|
||||
primitive_boxes.swap(i, splitIndex);
|
||||
//swapLeafNodes(i,splitIndex);
|
||||
splitIndex++;
|
||||
}
|
||||
@@ -142,32 +137,30 @@ int btBvhTree::_sort_and_calc_splitting_index(
|
||||
//bool unbalanced2 = true;
|
||||
|
||||
//this should be safe too:
|
||||
int rangeBalancedIndices = numIndices/3;
|
||||
bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
|
||||
int rangeBalancedIndices = numIndices / 3;
|
||||
bool unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices)));
|
||||
|
||||
if (unbalanced)
|
||||
{
|
||||
splitIndex = startIndex+ (numIndices>>1);
|
||||
splitIndex = startIndex + (numIndices >> 1);
|
||||
}
|
||||
|
||||
btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
|
||||
btAssert(!((splitIndex == startIndex) || (splitIndex == (endIndex))));
|
||||
|
||||
return splitIndex;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
|
||||
void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex)
|
||||
{
|
||||
int curIndex = m_num_nodes;
|
||||
m_num_nodes++;
|
||||
|
||||
btAssert((endIndex-startIndex)>0);
|
||||
btAssert((endIndex - startIndex) > 0);
|
||||
|
||||
if ((endIndex-startIndex)==1)
|
||||
if ((endIndex - startIndex) == 1)
|
||||
{
|
||||
//We have a leaf node
|
||||
setNodeBound(curIndex,primitive_boxes[startIndex].m_bound);
|
||||
//We have a leaf node
|
||||
setNodeBound(curIndex, primitive_boxes[startIndex].m_bound);
|
||||
m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data);
|
||||
|
||||
return;
|
||||
@@ -175,47 +168,42 @@ void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startI
|
||||
//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
|
||||
|
||||
//split axis
|
||||
int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex);
|
||||
int splitIndex = _calc_splitting_axis(primitive_boxes, startIndex, endIndex);
|
||||
|
||||
splitIndex = _sort_and_calc_splitting_index(
|
||||
primitive_boxes,startIndex,endIndex,
|
||||
splitIndex//split axis
|
||||
);
|
||||
|
||||
primitive_boxes, startIndex, endIndex,
|
||||
splitIndex //split axis
|
||||
);
|
||||
|
||||
//calc this node bounding box
|
||||
|
||||
btAABB node_bound;
|
||||
node_bound.invalidate();
|
||||
|
||||
for (int i=startIndex;i<endIndex;i++)
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
node_bound.merge(primitive_boxes[i].m_bound);
|
||||
}
|
||||
|
||||
setNodeBound(curIndex,node_bound);
|
||||
|
||||
setNodeBound(curIndex, node_bound);
|
||||
|
||||
//build left branch
|
||||
_build_sub_tree(primitive_boxes, startIndex, splitIndex );
|
||||
|
||||
_build_sub_tree(primitive_boxes, startIndex, splitIndex);
|
||||
|
||||
//build right branch
|
||||
_build_sub_tree(primitive_boxes, splitIndex ,endIndex);
|
||||
_build_sub_tree(primitive_boxes, splitIndex, endIndex);
|
||||
|
||||
m_node_array[curIndex].setEscapeIndex(m_num_nodes - curIndex);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//! stackless build tree
|
||||
void btBvhTree::build_tree(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes)
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes)
|
||||
{
|
||||
// initialize node count to 0
|
||||
m_num_nodes = 0;
|
||||
// allocate nodes
|
||||
m_node_array.resize(primitive_boxes.size()*2);
|
||||
m_node_array.resize(primitive_boxes.size() * 2);
|
||||
|
||||
_build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
|
||||
}
|
||||
@@ -225,13 +213,13 @@ void btBvhTree::build_tree(
|
||||
void btGImpactBvh::refit()
|
||||
{
|
||||
int nodecount = getNodeCount();
|
||||
while(nodecount--)
|
||||
while (nodecount--)
|
||||
{
|
||||
if(isLeafNode(nodecount))
|
||||
if (isLeafNode(nodecount))
|
||||
{
|
||||
btAABB leafbox;
|
||||
m_primitive_manager->get_primitive_box(getNodeData(nodecount),leafbox);
|
||||
setNodeBound(nodecount,leafbox);
|
||||
m_primitive_manager->get_primitive_box(getNodeData(nodecount), leafbox);
|
||||
setNodeBound(nodecount, leafbox);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -243,20 +231,20 @@ void btGImpactBvh::refit()
|
||||
btAABB temp_box;
|
||||
|
||||
int child_node = getLeftNode(nodecount);
|
||||
if(child_node)
|
||||
if (child_node)
|
||||
{
|
||||
getNodeBound(child_node,temp_box);
|
||||
getNodeBound(child_node, temp_box);
|
||||
bound.merge(temp_box);
|
||||
}
|
||||
|
||||
child_node = getRightNode(nodecount);
|
||||
if(child_node)
|
||||
if (child_node)
|
||||
{
|
||||
getNodeBound(child_node,temp_box);
|
||||
getNodeBound(child_node, temp_box);
|
||||
bound.merge(temp_box);
|
||||
}
|
||||
|
||||
setNodeBound(nodecount,bound);
|
||||
setNodeBound(nodecount, bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,17 +256,17 @@ void btGImpactBvh::buildSet()
|
||||
GIM_BVH_DATA_ARRAY primitive_boxes;
|
||||
primitive_boxes.resize(m_primitive_manager->get_primitive_count());
|
||||
|
||||
for (int i = 0;i<primitive_boxes.size() ;i++ )
|
||||
for (int i = 0; i < primitive_boxes.size(); i++)
|
||||
{
|
||||
m_primitive_manager->get_primitive_box(i,primitive_boxes[i].m_bound);
|
||||
primitive_boxes[i].m_data = i;
|
||||
m_primitive_manager->get_primitive_box(i, primitive_boxes[i].m_bound);
|
||||
primitive_boxes[i].m_data = i;
|
||||
}
|
||||
|
||||
m_box_tree.build_tree(primitive_boxes);
|
||||
}
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
bool btGImpactBvh::boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const
|
||||
bool btGImpactBvh::boxQuery(const btAABB& box, btAlignedObjectArray<int>& collided_results) const
|
||||
{
|
||||
int curIndex = 0;
|
||||
int numNodes = getNodeCount();
|
||||
@@ -286,7 +274,7 @@ bool btGImpactBvh::boxQuery(const btAABB & box, btAlignedObjectArray<int> & coll
|
||||
while (curIndex < numNodes)
|
||||
{
|
||||
btAABB bound;
|
||||
getNodeBound(curIndex,bound);
|
||||
getNodeBound(curIndex, bound);
|
||||
|
||||
//catch bugs in tree data
|
||||
|
||||
@@ -306,19 +294,17 @@ bool btGImpactBvh::boxQuery(const btAABB & box, btAlignedObjectArray<int> & coll
|
||||
else
|
||||
{
|
||||
//skip node
|
||||
curIndex+= getEscapeNodeIndex(curIndex);
|
||||
curIndex += getEscapeNodeIndex(curIndex);
|
||||
}
|
||||
}
|
||||
if(collided_results.size()>0) return true;
|
||||
if (collided_results.size() > 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
bool btGImpactBvh::rayQuery(
|
||||
const btVector3 & ray_dir,const btVector3 & ray_origin ,
|
||||
btAlignedObjectArray<int> & collided_results) const
|
||||
const btVector3& ray_dir, const btVector3& ray_origin,
|
||||
btAlignedObjectArray<int>& collided_results) const
|
||||
{
|
||||
int curIndex = 0;
|
||||
int numNodes = getNodeCount();
|
||||
@@ -326,16 +312,16 @@ bool btGImpactBvh::rayQuery(
|
||||
while (curIndex < numNodes)
|
||||
{
|
||||
btAABB bound;
|
||||
getNodeBound(curIndex,bound);
|
||||
getNodeBound(curIndex, bound);
|
||||
|
||||
//catch bugs in tree data
|
||||
|
||||
bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir);
|
||||
bool aabbOverlap = bound.collide_ray(ray_origin, ray_dir);
|
||||
bool isleafnode = isLeafNode(curIndex);
|
||||
|
||||
if (isleafnode && aabbOverlap)
|
||||
{
|
||||
collided_results.push_back(getNodeData( curIndex));
|
||||
collided_results.push_back(getNodeData(curIndex));
|
||||
}
|
||||
|
||||
if (aabbOverlap || isleafnode)
|
||||
@@ -346,153 +332,133 @@ bool btGImpactBvh::rayQuery(
|
||||
else
|
||||
{
|
||||
//skip node
|
||||
curIndex+= getEscapeNodeIndex(curIndex);
|
||||
curIndex += getEscapeNodeIndex(curIndex);
|
||||
}
|
||||
}
|
||||
if(collided_results.size()>0) return true;
|
||||
if (collided_results.size() > 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool _node_collision(
|
||||
btGImpactBvh * boxset0, btGImpactBvh * boxset1,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
|
||||
int node0 ,int node1, bool complete_primitive_tests)
|
||||
btGImpactBvh* boxset0, btGImpactBvh* boxset1,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE& trans_cache_1to0,
|
||||
int node0, int node1, bool complete_primitive_tests)
|
||||
{
|
||||
btAABB box0;
|
||||
boxset0->getNodeBound(node0,box0);
|
||||
boxset0->getNodeBound(node0, box0);
|
||||
btAABB box1;
|
||||
boxset1->getNodeBound(node1,box1);
|
||||
|
||||
return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests );
|
||||
// box1.appy_transform_trans_cache(trans_cache_1to0);
|
||||
// return box0.has_collision(box1);
|
||||
boxset1->getNodeBound(node1, box1);
|
||||
|
||||
return box0.overlapping_trans_cache(box1, trans_cache_1to0, complete_primitive_tests);
|
||||
// box1.appy_transform_trans_cache(trans_cache_1to0);
|
||||
// return box0.has_collision(box1);
|
||||
}
|
||||
|
||||
|
||||
//stackless recursive collision routine
|
||||
static void _find_collision_pairs_recursive(
|
||||
btGImpactBvh * boxset0, btGImpactBvh * boxset1,
|
||||
btPairSet * collision_pairs,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
|
||||
btGImpactBvh* boxset0, btGImpactBvh* boxset1,
|
||||
btPairSet* collision_pairs,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE& trans_cache_1to0,
|
||||
int node0, int node1, bool complete_primitive_tests)
|
||||
{
|
||||
if (_node_collision(
|
||||
boxset0, boxset1, trans_cache_1to0,
|
||||
node0, node1, complete_primitive_tests) == false) return; //avoid colliding internal nodes
|
||||
|
||||
|
||||
|
||||
if( _node_collision(
|
||||
boxset0,boxset1,trans_cache_1to0,
|
||||
node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes
|
||||
|
||||
if(boxset0->isLeafNode(node0))
|
||||
if (boxset0->isLeafNode(node0))
|
||||
{
|
||||
if(boxset1->isLeafNode(node1))
|
||||
if (boxset1->isLeafNode(node1))
|
||||
{
|
||||
// collision result
|
||||
collision_pairs->push_pair(
|
||||
boxset0->getNodeData(node0),boxset1->getNodeData(node1));
|
||||
boxset0->getNodeData(node0), boxset1->getNodeData(node1));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//collide left recursive
|
||||
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
node0,boxset1->getLeftNode(node1),false);
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
node0, boxset1->getLeftNode(node1), false);
|
||||
|
||||
//collide right recursive
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
node0,boxset1->getRightNode(node1),false);
|
||||
|
||||
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
node0, boxset1->getRightNode(node1), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(boxset1->isLeafNode(node1))
|
||||
if (boxset1->isLeafNode(node1))
|
||||
{
|
||||
|
||||
//collide left recursive
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0),node1,false);
|
||||
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0), node1, false);
|
||||
|
||||
//collide right recursive
|
||||
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getRightNode(node0),node1,false);
|
||||
|
||||
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getRightNode(node0), node1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//collide left0 left1
|
||||
|
||||
|
||||
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false);
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0), boxset1->getLeftNode(node1), false);
|
||||
|
||||
//collide left0 right1
|
||||
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false);
|
||||
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0), boxset1->getRightNode(node1), false);
|
||||
|
||||
//collide right0 left1
|
||||
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false);
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getRightNode(node0), boxset1->getLeftNode(node1), false);
|
||||
|
||||
//collide right0 right1
|
||||
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getRightNode(node0),boxset1->getRightNode(node1),false);
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getRightNode(node0), boxset1->getRightNode(node1), false);
|
||||
|
||||
}// else if node1 is not a leaf
|
||||
}// else if node0 is not a leaf
|
||||
} // else if node1 is not a leaf
|
||||
} // else if node0 is not a leaf
|
||||
}
|
||||
|
||||
|
||||
void btGImpactBvh::find_collision(btGImpactBvh * boxset0, const btTransform & trans0,
|
||||
btGImpactBvh * boxset1, const btTransform & trans1,
|
||||
btPairSet & collision_pairs)
|
||||
void btGImpactBvh::find_collision(btGImpactBvh* boxset0, const btTransform& trans0,
|
||||
btGImpactBvh* boxset1, const btTransform& trans1,
|
||||
btPairSet& collision_pairs)
|
||||
{
|
||||
|
||||
if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return;
|
||||
if (boxset0->getNodeCount() == 0 || boxset1->getNodeCount() == 0) return;
|
||||
|
||||
BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0;
|
||||
|
||||
trans_cache_1to0.calc_from_homogenic(trans0,trans1);
|
||||
trans_cache_1to0.calc_from_homogenic(trans0, trans1);
|
||||
|
||||
#ifdef TRI_COLLISION_PROFILING
|
||||
bt_begin_gim02_tree_time();
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
_find_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
&collision_pairs,trans_cache_1to0,0,0,true);
|
||||
boxset0, boxset1,
|
||||
&collision_pairs, trans_cache_1to0, 0, 0, true);
|
||||
#ifdef TRI_COLLISION_PROFILING
|
||||
bt_end_gim02_tree_time();
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "btBoxCollision.h"
|
||||
@@ -32,50 +31,48 @@ subject to the following restrictions:
|
||||
#include "btGImpactBvhStructs.h"
|
||||
|
||||
//! A pairset array
|
||||
class btPairSet: public btAlignedObjectArray<GIM_PAIR>
|
||||
class btPairSet : public btAlignedObjectArray<GIM_PAIR>
|
||||
{
|
||||
public:
|
||||
btPairSet()
|
||||
{
|
||||
reserve(32);
|
||||
}
|
||||
inline void push_pair(int index1,int index2)
|
||||
inline void push_pair(int index1, int index2)
|
||||
{
|
||||
push_back(GIM_PAIR(index1,index2));
|
||||
push_back(GIM_PAIR(index1, index2));
|
||||
}
|
||||
|
||||
inline void push_pair_inv(int index1,int index2)
|
||||
inline void push_pair_inv(int index1, int index2)
|
||||
{
|
||||
push_back(GIM_PAIR(index2,index1));
|
||||
push_back(GIM_PAIR(index2, index1));
|
||||
}
|
||||
};
|
||||
|
||||
class GIM_BVH_DATA_ARRAY:public btAlignedObjectArray<GIM_BVH_DATA>
|
||||
class GIM_BVH_DATA_ARRAY : public btAlignedObjectArray<GIM_BVH_DATA>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
class GIM_BVH_TREE_NODE_ARRAY:public btAlignedObjectArray<GIM_BVH_TREE_NODE>
|
||||
class GIM_BVH_TREE_NODE_ARRAY : public btAlignedObjectArray<GIM_BVH_TREE_NODE>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//! Basic Box tree structure
|
||||
class btBvhTree
|
||||
{
|
||||
protected:
|
||||
int m_num_nodes;
|
||||
GIM_BVH_TREE_NODE_ARRAY m_node_array;
|
||||
|
||||
protected:
|
||||
int _sort_and_calc_splitting_index(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes,
|
||||
int startIndex, int endIndex, int splitAxis);
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes,
|
||||
int startIndex, int endIndex, int splitAxis);
|
||||
|
||||
int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
|
||||
int _calc_splitting_axis(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex);
|
||||
|
||||
void _build_sub_tree(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex);
|
||||
|
||||
void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
|
||||
public:
|
||||
btBvhTree()
|
||||
{
|
||||
@@ -84,7 +81,7 @@ public:
|
||||
|
||||
//! prototype functions for box tree management
|
||||
//!@{
|
||||
void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
|
||||
void build_tree(GIM_BVH_DATA_ARRAY& primitive_boxes);
|
||||
|
||||
SIMD_FORCE_INLINE void clearNodes()
|
||||
{
|
||||
@@ -109,25 +106,25 @@ public:
|
||||
return m_node_array[nodeindex].getDataIndex();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
|
||||
SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB& bound) const
|
||||
{
|
||||
bound = m_node_array[nodeindex].m_bound;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
|
||||
SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB& bound)
|
||||
{
|
||||
m_node_array[nodeindex].m_bound = bound;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
|
||||
{
|
||||
return nodeindex+1;
|
||||
return nodeindex + 1;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
|
||||
{
|
||||
if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2;
|
||||
return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex();
|
||||
if (m_node_array[nodeindex + 1].isLeafNode()) return nodeindex + 2;
|
||||
return nodeindex + 1 + m_node_array[nodeindex + 1].getEscapeIndex();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
|
||||
@@ -135,7 +132,7 @@ public:
|
||||
return m_node_array[nodeindex].getEscapeIndex();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const
|
||||
SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE* get_node_pointer(int index = 0) const
|
||||
{
|
||||
return &m_node_array[index];
|
||||
}
|
||||
@@ -143,7 +140,6 @@ public:
|
||||
//!@}
|
||||
};
|
||||
|
||||
|
||||
//! Prototype Base class for primitive classification
|
||||
/*!
|
||||
This class is a wrapper for primitive collections.
|
||||
@@ -153,18 +149,16 @@ This class can manage Compound shapes and trimeshes, and if it is managing trime
|
||||
class btPrimitiveManagerBase
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~btPrimitiveManagerBase() {}
|
||||
|
||||
//! determines if this manager consist on only triangles, which special case will be optimized
|
||||
virtual bool is_trimesh() const = 0;
|
||||
virtual int get_primitive_count() const = 0;
|
||||
virtual void get_primitive_box(int prim_index ,btAABB & primbox) const = 0;
|
||||
virtual void get_primitive_box(int prim_index, btAABB& primbox) const = 0;
|
||||
//! retrieves only the points of the triangle, and the collision margin
|
||||
virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const= 0;
|
||||
virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle& triangle) const = 0;
|
||||
};
|
||||
|
||||
|
||||
//! Structure for containing Boxes
|
||||
/*!
|
||||
This class offers an structure for managing a box tree of primitives.
|
||||
@@ -174,13 +168,13 @@ class btGImpactBvh
|
||||
{
|
||||
protected:
|
||||
btBvhTree m_box_tree;
|
||||
btPrimitiveManagerBase * m_primitive_manager;
|
||||
btPrimitiveManagerBase* m_primitive_manager;
|
||||
|
||||
protected:
|
||||
//stackless refit
|
||||
void refit();
|
||||
public:
|
||||
|
||||
public:
|
||||
//! this constructor doesn't build the tree. you must call buildSet
|
||||
btGImpactBvh()
|
||||
{
|
||||
@@ -188,31 +182,30 @@ public:
|
||||
}
|
||||
|
||||
//! this constructor doesn't build the tree. you must call buildSet
|
||||
btGImpactBvh(btPrimitiveManagerBase * primitive_manager)
|
||||
btGImpactBvh(btPrimitiveManagerBase* primitive_manager)
|
||||
{
|
||||
m_primitive_manager = primitive_manager;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btAABB getGlobalBox() const
|
||||
SIMD_FORCE_INLINE btAABB getGlobalBox() const
|
||||
{
|
||||
btAABB totalbox;
|
||||
getNodeBound(0, totalbox);
|
||||
return totalbox;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager)
|
||||
SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase* primitive_manager)
|
||||
{
|
||||
m_primitive_manager = primitive_manager;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
|
||||
SIMD_FORCE_INLINE btPrimitiveManagerBase* getPrimitiveManager() const
|
||||
{
|
||||
return m_primitive_manager;
|
||||
}
|
||||
|
||||
|
||||
//! node manager prototype functions
|
||||
///@{
|
||||
//! node manager prototype functions
|
||||
///@{
|
||||
|
||||
//! this attemps to refit the box set.
|
||||
SIMD_FORCE_INLINE void update()
|
||||
@@ -224,21 +217,21 @@ public:
|
||||
void buildSet();
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
|
||||
bool boxQuery(const btAABB& box, btAlignedObjectArray<int>& collided_results) const;
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box,
|
||||
const btTransform & transform, btAlignedObjectArray<int> & collided_results) const
|
||||
SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB& box,
|
||||
const btTransform& transform, btAlignedObjectArray<int>& collided_results) const
|
||||
{
|
||||
btAABB transbox=box;
|
||||
btAABB transbox = box;
|
||||
transbox.appy_transform(transform);
|
||||
return boxQuery(transbox,collided_results);
|
||||
return boxQuery(transbox, collided_results);
|
||||
}
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
bool rayQuery(
|
||||
const btVector3 & ray_dir,const btVector3 & ray_origin ,
|
||||
btAlignedObjectArray<int> & collided_results) const;
|
||||
const btVector3& ray_dir, const btVector3& ray_origin,
|
||||
btAlignedObjectArray<int>& collided_results) const;
|
||||
|
||||
//! tells if this set has hierarcht
|
||||
SIMD_FORCE_INLINE bool hasHierarchy() const
|
||||
@@ -247,7 +240,7 @@ public:
|
||||
}
|
||||
|
||||
//! tells if this set is a trimesh
|
||||
SIMD_FORCE_INLINE bool isTrimesh() const
|
||||
SIMD_FORCE_INLINE bool isTrimesh() const
|
||||
{
|
||||
return m_primitive_manager->is_trimesh();
|
||||
}
|
||||
@@ -269,17 +262,16 @@ public:
|
||||
return m_box_tree.getNodeData(nodeindex);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
|
||||
SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB& bound) const
|
||||
{
|
||||
m_box_tree.getNodeBound(nodeindex, bound);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
|
||||
SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB& bound)
|
||||
{
|
||||
m_box_tree.setNodeBound(nodeindex, bound);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
|
||||
{
|
||||
return m_box_tree.getLeftNode(nodeindex);
|
||||
@@ -295,24 +287,23 @@ public:
|
||||
return m_box_tree.getEscapeNodeIndex(nodeindex);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const
|
||||
SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex, btPrimitiveTriangle& triangle) const
|
||||
{
|
||||
m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle);
|
||||
m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex), triangle);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const
|
||||
SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE* get_node_pointer(int index = 0) const
|
||||
{
|
||||
return m_box_tree.get_node_pointer(index);
|
||||
}
|
||||
|
||||
#ifdef TRI_COLLISION_PROFILING
|
||||
static float getAverageTreeCollisionTime();
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
static void find_collision(btGImpactBvh * boxset1, const btTransform & trans1,
|
||||
btGImpactBvh * boxset2, const btTransform & trans2,
|
||||
btPairSet & collision_pairs);
|
||||
static void find_collision(btGImpactBvh* boxset1, const btTransform& trans1,
|
||||
btGImpactBvh* boxset2, const btTransform& trans2,
|
||||
btPairSet& collision_pairs);
|
||||
};
|
||||
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
|
||||
@@ -24,7 +24,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "btBoxCollision.h"
|
||||
@@ -33,21 +32,22 @@ subject to the following restrictions:
|
||||
//! Overlapping pair
|
||||
struct GIM_PAIR
|
||||
{
|
||||
int m_index1;
|
||||
int m_index2;
|
||||
GIM_PAIR()
|
||||
{}
|
||||
int m_index1;
|
||||
int m_index2;
|
||||
GIM_PAIR()
|
||||
{
|
||||
}
|
||||
|
||||
GIM_PAIR(const GIM_PAIR & p)
|
||||
{
|
||||
m_index1 = p.m_index1;
|
||||
m_index2 = p.m_index2;
|
||||
GIM_PAIR(const GIM_PAIR& p)
|
||||
{
|
||||
m_index1 = p.m_index1;
|
||||
m_index2 = p.m_index2;
|
||||
}
|
||||
|
||||
GIM_PAIR(int index1, int index2)
|
||||
{
|
||||
m_index1 = index1;
|
||||
m_index2 = index2;
|
||||
{
|
||||
m_index1 = index1;
|
||||
m_index2 = index2;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,8 +63,10 @@ class GIM_BVH_TREE_NODE
|
||||
{
|
||||
public:
|
||||
btAABB m_bound;
|
||||
|
||||
protected:
|
||||
int m_escapeIndexOrDataIndex;
|
||||
int m_escapeIndexOrDataIndex;
|
||||
|
||||
public:
|
||||
GIM_BVH_TREE_NODE()
|
||||
{
|
||||
@@ -74,7 +76,7 @@ public:
|
||||
SIMD_FORCE_INLINE bool isLeafNode() const
|
||||
{
|
||||
//skipindex is negative (internal node), triangleindex >=0 (leafnode)
|
||||
return (m_escapeIndexOrDataIndex>=0);
|
||||
return (m_escapeIndexOrDataIndex >= 0);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getEscapeIndex() const
|
||||
@@ -99,7 +101,6 @@ public:
|
||||
{
|
||||
m_escapeIndexOrDataIndex = index;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,7 +42,6 @@ class btDispatcher;
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
|
||||
|
||||
|
||||
//! Collision Algorithm for GImpact Shapes
|
||||
/*!
|
||||
For register this algorithm in Bullet, proceed as following:
|
||||
@@ -54,36 +53,35 @@ btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
|
||||
class btGImpactCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
protected:
|
||||
btCollisionAlgorithm * m_convex_algorithm;
|
||||
btPersistentManifold * m_manifoldPtr;
|
||||
btCollisionAlgorithm* m_convex_algorithm;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
btManifoldResult* m_resultOut;
|
||||
const btDispatcherInfo * m_dispatchInfo;
|
||||
const btDispatcherInfo* m_dispatchInfo;
|
||||
int m_triface0;
|
||||
int m_part0;
|
||||
int m_triface1;
|
||||
int m_part1;
|
||||
|
||||
|
||||
//! Creates a new contact point
|
||||
SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(const btCollisionObject* body0,const btCollisionObject* body1)
|
||||
SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(const btCollisionObject* body0, const btCollisionObject* body1)
|
||||
{
|
||||
m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
|
||||
m_manifoldPtr = m_dispatcher->getNewManifold(body0, body1);
|
||||
return m_manifoldPtr;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void destroyConvexAlgorithm()
|
||||
{
|
||||
if(m_convex_algorithm)
|
||||
if (m_convex_algorithm)
|
||||
{
|
||||
m_convex_algorithm->~btCollisionAlgorithm();
|
||||
m_dispatcher->freeCollisionAlgorithm( m_convex_algorithm);
|
||||
m_dispatcher->freeCollisionAlgorithm(m_convex_algorithm);
|
||||
m_convex_algorithm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void destroyContactManifolds()
|
||||
{
|
||||
if(m_manifoldPtr == NULL) return;
|
||||
if (m_manifoldPtr == NULL) return;
|
||||
m_dispatcher->releaseManifold(m_manifoldPtr);
|
||||
m_manifoldPtr = NULL;
|
||||
}
|
||||
@@ -104,207 +102,187 @@ protected:
|
||||
return m_manifoldPtr;
|
||||
}
|
||||
|
||||
|
||||
// Call before process collision
|
||||
SIMD_FORCE_INLINE void checkManifold(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
SIMD_FORCE_INLINE void checkManifold(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
if(getLastManifold() == 0)
|
||||
if (getLastManifold() == 0)
|
||||
{
|
||||
newContactManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
|
||||
newContactManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject());
|
||||
}
|
||||
|
||||
m_resultOut->setPersistentManifold(getLastManifold());
|
||||
}
|
||||
|
||||
// Call before process collision
|
||||
SIMD_FORCE_INLINE btCollisionAlgorithm * newAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
SIMD_FORCE_INLINE btCollisionAlgorithm* newAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
checkManifold(body0Wrap,body1Wrap);
|
||||
checkManifold(body0Wrap, body1Wrap);
|
||||
|
||||
btCollisionAlgorithm * convex_algorithm = m_dispatcher->findAlgorithm(
|
||||
body0Wrap,body1Wrap,getLastManifold(), BT_CONTACT_POINT_ALGORITHMS);
|
||||
return convex_algorithm ;
|
||||
btCollisionAlgorithm* convex_algorithm = m_dispatcher->findAlgorithm(
|
||||
body0Wrap, body1Wrap, getLastManifold(), BT_CONTACT_POINT_ALGORITHMS);
|
||||
return convex_algorithm;
|
||||
}
|
||||
|
||||
// Call before process collision
|
||||
SIMD_FORCE_INLINE void checkConvexAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
SIMD_FORCE_INLINE void checkConvexAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
if(m_convex_algorithm) return;
|
||||
m_convex_algorithm = newAlgorithm(body0Wrap,body1Wrap);
|
||||
if (m_convex_algorithm) return;
|
||||
m_convex_algorithm = newAlgorithm(body0Wrap, body1Wrap);
|
||||
}
|
||||
|
||||
void addContactPoint(const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btVector3& point,
|
||||
const btVector3& normal,
|
||||
btScalar distance);
|
||||
|
||||
|
||||
|
||||
void addContactPoint(const btCollisionObjectWrapper * body0Wrap,
|
||||
const btCollisionObjectWrapper * body1Wrap,
|
||||
const btVector3 & point,
|
||||
const btVector3 & normal,
|
||||
btScalar distance);
|
||||
|
||||
//! Collision routines
|
||||
//!@{
|
||||
//! Collision routines
|
||||
//!@{
|
||||
|
||||
void collide_gjk_triangles(const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactMeshShapePart * shape0,
|
||||
const btGImpactMeshShapePart * shape1,
|
||||
const int * pairs, int pair_count);
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactMeshShapePart* shape0,
|
||||
const btGImpactMeshShapePart* shape1,
|
||||
const int* pairs, int pair_count);
|
||||
|
||||
void collide_sat_triangles(const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactMeshShapePart * shape0,
|
||||
const btGImpactMeshShapePart * shape1,
|
||||
const int * pairs, int pair_count);
|
||||
|
||||
|
||||
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactMeshShapePart* shape0,
|
||||
const btGImpactMeshShapePart* shape1,
|
||||
const int* pairs, int pair_count);
|
||||
|
||||
void shape_vs_shape_collision(
|
||||
const btCollisionObjectWrapper* body0,
|
||||
const btCollisionObjectWrapper* body1,
|
||||
const btCollisionShape * shape0,
|
||||
const btCollisionShape * shape1);
|
||||
const btCollisionObjectWrapper* body0,
|
||||
const btCollisionObjectWrapper* body1,
|
||||
const btCollisionShape* shape0,
|
||||
const btCollisionShape* shape1);
|
||||
|
||||
void convex_vs_convex_collision(const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btCollisionShape* shape0,
|
||||
const btCollisionShape* shape1);
|
||||
|
||||
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btCollisionShape* shape0,
|
||||
const btCollisionShape* shape1);
|
||||
|
||||
void gimpact_vs_gimpact_find_pairs(
|
||||
const btTransform & trans0,
|
||||
const btTransform & trans1,
|
||||
const btGImpactShapeInterface * shape0,
|
||||
const btGImpactShapeInterface * shape1,btPairSet & pairset);
|
||||
const btTransform& trans0,
|
||||
const btTransform& trans1,
|
||||
const btGImpactShapeInterface* shape0,
|
||||
const btGImpactShapeInterface* shape1, btPairSet& pairset);
|
||||
|
||||
void gimpact_vs_shape_find_pairs(
|
||||
const btTransform & trans0,
|
||||
const btTransform & trans1,
|
||||
const btGImpactShapeInterface * shape0,
|
||||
const btCollisionShape * shape1,
|
||||
btAlignedObjectArray<int> & collided_primitives);
|
||||
|
||||
const btTransform& trans0,
|
||||
const btTransform& trans1,
|
||||
const btGImpactShapeInterface* shape0,
|
||||
const btCollisionShape* shape1,
|
||||
btAlignedObjectArray<int>& collided_primitives);
|
||||
|
||||
void gimpacttrimeshpart_vs_plane_collision(
|
||||
const btCollisionObjectWrapper * body0Wrap,
|
||||
const btCollisionObjectWrapper * body1Wrap,
|
||||
const btGImpactMeshShapePart * shape0,
|
||||
const btStaticPlaneShape * shape1,bool swapped);
|
||||
|
||||
const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactMeshShapePart* shape0,
|
||||
const btStaticPlaneShape* shape1, bool swapped);
|
||||
|
||||
public:
|
||||
|
||||
btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
|
||||
btGImpactCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap);
|
||||
|
||||
virtual ~btGImpactCollisionAlgorithm();
|
||||
|
||||
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut);
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
{
|
||||
if (m_manifoldPtr)
|
||||
manifoldArray.push_back(m_manifoldPtr);
|
||||
}
|
||||
|
||||
btManifoldResult* internalGetResultOut()
|
||||
btManifoldResult* internalGetResultOut()
|
||||
{
|
||||
return m_resultOut;
|
||||
}
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
struct CreateFunc : public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btGImpactCollisionAlgorithm));
|
||||
return new(mem) btGImpactCollisionAlgorithm(ci,body0Wrap,body1Wrap);
|
||||
return new (mem) btGImpactCollisionAlgorithm(ci, body0Wrap, body1Wrap);
|
||||
}
|
||||
};
|
||||
|
||||
//! Use this function for register the algorithm externally
|
||||
static void registerAlgorithm(btCollisionDispatcher * dispatcher);
|
||||
static void registerAlgorithm(btCollisionDispatcher* dispatcher);
|
||||
#ifdef TRI_COLLISION_PROFILING
|
||||
//! Gets the average time in miliseconds of tree collisions
|
||||
static float getAverageTreeCollisionTime();
|
||||
|
||||
//! Gets the average time in miliseconds of triangle collisions
|
||||
static float getAverageTriangleCollisionTime();
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
//! Collides two gimpact shapes
|
||||
/*!
|
||||
\pre shape0 and shape1 couldn't be btGImpactMeshShape objects
|
||||
*/
|
||||
|
||||
|
||||
void gimpact_vs_gimpact(const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper * body1Wrap,
|
||||
const btGImpactShapeInterface * shape0,
|
||||
const btGImpactShapeInterface * shape1);
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactShapeInterface* shape0,
|
||||
const btGImpactShapeInterface* shape1);
|
||||
|
||||
void gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactShapeInterface * shape0,
|
||||
const btCollisionShape * shape1,bool swapped);
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactShapeInterface* shape0,
|
||||
const btCollisionShape* shape1, bool swapped);
|
||||
|
||||
void gimpact_vs_compoundshape(const btCollisionObjectWrapper * body0Wrap,
|
||||
const btCollisionObjectWrapper * body1Wrap,
|
||||
const btGImpactShapeInterface * shape0,
|
||||
const btCompoundShape * shape1,bool swapped);
|
||||
void gimpact_vs_compoundshape(const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactShapeInterface* shape0,
|
||||
const btCompoundShape* shape1, bool swapped);
|
||||
|
||||
void gimpact_vs_concave(
|
||||
const btCollisionObjectWrapper * body0Wrap,
|
||||
const btCollisionObjectWrapper * body1Wrap,
|
||||
const btGImpactShapeInterface * shape0,
|
||||
const btConcaveShape * shape1,bool swapped);
|
||||
|
||||
|
||||
|
||||
|
||||
/// Accessor/Mutator pairs for Part and triangleID
|
||||
void setFace0(int value)
|
||||
{
|
||||
m_triface0 = value;
|
||||
}
|
||||
int getFace0()
|
||||
{
|
||||
return m_triface0;
|
||||
}
|
||||
void setFace1(int value)
|
||||
{
|
||||
m_triface1 = value;
|
||||
}
|
||||
int getFace1()
|
||||
{
|
||||
return m_triface1;
|
||||
}
|
||||
void setPart0(int value)
|
||||
{
|
||||
m_part0 = value;
|
||||
}
|
||||
int getPart0()
|
||||
{
|
||||
return m_part0;
|
||||
}
|
||||
void setPart1(int value)
|
||||
{
|
||||
m_part1 = value;
|
||||
}
|
||||
int getPart1()
|
||||
{
|
||||
return m_part1;
|
||||
}
|
||||
const btCollisionObjectWrapper* body0Wrap,
|
||||
const btCollisionObjectWrapper* body1Wrap,
|
||||
const btGImpactShapeInterface* shape0,
|
||||
const btConcaveShape* shape1, bool swapped);
|
||||
|
||||
/// Accessor/Mutator pairs for Part and triangleID
|
||||
void setFace0(int value)
|
||||
{
|
||||
m_triface0 = value;
|
||||
}
|
||||
int getFace0()
|
||||
{
|
||||
return m_triface0;
|
||||
}
|
||||
void setFace1(int value)
|
||||
{
|
||||
m_triface1 = value;
|
||||
}
|
||||
int getFace1()
|
||||
{
|
||||
return m_triface1;
|
||||
}
|
||||
void setPart0(int value)
|
||||
{
|
||||
m_part0 = value;
|
||||
}
|
||||
int getPart0()
|
||||
{
|
||||
return m_part0;
|
||||
}
|
||||
void setPart1(int value)
|
||||
{
|
||||
m_part1 = value;
|
||||
}
|
||||
int getPart1()
|
||||
{
|
||||
return m_part1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//algorithm details
|
||||
//#define BULLET_TRIANGLE_COLLISION 1
|
||||
#define GIMPACT_VS_PLANE_COLLISION 1
|
||||
|
||||
|
||||
|
||||
#endif //BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H
|
||||
#endif //BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H
|
||||
|
||||
@@ -21,40 +21,36 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GIMPACT_MASS_UTIL_H
|
||||
#define GIMPACT_MASS_UTIL_H
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 gim_inertia_add_transformed(
|
||||
const btVector3 & source_inertia, const btVector3 & added_inertia, const btTransform & transform)
|
||||
const btVector3& source_inertia, const btVector3& added_inertia, const btTransform& transform)
|
||||
{
|
||||
btMatrix3x3 rotatedTensor = transform.getBasis().scaled(added_inertia) * transform.getBasis().transpose();
|
||||
btMatrix3x3 rotatedTensor = transform.getBasis().scaled(added_inertia) * transform.getBasis().transpose();
|
||||
|
||||
btScalar x2 = transform.getOrigin()[0];
|
||||
x2*= x2;
|
||||
x2 *= x2;
|
||||
btScalar y2 = transform.getOrigin()[1];
|
||||
y2*= y2;
|
||||
y2 *= y2;
|
||||
btScalar z2 = transform.getOrigin()[2];
|
||||
z2*= z2;
|
||||
z2 *= z2;
|
||||
|
||||
btScalar ix = rotatedTensor[0][0]*(y2+z2);
|
||||
btScalar iy = rotatedTensor[1][1]*(x2+z2);
|
||||
btScalar iz = rotatedTensor[2][2]*(x2+y2);
|
||||
btScalar ix = rotatedTensor[0][0] * (y2 + z2);
|
||||
btScalar iy = rotatedTensor[1][1] * (x2 + z2);
|
||||
btScalar iz = rotatedTensor[2][2] * (x2 + y2);
|
||||
|
||||
return btVector3(source_inertia[0]+ix,source_inertia[1]+iy,source_inertia[2] + iz);
|
||||
return btVector3(source_inertia[0] + ix, source_inertia[1] + iy, source_inertia[2] + iz);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 gim_get_point_inertia(const btVector3 & point, btScalar mass)
|
||||
SIMD_FORCE_INLINE btVector3 gim_get_point_inertia(const btVector3& point, btScalar mass)
|
||||
{
|
||||
btScalar x2 = point[0]*point[0];
|
||||
btScalar y2 = point[1]*point[1];
|
||||
btScalar z2 = point[2]*point[2];
|
||||
return btVector3(mass*(y2+z2),mass*(x2+z2),mass*(x2+y2));
|
||||
btScalar x2 = point[0] * point[0];
|
||||
btScalar y2 = point[1] * point[1];
|
||||
btScalar z2 = point[2] * point[2];
|
||||
return btVector3(mass * (y2 + z2), mass * (x2 + z2), mass * (x2 + y2));
|
||||
}
|
||||
|
||||
|
||||
#endif //GIMPACT_MESH_SHAPE_H
|
||||
#endif //GIMPACT_MESH_SHAPE_H
|
||||
|
||||
@@ -27,11 +27,9 @@ subject to the following restrictions:
|
||||
#ifdef TRI_COLLISION_PROFILING
|
||||
btClock g_q_tree_clock;
|
||||
|
||||
|
||||
float g_q_accum_tree_collision_time = 0;
|
||||
int g_q_count_traversing = 0;
|
||||
|
||||
|
||||
void bt_begin_gim02_q_tree_time()
|
||||
{
|
||||
g_q_tree_clock.reset();
|
||||
@@ -43,11 +41,10 @@ void bt_end_gim02_q_tree_time()
|
||||
g_q_count_traversing++;
|
||||
}
|
||||
|
||||
|
||||
//! Gets the average time in miliseconds of tree collisions
|
||||
float btGImpactQuantizedBvh::getAverageTreeCollisionTime()
|
||||
{
|
||||
if(g_q_count_traversing == 0) return 0;
|
||||
if (g_q_count_traversing == 0) return 0;
|
||||
|
||||
float avgtime = g_q_accum_tree_collision_time;
|
||||
avgtime /= (float)g_q_count_traversing;
|
||||
@@ -56,99 +53,92 @@ float btGImpactQuantizedBvh::getAverageTreeCollisionTime()
|
||||
g_q_count_traversing = 0;
|
||||
return avgtime;
|
||||
|
||||
// float avgtime = g_q_count_traversing;
|
||||
// g_q_count_traversing = 0;
|
||||
// return avgtime;
|
||||
|
||||
// float avgtime = g_q_count_traversing;
|
||||
// g_q_count_traversing = 0;
|
||||
// return avgtime;
|
||||
}
|
||||
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
/////////////////////// btQuantizedBvhTree /////////////////////////////////
|
||||
|
||||
void btQuantizedBvhTree::calc_quantization(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin)
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes, btScalar boundMargin)
|
||||
{
|
||||
//calc globa box
|
||||
btAABB global_bound;
|
||||
global_bound.invalidate();
|
||||
|
||||
for (int i=0;i<primitive_boxes.size() ;i++ )
|
||||
for (int i = 0; i < primitive_boxes.size(); i++)
|
||||
{
|
||||
global_bound.merge(primitive_boxes[i].m_bound);
|
||||
}
|
||||
|
||||
bt_calc_quantization_parameters(
|
||||
m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization,global_bound.m_min,global_bound.m_max,boundMargin);
|
||||
|
||||
m_global_bound.m_min, m_global_bound.m_max, m_bvhQuantization, global_bound.m_min, global_bound.m_max, boundMargin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int btQuantizedBvhTree::_calc_splitting_axis(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
int numIndices = endIndex-startIndex;
|
||||
btVector3 means(btScalar(0.), btScalar(0.), btScalar(0.));
|
||||
btVector3 variance(btScalar(0.), btScalar(0.), btScalar(0.));
|
||||
int numIndices = endIndex - startIndex;
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means+=center;
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means += center;
|
||||
}
|
||||
means *= (btScalar(1.)/(btScalar)numIndices);
|
||||
means *= (btScalar(1.) / (btScalar)numIndices);
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
btVector3 diff2 = center-means;
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
btVector3 diff2 = center - means;
|
||||
diff2 = diff2 * diff2;
|
||||
variance += diff2;
|
||||
}
|
||||
variance *= (btScalar(1.)/ ((btScalar)numIndices-1) );
|
||||
variance *= (btScalar(1.) / ((btScalar)numIndices - 1));
|
||||
|
||||
return variance.maxAxis();
|
||||
}
|
||||
|
||||
|
||||
int btQuantizedBvhTree::_sort_and_calc_splitting_index(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex,
|
||||
int endIndex, int splitAxis)
|
||||
{
|
||||
int i;
|
||||
int splitIndex =startIndex;
|
||||
int splitIndex = startIndex;
|
||||
int numIndices = endIndex - startIndex;
|
||||
|
||||
// average of centers
|
||||
btScalar splitValue = 0.0f;
|
||||
|
||||
btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
btVector3 means(btScalar(0.), btScalar(0.), btScalar(0.));
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means+=center;
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means += center;
|
||||
}
|
||||
means *= (btScalar(1.)/(btScalar)numIndices);
|
||||
means *= (btScalar(1.) / (btScalar)numIndices);
|
||||
|
||||
splitValue = means[splitAxis];
|
||||
|
||||
|
||||
//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
if (center[splitAxis] > splitValue)
|
||||
{
|
||||
//swap
|
||||
primitive_boxes.swap(i,splitIndex);
|
||||
primitive_boxes.swap(i, splitIndex);
|
||||
//swapLeafNodes(i,splitIndex);
|
||||
splitIndex++;
|
||||
}
|
||||
@@ -163,32 +153,30 @@ int btQuantizedBvhTree::_sort_and_calc_splitting_index(
|
||||
//bool unbalanced2 = true;
|
||||
|
||||
//this should be safe too:
|
||||
int rangeBalancedIndices = numIndices/3;
|
||||
bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
|
||||
int rangeBalancedIndices = numIndices / 3;
|
||||
bool unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices)));
|
||||
|
||||
if (unbalanced)
|
||||
{
|
||||
splitIndex = startIndex+ (numIndices>>1);
|
||||
splitIndex = startIndex + (numIndices >> 1);
|
||||
}
|
||||
|
||||
btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
|
||||
btAssert(!((splitIndex == startIndex) || (splitIndex == (endIndex))));
|
||||
|
||||
return splitIndex;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
|
||||
void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex)
|
||||
{
|
||||
int curIndex = m_num_nodes;
|
||||
m_num_nodes++;
|
||||
|
||||
btAssert((endIndex-startIndex)>0);
|
||||
btAssert((endIndex - startIndex) > 0);
|
||||
|
||||
if ((endIndex-startIndex)==1)
|
||||
if ((endIndex - startIndex) == 1)
|
||||
{
|
||||
//We have a leaf node
|
||||
setNodeBound(curIndex,primitive_boxes[startIndex].m_bound);
|
||||
//We have a leaf node
|
||||
setNodeBound(curIndex, primitive_boxes[startIndex].m_bound);
|
||||
m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data);
|
||||
|
||||
return;
|
||||
@@ -196,48 +184,43 @@ void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, i
|
||||
//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
|
||||
|
||||
//split axis
|
||||
int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex);
|
||||
int splitIndex = _calc_splitting_axis(primitive_boxes, startIndex, endIndex);
|
||||
|
||||
splitIndex = _sort_and_calc_splitting_index(
|
||||
primitive_boxes,startIndex,endIndex,
|
||||
splitIndex//split axis
|
||||
);
|
||||
|
||||
primitive_boxes, startIndex, endIndex,
|
||||
splitIndex //split axis
|
||||
);
|
||||
|
||||
//calc this node bounding box
|
||||
|
||||
btAABB node_bound;
|
||||
node_bound.invalidate();
|
||||
|
||||
for (int i=startIndex;i<endIndex;i++)
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
node_bound.merge(primitive_boxes[i].m_bound);
|
||||
}
|
||||
|
||||
setNodeBound(curIndex,node_bound);
|
||||
|
||||
setNodeBound(curIndex, node_bound);
|
||||
|
||||
//build left branch
|
||||
_build_sub_tree(primitive_boxes, startIndex, splitIndex );
|
||||
|
||||
_build_sub_tree(primitive_boxes, startIndex, splitIndex);
|
||||
|
||||
//build right branch
|
||||
_build_sub_tree(primitive_boxes, splitIndex ,endIndex);
|
||||
_build_sub_tree(primitive_boxes, splitIndex, endIndex);
|
||||
|
||||
m_node_array[curIndex].setEscapeIndex(m_num_nodes - curIndex);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//! stackless build tree
|
||||
void btQuantizedBvhTree::build_tree(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes)
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes)
|
||||
{
|
||||
calc_quantization(primitive_boxes);
|
||||
// initialize node count to 0
|
||||
m_num_nodes = 0;
|
||||
// allocate nodes
|
||||
m_node_array.resize(primitive_boxes.size()*2);
|
||||
m_node_array.resize(primitive_boxes.size() * 2);
|
||||
|
||||
_build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
|
||||
}
|
||||
@@ -247,13 +230,13 @@ void btQuantizedBvhTree::build_tree(
|
||||
void btGImpactQuantizedBvh::refit()
|
||||
{
|
||||
int nodecount = getNodeCount();
|
||||
while(nodecount--)
|
||||
while (nodecount--)
|
||||
{
|
||||
if(isLeafNode(nodecount))
|
||||
if (isLeafNode(nodecount))
|
||||
{
|
||||
btAABB leafbox;
|
||||
m_primitive_manager->get_primitive_box(getNodeData(nodecount),leafbox);
|
||||
setNodeBound(nodecount,leafbox);
|
||||
m_primitive_manager->get_primitive_box(getNodeData(nodecount), leafbox);
|
||||
setNodeBound(nodecount, leafbox);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -265,20 +248,20 @@ void btGImpactQuantizedBvh::refit()
|
||||
btAABB temp_box;
|
||||
|
||||
int child_node = getLeftNode(nodecount);
|
||||
if(child_node)
|
||||
if (child_node)
|
||||
{
|
||||
getNodeBound(child_node,temp_box);
|
||||
getNodeBound(child_node, temp_box);
|
||||
bound.merge(temp_box);
|
||||
}
|
||||
|
||||
child_node = getRightNode(nodecount);
|
||||
if(child_node)
|
||||
if (child_node)
|
||||
{
|
||||
getNodeBound(child_node,temp_box);
|
||||
getNodeBound(child_node, temp_box);
|
||||
bound.merge(temp_box);
|
||||
}
|
||||
|
||||
setNodeBound(nodecount,bound);
|
||||
setNodeBound(nodecount, bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,17 +273,17 @@ void btGImpactQuantizedBvh::buildSet()
|
||||
GIM_BVH_DATA_ARRAY primitive_boxes;
|
||||
primitive_boxes.resize(m_primitive_manager->get_primitive_count());
|
||||
|
||||
for (int i = 0;i<primitive_boxes.size() ;i++ )
|
||||
for (int i = 0; i < primitive_boxes.size(); i++)
|
||||
{
|
||||
m_primitive_manager->get_primitive_box(i,primitive_boxes[i].m_bound);
|
||||
primitive_boxes[i].m_data = i;
|
||||
m_primitive_manager->get_primitive_box(i, primitive_boxes[i].m_bound);
|
||||
primitive_boxes[i].m_data = i;
|
||||
}
|
||||
|
||||
m_box_tree.build_tree(primitive_boxes);
|
||||
}
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
bool btGImpactQuantizedBvh::boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const
|
||||
bool btGImpactQuantizedBvh::boxQuery(const btAABB& box, btAlignedObjectArray<int>& collided_results) const
|
||||
{
|
||||
int curIndex = 0;
|
||||
int numNodes = getNodeCount();
|
||||
@@ -310,16 +293,14 @@ bool btGImpactQuantizedBvh::boxQuery(const btAABB & box, btAlignedObjectArray<in
|
||||
unsigned short quantizedMin[3];
|
||||
unsigned short quantizedMax[3];
|
||||
|
||||
m_box_tree.quantizePoint(quantizedMin,box.m_min);
|
||||
m_box_tree.quantizePoint(quantizedMax,box.m_max);
|
||||
|
||||
m_box_tree.quantizePoint(quantizedMin, box.m_min);
|
||||
m_box_tree.quantizePoint(quantizedMax, box.m_max);
|
||||
|
||||
while (curIndex < numNodes)
|
||||
{
|
||||
|
||||
//catch bugs in tree data
|
||||
|
||||
bool aabbOverlap = m_box_tree.testQuantizedBoxOverlapp(curIndex, quantizedMin,quantizedMax);
|
||||
bool aabbOverlap = m_box_tree.testQuantizedBoxOverlapp(curIndex, quantizedMin, quantizedMax);
|
||||
bool isleafnode = isLeafNode(curIndex);
|
||||
|
||||
if (isleafnode && aabbOverlap)
|
||||
@@ -335,19 +316,17 @@ bool btGImpactQuantizedBvh::boxQuery(const btAABB & box, btAlignedObjectArray<in
|
||||
else
|
||||
{
|
||||
//skip node
|
||||
curIndex+= getEscapeNodeIndex(curIndex);
|
||||
curIndex += getEscapeNodeIndex(curIndex);
|
||||
}
|
||||
}
|
||||
if(collided_results.size()>0) return true;
|
||||
if (collided_results.size() > 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
bool btGImpactQuantizedBvh::rayQuery(
|
||||
const btVector3 & ray_dir,const btVector3 & ray_origin ,
|
||||
btAlignedObjectArray<int> & collided_results) const
|
||||
const btVector3& ray_dir, const btVector3& ray_origin,
|
||||
btAlignedObjectArray<int>& collided_results) const
|
||||
{
|
||||
int curIndex = 0;
|
||||
int numNodes = getNodeCount();
|
||||
@@ -355,16 +334,16 @@ bool btGImpactQuantizedBvh::rayQuery(
|
||||
while (curIndex < numNodes)
|
||||
{
|
||||
btAABB bound;
|
||||
getNodeBound(curIndex,bound);
|
||||
getNodeBound(curIndex, bound);
|
||||
|
||||
//catch bugs in tree data
|
||||
|
||||
bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir);
|
||||
bool aabbOverlap = bound.collide_ray(ray_origin, ray_dir);
|
||||
bool isleafnode = isLeafNode(curIndex);
|
||||
|
||||
if (isleafnode && aabbOverlap)
|
||||
{
|
||||
collided_results.push_back(getNodeData( curIndex));
|
||||
collided_results.push_back(getNodeData(curIndex));
|
||||
}
|
||||
|
||||
if (aabbOverlap || isleafnode)
|
||||
@@ -375,154 +354,133 @@ bool btGImpactQuantizedBvh::rayQuery(
|
||||
else
|
||||
{
|
||||
//skip node
|
||||
curIndex+= getEscapeNodeIndex(curIndex);
|
||||
curIndex += getEscapeNodeIndex(curIndex);
|
||||
}
|
||||
}
|
||||
if(collided_results.size()>0) return true;
|
||||
if (collided_results.size() > 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool _quantized_node_collision(
|
||||
const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
|
||||
int node0 ,int node1, bool complete_primitive_tests)
|
||||
const btGImpactQuantizedBvh* boxset0, const btGImpactQuantizedBvh* boxset1,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE& trans_cache_1to0,
|
||||
int node0, int node1, bool complete_primitive_tests)
|
||||
{
|
||||
btAABB box0;
|
||||
boxset0->getNodeBound(node0,box0);
|
||||
boxset0->getNodeBound(node0, box0);
|
||||
btAABB box1;
|
||||
boxset1->getNodeBound(node1,box1);
|
||||
|
||||
return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests );
|
||||
// box1.appy_transform_trans_cache(trans_cache_1to0);
|
||||
// return box0.has_collision(box1);
|
||||
boxset1->getNodeBound(node1, box1);
|
||||
|
||||
return box0.overlapping_trans_cache(box1, trans_cache_1to0, complete_primitive_tests);
|
||||
// box1.appy_transform_trans_cache(trans_cache_1to0);
|
||||
// return box0.has_collision(box1);
|
||||
}
|
||||
|
||||
|
||||
//stackless recursive collision routine
|
||||
static void _find_quantized_collision_pairs_recursive(
|
||||
const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1,
|
||||
btPairSet * collision_pairs,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
|
||||
const btGImpactQuantizedBvh* boxset0, const btGImpactQuantizedBvh* boxset1,
|
||||
btPairSet* collision_pairs,
|
||||
const BT_BOX_BOX_TRANSFORM_CACHE& trans_cache_1to0,
|
||||
int node0, int node1, bool complete_primitive_tests)
|
||||
{
|
||||
if (_quantized_node_collision(
|
||||
boxset0, boxset1, trans_cache_1to0,
|
||||
node0, node1, complete_primitive_tests) == false) return; //avoid colliding internal nodes
|
||||
|
||||
|
||||
|
||||
if( _quantized_node_collision(
|
||||
boxset0,boxset1,trans_cache_1to0,
|
||||
node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes
|
||||
|
||||
if(boxset0->isLeafNode(node0))
|
||||
if (boxset0->isLeafNode(node0))
|
||||
{
|
||||
if(boxset1->isLeafNode(node1))
|
||||
if (boxset1->isLeafNode(node1))
|
||||
{
|
||||
// collision result
|
||||
collision_pairs->push_pair(
|
||||
boxset0->getNodeData(node0),boxset1->getNodeData(node1));
|
||||
boxset0->getNodeData(node0), boxset1->getNodeData(node1));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//collide left recursive
|
||||
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
node0,boxset1->getLeftNode(node1),false);
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
node0, boxset1->getLeftNode(node1), false);
|
||||
|
||||
//collide right recursive
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
node0,boxset1->getRightNode(node1),false);
|
||||
|
||||
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
node0, boxset1->getRightNode(node1), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(boxset1->isLeafNode(node1))
|
||||
if (boxset1->isLeafNode(node1))
|
||||
{
|
||||
|
||||
//collide left recursive
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0),node1,false);
|
||||
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0), node1, false);
|
||||
|
||||
//collide right recursive
|
||||
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getRightNode(node0),node1,false);
|
||||
|
||||
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getRightNode(node0), node1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//collide left0 left1
|
||||
|
||||
|
||||
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false);
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0), boxset1->getLeftNode(node1), false);
|
||||
|
||||
//collide left0 right1
|
||||
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false);
|
||||
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getLeftNode(node0), boxset1->getRightNode(node1), false);
|
||||
|
||||
//collide right0 left1
|
||||
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false);
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getRightNode(node0), boxset1->getLeftNode(node1), false);
|
||||
|
||||
//collide right0 right1
|
||||
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
collision_pairs,trans_cache_1to0,
|
||||
boxset0->getRightNode(node0),boxset1->getRightNode(node1),false);
|
||||
boxset0, boxset1,
|
||||
collision_pairs, trans_cache_1to0,
|
||||
boxset0->getRightNode(node0), boxset1->getRightNode(node1), false);
|
||||
|
||||
}// else if node1 is not a leaf
|
||||
}// else if node0 is not a leaf
|
||||
} // else if node1 is not a leaf
|
||||
} // else if node0 is not a leaf
|
||||
}
|
||||
|
||||
|
||||
void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh * boxset0, const btTransform & trans0,
|
||||
const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
|
||||
btPairSet & collision_pairs)
|
||||
void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh* boxset0, const btTransform& trans0,
|
||||
const btGImpactQuantizedBvh* boxset1, const btTransform& trans1,
|
||||
btPairSet& collision_pairs)
|
||||
{
|
||||
|
||||
if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return;
|
||||
if (boxset0->getNodeCount() == 0 || boxset1->getNodeCount() == 0) return;
|
||||
|
||||
BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0;
|
||||
|
||||
trans_cache_1to0.calc_from_homogenic(trans0,trans1);
|
||||
trans_cache_1to0.calc_from_homogenic(trans0, trans1);
|
||||
|
||||
#ifdef TRI_COLLISION_PROFILING
|
||||
bt_begin_gim02_q_tree_time();
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
_find_quantized_collision_pairs_recursive(
|
||||
boxset0,boxset1,
|
||||
&collision_pairs,trans_cache_1to0,0,0,true);
|
||||
boxset0, boxset1,
|
||||
&collision_pairs, trans_cache_1to0, 0, 0, true);
|
||||
#ifdef TRI_COLLISION_PROFILING
|
||||
bt_end_gim02_q_tree_time();
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,13 +28,10 @@ subject to the following restrictions:
|
||||
#include "btQuantization.h"
|
||||
#include "btGImpactQuantizedBvhStructs.h"
|
||||
|
||||
class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
|
||||
class GIM_QUANTIZED_BVH_NODE_ARRAY : public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//! Basic Box tree structure
|
||||
class btQuantizedBvhTree
|
||||
{
|
||||
@@ -43,16 +40,18 @@ protected:
|
||||
GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array;
|
||||
btAABB m_global_bound;
|
||||
btVector3 m_bvhQuantization;
|
||||
|
||||
protected:
|
||||
void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
|
||||
void calc_quantization(GIM_BVH_DATA_ARRAY& primitive_boxes, btScalar boundMargin = btScalar(1.0));
|
||||
|
||||
int _sort_and_calc_splitting_index(
|
||||
GIM_BVH_DATA_ARRAY & primitive_boxes,
|
||||
int startIndex, int endIndex, int splitAxis);
|
||||
GIM_BVH_DATA_ARRAY& primitive_boxes,
|
||||
int startIndex, int endIndex, int splitAxis);
|
||||
|
||||
int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
|
||||
int _calc_splitting_axis(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex);
|
||||
|
||||
void _build_sub_tree(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex);
|
||||
|
||||
void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
|
||||
public:
|
||||
btQuantizedBvhTree()
|
||||
{
|
||||
@@ -61,20 +60,19 @@ public:
|
||||
|
||||
//! prototype functions for box tree management
|
||||
//!@{
|
||||
void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
|
||||
void build_tree(GIM_BVH_DATA_ARRAY& primitive_boxes);
|
||||
|
||||
SIMD_FORCE_INLINE void quantizePoint(
|
||||
unsigned short * quantizedpoint, const btVector3 & point) const
|
||||
unsigned short* quantizedpoint, const btVector3& point) const
|
||||
{
|
||||
bt_quantize_clamp(quantizedpoint,point,m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization);
|
||||
bt_quantize_clamp(quantizedpoint, point, m_global_bound.m_min, m_global_bound.m_max, m_bvhQuantization);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
|
||||
int node_index,
|
||||
unsigned short * quantizedMin,unsigned short * quantizedMax) const
|
||||
unsigned short* quantizedMin, unsigned short* quantizedMax) const
|
||||
{
|
||||
return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin,quantizedMax);
|
||||
return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin, quantizedMax);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void clearNodes()
|
||||
@@ -100,41 +98,41 @@ public:
|
||||
return m_node_array[nodeindex].getDataIndex();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
|
||||
SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB& bound) const
|
||||
{
|
||||
bound.m_min = bt_unquantize(
|
||||
m_node_array[nodeindex].m_quantizedAabbMin,
|
||||
m_global_bound.m_min,m_bvhQuantization);
|
||||
m_global_bound.m_min, m_bvhQuantization);
|
||||
|
||||
bound.m_max = bt_unquantize(
|
||||
m_node_array[nodeindex].m_quantizedAabbMax,
|
||||
m_global_bound.m_min,m_bvhQuantization);
|
||||
m_global_bound.m_min, m_bvhQuantization);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
|
||||
SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB& bound)
|
||||
{
|
||||
bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMin,
|
||||
bound.m_min,
|
||||
m_global_bound.m_min,
|
||||
m_global_bound.m_max,
|
||||
m_bvhQuantization);
|
||||
bt_quantize_clamp(m_node_array[nodeindex].m_quantizedAabbMin,
|
||||
bound.m_min,
|
||||
m_global_bound.m_min,
|
||||
m_global_bound.m_max,
|
||||
m_bvhQuantization);
|
||||
|
||||
bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMax,
|
||||
bound.m_max,
|
||||
m_global_bound.m_min,
|
||||
m_global_bound.m_max,
|
||||
m_bvhQuantization);
|
||||
bt_quantize_clamp(m_node_array[nodeindex].m_quantizedAabbMax,
|
||||
bound.m_max,
|
||||
m_global_bound.m_min,
|
||||
m_global_bound.m_max,
|
||||
m_bvhQuantization);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
|
||||
{
|
||||
return nodeindex+1;
|
||||
return nodeindex + 1;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
|
||||
{
|
||||
if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2;
|
||||
return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex();
|
||||
if (m_node_array[nodeindex + 1].isLeafNode()) return nodeindex + 2;
|
||||
return nodeindex + 1 + m_node_array[nodeindex + 1].getEscapeIndex();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
|
||||
@@ -142,7 +140,7 @@ public:
|
||||
return m_node_array[nodeindex].getEscapeIndex();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
|
||||
SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE* get_node_pointer(int index = 0) const
|
||||
{
|
||||
return &m_node_array[index];
|
||||
}
|
||||
@@ -150,8 +148,6 @@ public:
|
||||
//!@}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//! Structure for containing Boxes
|
||||
/*!
|
||||
This class offers an structure for managing a box tree of primitives.
|
||||
@@ -161,13 +157,13 @@ class btGImpactQuantizedBvh
|
||||
{
|
||||
protected:
|
||||
btQuantizedBvhTree m_box_tree;
|
||||
btPrimitiveManagerBase * m_primitive_manager;
|
||||
btPrimitiveManagerBase* m_primitive_manager;
|
||||
|
||||
protected:
|
||||
//stackless refit
|
||||
void refit();
|
||||
public:
|
||||
|
||||
public:
|
||||
//! this constructor doesn't build the tree. you must call buildSet
|
||||
btGImpactQuantizedBvh()
|
||||
{
|
||||
@@ -175,31 +171,30 @@ public:
|
||||
}
|
||||
|
||||
//! this constructor doesn't build the tree. you must call buildSet
|
||||
btGImpactQuantizedBvh(btPrimitiveManagerBase * primitive_manager)
|
||||
btGImpactQuantizedBvh(btPrimitiveManagerBase* primitive_manager)
|
||||
{
|
||||
m_primitive_manager = primitive_manager;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btAABB getGlobalBox() const
|
||||
SIMD_FORCE_INLINE btAABB getGlobalBox() const
|
||||
{
|
||||
btAABB totalbox;
|
||||
getNodeBound(0, totalbox);
|
||||
return totalbox;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager)
|
||||
SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase* primitive_manager)
|
||||
{
|
||||
m_primitive_manager = primitive_manager;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
|
||||
SIMD_FORCE_INLINE btPrimitiveManagerBase* getPrimitiveManager() const
|
||||
{
|
||||
return m_primitive_manager;
|
||||
}
|
||||
|
||||
|
||||
//! node manager prototype functions
|
||||
///@{
|
||||
//! node manager prototype functions
|
||||
///@{
|
||||
|
||||
//! this attemps to refit the box set.
|
||||
SIMD_FORCE_INLINE void update()
|
||||
@@ -211,21 +206,21 @@ public:
|
||||
void buildSet();
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
|
||||
bool boxQuery(const btAABB& box, btAlignedObjectArray<int>& collided_results) const;
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box,
|
||||
const btTransform & transform, btAlignedObjectArray<int> & collided_results) const
|
||||
SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB& box,
|
||||
const btTransform& transform, btAlignedObjectArray<int>& collided_results) const
|
||||
{
|
||||
btAABB transbox=box;
|
||||
btAABB transbox = box;
|
||||
transbox.appy_transform(transform);
|
||||
return boxQuery(transbox,collided_results);
|
||||
return boxQuery(transbox, collided_results);
|
||||
}
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
bool rayQuery(
|
||||
const btVector3 & ray_dir,const btVector3 & ray_origin ,
|
||||
btAlignedObjectArray<int> & collided_results) const;
|
||||
const btVector3& ray_dir, const btVector3& ray_origin,
|
||||
btAlignedObjectArray<int>& collided_results) const;
|
||||
|
||||
//! tells if this set has hierarcht
|
||||
SIMD_FORCE_INLINE bool hasHierarchy() const
|
||||
@@ -234,7 +229,7 @@ public:
|
||||
}
|
||||
|
||||
//! tells if this set is a trimesh
|
||||
SIMD_FORCE_INLINE bool isTrimesh() const
|
||||
SIMD_FORCE_INLINE bool isTrimesh() const
|
||||
{
|
||||
return m_primitive_manager->is_trimesh();
|
||||
}
|
||||
@@ -256,17 +251,16 @@ public:
|
||||
return m_box_tree.getNodeData(nodeindex);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
|
||||
SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB& bound) const
|
||||
{
|
||||
m_box_tree.getNodeBound(nodeindex, bound);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
|
||||
SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB& bound)
|
||||
{
|
||||
m_box_tree.setNodeBound(nodeindex, bound);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
|
||||
{
|
||||
return m_box_tree.getLeftNode(nodeindex);
|
||||
@@ -282,24 +276,23 @@ public:
|
||||
return m_box_tree.getEscapeNodeIndex(nodeindex);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const
|
||||
SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex, btPrimitiveTriangle& triangle) const
|
||||
{
|
||||
m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle);
|
||||
m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex), triangle);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
|
||||
SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE* get_node_pointer(int index = 0) const
|
||||
{
|
||||
return m_box_tree.get_node_pointer(index);
|
||||
}
|
||||
|
||||
#ifdef TRI_COLLISION_PROFILING
|
||||
static float getAverageTreeCollisionTime();
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
#endif //TRI_COLLISION_PROFILING
|
||||
|
||||
static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
|
||||
const btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
|
||||
btPairSet & collision_pairs);
|
||||
static void find_collision(const btGImpactQuantizedBvh* boxset1, const btTransform& trans1,
|
||||
const btGImpactQuantizedBvh* boxset2, const btTransform& trans2,
|
||||
btPairSet& collision_pairs);
|
||||
};
|
||||
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
|
||||
@@ -29,13 +29,14 @@ subject to the following restrictions:
|
||||
|
||||
///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
|
||||
///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
|
||||
ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE
|
||||
ATTRIBUTE_ALIGNED16(struct)
|
||||
BT_QUANTIZED_BVH_NODE
|
||||
{
|
||||
//12 bytes
|
||||
unsigned short int m_quantizedAabbMin[3];
|
||||
unsigned short int m_quantizedAabbMax[3];
|
||||
unsigned short int m_quantizedAabbMin[3];
|
||||
unsigned short int m_quantizedAabbMax[3];
|
||||
//4 bytes
|
||||
int m_escapeIndexOrDataIndex;
|
||||
int m_escapeIndexOrDataIndex;
|
||||
|
||||
BT_QUANTIZED_BVH_NODE()
|
||||
{
|
||||
@@ -45,7 +46,7 @@ ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE
|
||||
SIMD_FORCE_INLINE bool isLeafNode() const
|
||||
{
|
||||
//skipindex is negative (internal node), triangleindex >=0 (leafnode)
|
||||
return (m_escapeIndexOrDataIndex>=0);
|
||||
return (m_escapeIndexOrDataIndex >= 0);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getEscapeIndex() const
|
||||
@@ -72,20 +73,19 @@ ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
|
||||
unsigned short * quantizedMin,unsigned short * quantizedMax) const
|
||||
unsigned short* quantizedMin, unsigned short* quantizedMax) const
|
||||
{
|
||||
if(m_quantizedAabbMin[0] > quantizedMax[0] ||
|
||||
m_quantizedAabbMax[0] < quantizedMin[0] ||
|
||||
m_quantizedAabbMin[1] > quantizedMax[1] ||
|
||||
m_quantizedAabbMax[1] < quantizedMin[1] ||
|
||||
m_quantizedAabbMin[2] > quantizedMax[2] ||
|
||||
m_quantizedAabbMax[2] < quantizedMin[2])
|
||||
if (m_quantizedAabbMin[0] > quantizedMax[0] ||
|
||||
m_quantizedAabbMax[0] < quantizedMin[0] ||
|
||||
m_quantizedAabbMin[1] > quantizedMax[1] ||
|
||||
m_quantizedAabbMax[1] < quantizedMin[1] ||
|
||||
m_quantizedAabbMin[2] > quantizedMax[2] ||
|
||||
m_quantizedAabbMax[2] < quantizedMin[2])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // GIM_QUANTIZED_SET_STRUCTS_H_INCLUDED
|
||||
#endif // GIM_QUANTIZED_SET_STRUCTS_H_INCLUDED
|
||||
|
||||
@@ -18,178 +18,169 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "btGImpactShape.h"
|
||||
#include "btGImpactMassUtil.h"
|
||||
|
||||
|
||||
btGImpactMeshShapePart::btGImpactMeshShapePart( btStridingMeshInterface * meshInterface, int part )
|
||||
btGImpactMeshShapePart::btGImpactMeshShapePart(btStridingMeshInterface* meshInterface, int part)
|
||||
{
|
||||
// moved from .h to .cpp because of conditional compilation
|
||||
// (The setting of BT_THREADSAFE may differ between various cpp files, so it is best to
|
||||
// avoid using it in h files)
|
||||
m_primitive_manager.m_meshInterface = meshInterface;
|
||||
m_primitive_manager.m_part = part;
|
||||
m_box_set.setPrimitiveManager( &m_primitive_manager );
|
||||
// moved from .h to .cpp because of conditional compilation
|
||||
// (The setting of BT_THREADSAFE may differ between various cpp files, so it is best to
|
||||
// avoid using it in h files)
|
||||
m_primitive_manager.m_meshInterface = meshInterface;
|
||||
m_primitive_manager.m_part = part;
|
||||
m_box_set.setPrimitiveManager(&m_primitive_manager);
|
||||
#if BT_THREADSAFE
|
||||
// If threadsafe is requested, this object uses a different lock/unlock
|
||||
// model with the btStridingMeshInterface -- lock once when the object is constructed
|
||||
// and unlock once in the destructor.
|
||||
// The other way of locking and unlocking for each collision check in the narrowphase
|
||||
// is not threadsafe. Note these are not thread-locks, they are calls to the meshInterface's
|
||||
// getLockedReadOnlyVertexIndexBase virtual function, which by default just returns a couple of
|
||||
// pointers. In theory a client could override the lock function to do all sorts of
|
||||
// things like reading data from GPU memory, or decompressing data on the fly, but such things
|
||||
// do not seem all that likely or useful, given the performance cost.
|
||||
m_primitive_manager.lock();
|
||||
// If threadsafe is requested, this object uses a different lock/unlock
|
||||
// model with the btStridingMeshInterface -- lock once when the object is constructed
|
||||
// and unlock once in the destructor.
|
||||
// The other way of locking and unlocking for each collision check in the narrowphase
|
||||
// is not threadsafe. Note these are not thread-locks, they are calls to the meshInterface's
|
||||
// getLockedReadOnlyVertexIndexBase virtual function, which by default just returns a couple of
|
||||
// pointers. In theory a client could override the lock function to do all sorts of
|
||||
// things like reading data from GPU memory, or decompressing data on the fly, but such things
|
||||
// do not seem all that likely or useful, given the performance cost.
|
||||
m_primitive_manager.lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
btGImpactMeshShapePart::~btGImpactMeshShapePart()
|
||||
{
|
||||
// moved from .h to .cpp because of conditional compilation
|
||||
// moved from .h to .cpp because of conditional compilation
|
||||
#if BT_THREADSAFE
|
||||
m_primitive_manager.unlock();
|
||||
m_primitive_manager.unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void btGImpactMeshShapePart::lockChildShapes() const
|
||||
{
|
||||
// moved from .h to .cpp because of conditional compilation
|
||||
#if ! BT_THREADSAFE
|
||||
// called in the narrowphase -- not threadsafe!
|
||||
void * dummy = (void*) ( m_box_set.getPrimitiveManager() );
|
||||
TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>( dummy );
|
||||
dummymanager->lock();
|
||||
// moved from .h to .cpp because of conditional compilation
|
||||
#if !BT_THREADSAFE
|
||||
// called in the narrowphase -- not threadsafe!
|
||||
void* dummy = (void*)(m_box_set.getPrimitiveManager());
|
||||
TrimeshPrimitiveManager* dummymanager = static_cast<TrimeshPrimitiveManager*>(dummy);
|
||||
dummymanager->lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void btGImpactMeshShapePart::unlockChildShapes() const
|
||||
void btGImpactMeshShapePart::unlockChildShapes() const
|
||||
{
|
||||
// moved from .h to .cpp because of conditional compilation
|
||||
#if ! BT_THREADSAFE
|
||||
// called in the narrowphase -- not threadsafe!
|
||||
void * dummy = (void*) ( m_box_set.getPrimitiveManager() );
|
||||
TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>( dummy );
|
||||
dummymanager->unlock();
|
||||
// moved from .h to .cpp because of conditional compilation
|
||||
#if !BT_THREADSAFE
|
||||
// called in the narrowphase -- not threadsafe!
|
||||
void* dummy = (void*)(m_box_set.getPrimitiveManager());
|
||||
TrimeshPrimitiveManager* dummymanager = static_cast<TrimeshPrimitiveManager*>(dummy);
|
||||
dummymanager->unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define CALC_EXACT_INERTIA 1
|
||||
|
||||
|
||||
void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
|
||||
void btGImpactCompoundShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const
|
||||
{
|
||||
lockChildShapes();
|
||||
#ifdef CALC_EXACT_INERTIA
|
||||
inertia.setValue(0.f,0.f,0.f);
|
||||
inertia.setValue(0.f, 0.f, 0.f);
|
||||
|
||||
int i = this->getNumChildShapes();
|
||||
btScalar shapemass = mass/btScalar(i);
|
||||
btScalar shapemass = mass / btScalar(i);
|
||||
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
btVector3 temp_inertia;
|
||||
m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia);
|
||||
if(childrenHasTransform())
|
||||
m_childShapes[i]->calculateLocalInertia(shapemass, temp_inertia);
|
||||
if (childrenHasTransform())
|
||||
{
|
||||
inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]);
|
||||
inertia = gim_inertia_add_transformed(inertia, temp_inertia, m_childTransforms[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
inertia = gim_inertia_add_transformed( inertia,temp_inertia,btTransform::getIdentity());
|
||||
inertia = gim_inertia_add_transformed(inertia, temp_inertia, btTransform::getIdentity());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Calc box inertia
|
||||
|
||||
btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
|
||||
btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
|
||||
btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
|
||||
const btScalar x2 = lx*lx;
|
||||
const btScalar y2 = ly*ly;
|
||||
const btScalar z2 = lz*lz;
|
||||
btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0];
|
||||
btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1];
|
||||
btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2];
|
||||
const btScalar x2 = lx * lx;
|
||||
const btScalar y2 = ly * ly;
|
||||
const btScalar z2 = lz * lz;
|
||||
const btScalar scaledmass = mass * btScalar(0.08333333);
|
||||
|
||||
inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
|
||||
inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
|
||||
|
||||
#endif
|
||||
unlockChildShapes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass,btVector3& inertia) const
|
||||
void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass, btVector3& inertia) const
|
||||
{
|
||||
lockChildShapes();
|
||||
|
||||
|
||||
#ifdef CALC_EXACT_INERTIA
|
||||
inertia.setValue(0.f,0.f,0.f);
|
||||
inertia.setValue(0.f, 0.f, 0.f);
|
||||
|
||||
int i = this->getVertexCount();
|
||||
btScalar pointmass = mass/btScalar(i);
|
||||
btScalar pointmass = mass / btScalar(i);
|
||||
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
btVector3 pointintertia;
|
||||
this->getVertex(i,pointintertia);
|
||||
pointintertia = gim_get_point_inertia(pointintertia,pointmass);
|
||||
inertia+=pointintertia;
|
||||
this->getVertex(i, pointintertia);
|
||||
pointintertia = gim_get_point_inertia(pointintertia, pointmass);
|
||||
inertia += pointintertia;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Calc box inertia
|
||||
|
||||
btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
|
||||
btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
|
||||
btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
|
||||
const btScalar x2 = lx*lx;
|
||||
const btScalar y2 = ly*ly;
|
||||
const btScalar z2 = lz*lz;
|
||||
btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0];
|
||||
btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1];
|
||||
btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2];
|
||||
const btScalar x2 = lx * lx;
|
||||
const btScalar y2 = ly * ly;
|
||||
const btScalar z2 = lz * lz;
|
||||
const btScalar scaledmass = mass * btScalar(0.08333333);
|
||||
|
||||
inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
|
||||
inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
|
||||
|
||||
#endif
|
||||
|
||||
unlockChildShapes();
|
||||
}
|
||||
|
||||
void btGImpactMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
|
||||
void btGImpactMeshShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const
|
||||
{
|
||||
|
||||
#ifdef CALC_EXACT_INERTIA
|
||||
inertia.setValue(0.f,0.f,0.f);
|
||||
inertia.setValue(0.f, 0.f, 0.f);
|
||||
|
||||
int i = this->getMeshPartCount();
|
||||
btScalar partmass = mass/btScalar(i);
|
||||
btScalar partmass = mass / btScalar(i);
|
||||
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
btVector3 partinertia;
|
||||
getMeshPart(i)->calculateLocalInertia(partmass,partinertia);
|
||||
inertia+=partinertia;
|
||||
getMeshPart(i)->calculateLocalInertia(partmass, partinertia);
|
||||
inertia += partinertia;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Calc box inertia
|
||||
|
||||
btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
|
||||
btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
|
||||
btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
|
||||
const btScalar x2 = lx*lx;
|
||||
const btScalar y2 = ly*ly;
|
||||
const btScalar z2 = lz*lz;
|
||||
btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0];
|
||||
btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1];
|
||||
btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2];
|
||||
const btScalar x2 = lx * lx;
|
||||
const btScalar y2 = ly * ly;
|
||||
const btScalar z2 = lz * lz;
|
||||
const btScalar scaledmass = mass * btScalar(0.08333333);
|
||||
|
||||
inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
|
||||
inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -198,7 +189,7 @@ void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayT
|
||||
{
|
||||
}
|
||||
|
||||
void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
|
||||
void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const
|
||||
{
|
||||
lockChildShapes();
|
||||
|
||||
@@ -207,7 +198,7 @@ void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback
|
||||
rayDir.normalize();
|
||||
m_box_set.rayQuery(rayDir, rayFrom, collided);
|
||||
|
||||
if(collided.size()==0)
|
||||
if (collided.size() == 0)
|
||||
{
|
||||
unlockChildShapes();
|
||||
return;
|
||||
@@ -216,15 +207,15 @@ void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback
|
||||
int part = (int)getPart();
|
||||
btPrimitiveTriangle triangle;
|
||||
int i = collided.size();
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
getPrimitiveTriangle(collided[i],triangle);
|
||||
callback->processTriangle(triangle.m_vertices,part,collided[i]);
|
||||
getPrimitiveTriangle(collided[i], triangle);
|
||||
callback->processTriangle(triangle.m_vertices, part, collided[i]);
|
||||
}
|
||||
unlockChildShapes();
|
||||
}
|
||||
|
||||
void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
|
||||
{
|
||||
lockChildShapes();
|
||||
btAABB box;
|
||||
@@ -232,9 +223,9 @@ void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,co
|
||||
box.m_max = aabbMax;
|
||||
|
||||
btAlignedObjectArray<int> collided;
|
||||
m_box_set.boxQuery(box,collided);
|
||||
m_box_set.boxQuery(box, collided);
|
||||
|
||||
if(collided.size()==0)
|
||||
if (collided.size() == 0)
|
||||
{
|
||||
unlockChildShapes();
|
||||
return;
|
||||
@@ -243,40 +234,38 @@ void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,co
|
||||
int part = (int)getPart();
|
||||
btPrimitiveTriangle triangle;
|
||||
int i = collided.size();
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
this->getPrimitiveTriangle(collided[i],triangle);
|
||||
callback->processTriangle(triangle.m_vertices,part,collided[i]);
|
||||
this->getPrimitiveTriangle(collided[i], triangle);
|
||||
callback->processTriangle(triangle.m_vertices, part, collided[i]);
|
||||
}
|
||||
unlockChildShapes();
|
||||
|
||||
}
|
||||
|
||||
void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
|
||||
{
|
||||
int i = m_mesh_parts.size();
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax);
|
||||
m_mesh_parts[i]->processAllTriangles(callback, aabbMin, aabbMax);
|
||||
}
|
||||
}
|
||||
|
||||
void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
|
||||
void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const
|
||||
{
|
||||
int i = m_mesh_parts.size();
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*) dataBuffer;
|
||||
btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*)dataBuffer;
|
||||
|
||||
btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer);
|
||||
btCollisionShape::serialize(&trimeshData->m_collisionShapeData, serializer);
|
||||
|
||||
m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
|
||||
|
||||
@@ -288,4 +277,3 @@ const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serial
|
||||
|
||||
return "btGImpactMeshShapeData";
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,48 +20,45 @@ subject to the following restrictions:
|
||||
|
||||
#include "btGenericPoolAllocator.h"
|
||||
|
||||
|
||||
|
||||
/// *************** btGenericMemoryPool ******************///////////
|
||||
|
||||
size_t btGenericMemoryPool::allocate_from_free_nodes(size_t num_elements)
|
||||
{
|
||||
size_t ptr = BT_UINT_MAX;
|
||||
|
||||
if(m_free_nodes_count == 0) return BT_UINT_MAX;
|
||||
if (m_free_nodes_count == 0) return BT_UINT_MAX;
|
||||
// find an avaliable free node with the correct size
|
||||
size_t revindex = m_free_nodes_count;
|
||||
|
||||
while(revindex-- && ptr == BT_UINT_MAX)
|
||||
while (revindex-- && ptr == BT_UINT_MAX)
|
||||
{
|
||||
if(m_allocated_sizes[m_free_nodes[revindex]]>=num_elements)
|
||||
if (m_allocated_sizes[m_free_nodes[revindex]] >= num_elements)
|
||||
{
|
||||
ptr = revindex;
|
||||
}
|
||||
}
|
||||
if(ptr == BT_UINT_MAX) return BT_UINT_MAX; // not found
|
||||
|
||||
if (ptr == BT_UINT_MAX) return BT_UINT_MAX; // not found
|
||||
|
||||
revindex = ptr;
|
||||
ptr = m_free_nodes[revindex];
|
||||
// post: ptr contains the node index, and revindex the index in m_free_nodes
|
||||
|
||||
size_t finalsize = m_allocated_sizes[ptr];
|
||||
size_t finalsize = m_allocated_sizes[ptr];
|
||||
finalsize -= num_elements;
|
||||
|
||||
m_allocated_sizes[ptr] = num_elements;
|
||||
|
||||
// post: finalsize>=0, m_allocated_sizes[ptr] has the requested size
|
||||
|
||||
if(finalsize>0) // preserve free node, there are some free memory
|
||||
if (finalsize > 0) // preserve free node, there are some free memory
|
||||
{
|
||||
m_free_nodes[revindex] = ptr + num_elements;
|
||||
m_allocated_sizes[ptr + num_elements] = finalsize;
|
||||
}
|
||||
else // delete free node
|
||||
else // delete free node
|
||||
{
|
||||
// swap with end
|
||||
m_free_nodes[revindex] = m_free_nodes[m_free_nodes_count-1];
|
||||
m_free_nodes[revindex] = m_free_nodes[m_free_nodes_count - 1];
|
||||
m_free_nodes_count--;
|
||||
}
|
||||
|
||||
@@ -70,17 +67,16 @@ size_t btGenericMemoryPool::allocate_from_free_nodes(size_t num_elements)
|
||||
|
||||
size_t btGenericMemoryPool::allocate_from_pool(size_t num_elements)
|
||||
{
|
||||
if(m_allocated_count+num_elements>m_max_element_count) return BT_UINT_MAX;
|
||||
if (m_allocated_count + num_elements > m_max_element_count) return BT_UINT_MAX;
|
||||
|
||||
size_t ptr = m_allocated_count;
|
||||
|
||||
m_allocated_sizes[m_allocated_count] = num_elements;
|
||||
m_allocated_count+=num_elements;
|
||||
m_allocated_count += num_elements;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void btGenericMemoryPool::init_pool(size_t element_size, size_t element_count)
|
||||
{
|
||||
m_allocated_count = 0;
|
||||
@@ -89,14 +85,11 @@ void btGenericMemoryPool::init_pool(size_t element_size, size_t element_count)
|
||||
m_element_size = element_size;
|
||||
m_max_element_count = element_count;
|
||||
|
||||
m_pool = (unsigned char *)btAlignedAlloc(m_element_size * m_max_element_count, 16);
|
||||
m_free_nodes = (size_t *)btAlignedAlloc(sizeof(size_t) * m_max_element_count, 16);
|
||||
m_allocated_sizes = (size_t *)btAlignedAlloc(sizeof(size_t) * m_max_element_count, 16);
|
||||
|
||||
|
||||
|
||||
m_pool = (unsigned char *) btAlignedAlloc(m_element_size*m_max_element_count,16);
|
||||
m_free_nodes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16);
|
||||
m_allocated_sizes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16);
|
||||
|
||||
for (size_t i = 0;i< m_max_element_count;i++ )
|
||||
for (size_t i = 0; i < m_max_element_count; i++)
|
||||
{
|
||||
m_allocated_sizes[i] = 0;
|
||||
}
|
||||
@@ -111,150 +104,141 @@ void btGenericMemoryPool::end_pool()
|
||||
m_free_nodes_count = 0;
|
||||
}
|
||||
|
||||
|
||||
//! Allocates memory in pool
|
||||
/*!
|
||||
\param size_bytes size in bytes of the buffer
|
||||
*/
|
||||
void * btGenericMemoryPool::allocate(size_t size_bytes)
|
||||
void *btGenericMemoryPool::allocate(size_t size_bytes)
|
||||
{
|
||||
|
||||
size_t module = size_bytes%m_element_size;
|
||||
size_t element_count = size_bytes/m_element_size;
|
||||
if(module>0) element_count++;
|
||||
size_t module = size_bytes % m_element_size;
|
||||
size_t element_count = size_bytes / m_element_size;
|
||||
if (module > 0) element_count++;
|
||||
|
||||
size_t alloc_pos = allocate_from_free_nodes(element_count);
|
||||
// a free node is found
|
||||
if(alloc_pos != BT_UINT_MAX)
|
||||
if (alloc_pos != BT_UINT_MAX)
|
||||
{
|
||||
return get_element_data(alloc_pos);
|
||||
}
|
||||
// allocate directly on pool
|
||||
alloc_pos = allocate_from_pool(element_count);
|
||||
|
||||
if(alloc_pos == BT_UINT_MAX) return NULL; // not space
|
||||
if (alloc_pos == BT_UINT_MAX) return NULL; // not space
|
||||
return get_element_data(alloc_pos);
|
||||
}
|
||||
|
||||
bool btGenericMemoryPool::freeMemory(void * pointer)
|
||||
bool btGenericMemoryPool::freeMemory(void *pointer)
|
||||
{
|
||||
unsigned char * pointer_pos = (unsigned char *)pointer;
|
||||
unsigned char * pool_pos = (unsigned char *)m_pool;
|
||||
unsigned char *pointer_pos = (unsigned char *)pointer;
|
||||
unsigned char *pool_pos = (unsigned char *)m_pool;
|
||||
// calc offset
|
||||
if(pointer_pos<pool_pos) return false;//other pool
|
||||
if (pointer_pos < pool_pos) return false; //other pool
|
||||
size_t offset = size_t(pointer_pos - pool_pos);
|
||||
if(offset>=get_pool_capacity()) return false;// far away
|
||||
if (offset >= get_pool_capacity()) return false; // far away
|
||||
|
||||
// find free position
|
||||
m_free_nodes[m_free_nodes_count] = offset/m_element_size;
|
||||
m_free_nodes[m_free_nodes_count] = offset / m_element_size;
|
||||
m_free_nodes_count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// *******************! btGenericPoolAllocator *******************!///
|
||||
|
||||
|
||||
btGenericPoolAllocator::~btGenericPoolAllocator()
|
||||
{
|
||||
// destroy pools
|
||||
size_t i;
|
||||
for (i=0;i<m_pool_count;i++)
|
||||
for (i = 0; i < m_pool_count; i++)
|
||||
{
|
||||
m_pools[i]->end_pool();
|
||||
btAlignedFree(m_pools[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// creates a pool
|
||||
btGenericMemoryPool * btGenericPoolAllocator::push_new_pool()
|
||||
btGenericMemoryPool *btGenericPoolAllocator::push_new_pool()
|
||||
{
|
||||
if(m_pool_count >= BT_DEFAULT_MAX_POOLS) return NULL;
|
||||
if (m_pool_count >= BT_DEFAULT_MAX_POOLS) return NULL;
|
||||
|
||||
btGenericMemoryPool * newptr = (btGenericMemoryPool *)btAlignedAlloc(sizeof(btGenericMemoryPool),16);
|
||||
btGenericMemoryPool *newptr = (btGenericMemoryPool *)btAlignedAlloc(sizeof(btGenericMemoryPool), 16);
|
||||
|
||||
m_pools[m_pool_count] = newptr;
|
||||
|
||||
m_pools[m_pool_count]->init_pool(m_pool_element_size,m_pool_element_count);
|
||||
m_pools[m_pool_count]->init_pool(m_pool_element_size, m_pool_element_count);
|
||||
|
||||
m_pool_count++;
|
||||
return newptr;
|
||||
}
|
||||
|
||||
void * btGenericPoolAllocator::failback_alloc(size_t size_bytes)
|
||||
void *btGenericPoolAllocator::failback_alloc(size_t size_bytes)
|
||||
{
|
||||
btGenericMemoryPool *pool = NULL;
|
||||
|
||||
btGenericMemoryPool * pool = NULL;
|
||||
|
||||
|
||||
if(size_bytes<=get_pool_capacity())
|
||||
if (size_bytes <= get_pool_capacity())
|
||||
{
|
||||
pool = push_new_pool();
|
||||
pool = push_new_pool();
|
||||
}
|
||||
|
||||
if(pool==NULL) // failback
|
||||
if (pool == NULL) // failback
|
||||
{
|
||||
return btAlignedAlloc(size_bytes,16);
|
||||
return btAlignedAlloc(size_bytes, 16);
|
||||
}
|
||||
|
||||
return pool->allocate(size_bytes);
|
||||
}
|
||||
|
||||
bool btGenericPoolAllocator::failback_free(void * pointer)
|
||||
bool btGenericPoolAllocator::failback_free(void *pointer)
|
||||
{
|
||||
btAlignedFree(pointer);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! Allocates memory in pool
|
||||
/*!
|
||||
\param size_bytes size in bytes of the buffer
|
||||
*/
|
||||
void * btGenericPoolAllocator::allocate(size_t size_bytes)
|
||||
void *btGenericPoolAllocator::allocate(size_t size_bytes)
|
||||
{
|
||||
void * ptr = NULL;
|
||||
void *ptr = NULL;
|
||||
|
||||
size_t i = 0;
|
||||
while(i<m_pool_count && ptr == NULL)
|
||||
while (i < m_pool_count && ptr == NULL)
|
||||
{
|
||||
ptr = m_pools[i]->allocate(size_bytes);
|
||||
++i;
|
||||
}
|
||||
|
||||
if(ptr) return ptr;
|
||||
if (ptr) return ptr;
|
||||
|
||||
return failback_alloc(size_bytes);
|
||||
}
|
||||
|
||||
bool btGenericPoolAllocator::freeMemory(void * pointer)
|
||||
bool btGenericPoolAllocator::freeMemory(void *pointer)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
size_t i = 0;
|
||||
while(i<m_pool_count && result == false)
|
||||
while (i < m_pool_count && result == false)
|
||||
{
|
||||
result = m_pools[i]->freeMemory(pointer);
|
||||
++i;
|
||||
}
|
||||
|
||||
if(result) return true;
|
||||
if (result) return true;
|
||||
|
||||
return failback_free(pointer);
|
||||
}
|
||||
|
||||
/// ************** STANDARD ALLOCATOR ***************************///
|
||||
|
||||
|
||||
#define BT_DEFAULT_POOL_SIZE 32768
|
||||
#define BT_DEFAULT_POOL_ELEMENT_SIZE 8
|
||||
|
||||
// main allocator
|
||||
class GIM_STANDARD_ALLOCATOR: public btGenericPoolAllocator
|
||||
class GIM_STANDARD_ALLOCATOR : public btGenericPoolAllocator
|
||||
{
|
||||
public:
|
||||
GIM_STANDARD_ALLOCATOR():btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE,BT_DEFAULT_POOL_SIZE)
|
||||
GIM_STANDARD_ALLOCATOR() : btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE, BT_DEFAULT_POOL_SIZE)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -262,19 +246,18 @@ public:
|
||||
// global allocator
|
||||
GIM_STANDARD_ALLOCATOR g_main_allocator;
|
||||
|
||||
|
||||
void * btPoolAlloc(size_t size)
|
||||
void *btPoolAlloc(size_t size)
|
||||
{
|
||||
return g_main_allocator.allocate(size);
|
||||
}
|
||||
|
||||
void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize)
|
||||
void *btPoolRealloc(void *ptr, size_t oldsize, size_t newsize)
|
||||
{
|
||||
void * newptr = btPoolAlloc(newsize);
|
||||
size_t copysize = oldsize<newsize?oldsize:newsize;
|
||||
memcpy(newptr,ptr,copysize);
|
||||
btPoolFree(ptr);
|
||||
return newptr;
|
||||
void *newptr = btPoolAlloc(newsize);
|
||||
size_t copysize = oldsize < newsize ? oldsize : newsize;
|
||||
memcpy(newptr, ptr, copysize);
|
||||
btPoolFree(ptr);
|
||||
return newptr;
|
||||
}
|
||||
|
||||
void btPoolFree(void *ptr)
|
||||
|
||||
@@ -29,16 +29,16 @@ subject to the following restrictions:
|
||||
#define BT_UINT_MAX UINT_MAX
|
||||
#define BT_DEFAULT_MAX_POOLS 16
|
||||
|
||||
|
||||
//! Generic Pool class
|
||||
class btGenericMemoryPool
|
||||
{
|
||||
public:
|
||||
unsigned char * m_pool; //[m_element_size*m_max_element_count];
|
||||
size_t * m_free_nodes; //[m_max_element_count];//! free nodes
|
||||
size_t * m_allocated_sizes;//[m_max_element_count];//! Number of elements allocated per node
|
||||
unsigned char *m_pool; //[m_element_size*m_max_element_count];
|
||||
size_t *m_free_nodes; //[m_max_element_count];//! free nodes
|
||||
size_t *m_allocated_sizes; //[m_max_element_count];//! Number of elements allocated per node
|
||||
size_t m_allocated_count;
|
||||
size_t m_free_nodes_count;
|
||||
|
||||
protected:
|
||||
size_t m_element_size;
|
||||
size_t m_max_element_count;
|
||||
@@ -47,12 +47,10 @@ protected:
|
||||
size_t allocate_from_pool(size_t num_elements);
|
||||
|
||||
public:
|
||||
|
||||
void init_pool(size_t element_size, size_t element_count);
|
||||
|
||||
void end_pool();
|
||||
|
||||
|
||||
btGenericMemoryPool(size_t element_size, size_t element_count)
|
||||
{
|
||||
init_pool(element_size, element_count);
|
||||
@@ -63,10 +61,9 @@ public:
|
||||
end_pool();
|
||||
}
|
||||
|
||||
|
||||
inline size_t get_pool_capacity()
|
||||
{
|
||||
return m_element_size*m_max_element_count;
|
||||
return m_element_size * m_max_element_count;
|
||||
}
|
||||
|
||||
inline size_t gem_element_size()
|
||||
@@ -89,23 +86,20 @@ public:
|
||||
return m_free_nodes_count;
|
||||
}
|
||||
|
||||
inline void * get_element_data(size_t element_index)
|
||||
inline void *get_element_data(size_t element_index)
|
||||
{
|
||||
return &m_pool[element_index*m_element_size];
|
||||
return &m_pool[element_index * m_element_size];
|
||||
}
|
||||
|
||||
//! Allocates memory in pool
|
||||
/*!
|
||||
\param size_bytes size in bytes of the buffer
|
||||
*/
|
||||
void * allocate(size_t size_bytes);
|
||||
void *allocate(size_t size_bytes);
|
||||
|
||||
bool freeMemory(void * pointer);
|
||||
bool freeMemory(void *pointer);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//! Generic Allocator with pools
|
||||
/*!
|
||||
General purpose Allocator which can create Memory Pools dynamiacally as needed.
|
||||
@@ -115,26 +109,25 @@ class btGenericPoolAllocator
|
||||
protected:
|
||||
size_t m_pool_element_size;
|
||||
size_t m_pool_element_count;
|
||||
public:
|
||||
btGenericMemoryPool * m_pools[BT_DEFAULT_MAX_POOLS];
|
||||
size_t m_pool_count;
|
||||
|
||||
public:
|
||||
btGenericMemoryPool *m_pools[BT_DEFAULT_MAX_POOLS];
|
||||
size_t m_pool_count;
|
||||
|
||||
inline size_t get_pool_capacity()
|
||||
{
|
||||
return m_pool_element_size*m_pool_element_count;
|
||||
return m_pool_element_size * m_pool_element_count;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
// creates a pool
|
||||
btGenericMemoryPool * push_new_pool();
|
||||
btGenericMemoryPool *push_new_pool();
|
||||
|
||||
void * failback_alloc(size_t size_bytes);
|
||||
void *failback_alloc(size_t size_bytes);
|
||||
|
||||
bool failback_free(void *pointer);
|
||||
|
||||
bool failback_free(void * pointer);
|
||||
public:
|
||||
|
||||
btGenericPoolAllocator(size_t pool_element_size, size_t pool_element_count)
|
||||
{
|
||||
m_pool_count = 0;
|
||||
@@ -148,16 +141,13 @@ public:
|
||||
/*!
|
||||
\param size_bytes size in bytes of the buffer
|
||||
*/
|
||||
void * allocate(size_t size_bytes);
|
||||
void *allocate(size_t size_bytes);
|
||||
|
||||
bool freeMemory(void * pointer);
|
||||
bool freeMemory(void *pointer);
|
||||
};
|
||||
|
||||
|
||||
|
||||
void * btPoolAlloc(size_t size);
|
||||
void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize);
|
||||
void *btPoolAlloc(size_t size);
|
||||
void *btPoolRealloc(void *ptr, size_t oldsize, size_t newsize);
|
||||
void btPoolFree(void *ptr);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,52 +27,44 @@ subject to the following restrictions:
|
||||
|
||||
#include "btBoxCollision.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define PLANEDIREPSILON 0.0000001f
|
||||
#define PARALELENORMALS 0.000001f
|
||||
|
||||
|
||||
#define BT_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
|
||||
#define BT_CLAMP(number, minval, maxval) (number < minval ? minval : (number > maxval ? maxval : number))
|
||||
|
||||
/// Calc a plane from a triangle edge an a normal. plane is a vec4f
|
||||
SIMD_FORCE_INLINE void bt_edge_plane(const btVector3 & e1,const btVector3 & e2, const btVector3 & normal,btVector4 & plane)
|
||||
SIMD_FORCE_INLINE void bt_edge_plane(const btVector3 &e1, const btVector3 &e2, const btVector3 &normal, btVector4 &plane)
|
||||
{
|
||||
btVector3 planenormal = (e2-e1).cross(normal);
|
||||
btVector3 planenormal = (e2 - e1).cross(normal);
|
||||
planenormal.normalize();
|
||||
plane.setValue(planenormal[0],planenormal[1],planenormal[2],e2.dot(planenormal));
|
||||
plane.setValue(planenormal[0], planenormal[1], planenormal[2], e2.dot(planenormal));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***************** SEGMENT and LINE FUNCTIONS **********************************///
|
||||
|
||||
/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
|
||||
*/
|
||||
SIMD_FORCE_INLINE void bt_closest_point_on_segment(
|
||||
btVector3 & cp, const btVector3 & v,
|
||||
const btVector3 &e1,const btVector3 &e2)
|
||||
btVector3 &cp, const btVector3 &v,
|
||||
const btVector3 &e1, const btVector3 &e2)
|
||||
{
|
||||
btVector3 n = e2-e1;
|
||||
cp = v - e1;
|
||||
btScalar _scalar = cp.dot(n)/n.dot(n);
|
||||
if(_scalar <0.0f)
|
||||
btVector3 n = e2 - e1;
|
||||
cp = v - e1;
|
||||
btScalar _scalar = cp.dot(n) / n.dot(n);
|
||||
if (_scalar < 0.0f)
|
||||
{
|
||||
cp = e1;
|
||||
cp = e1;
|
||||
}
|
||||
else if(_scalar >1.0f)
|
||||
else if (_scalar > 1.0f)
|
||||
{
|
||||
cp = e2;
|
||||
cp = e2;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp = _scalar*n + e1;
|
||||
cp = _scalar * n + e1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! line plane collision
|
||||
/*!
|
||||
*\return
|
||||
@@ -82,131 +74,125 @@ SIMD_FORCE_INLINE void bt_closest_point_on_segment(
|
||||
*/
|
||||
|
||||
SIMD_FORCE_INLINE int bt_line_plane_collision(
|
||||
const btVector4 & plane,
|
||||
const btVector3 & vDir,
|
||||
const btVector3 & vPoint,
|
||||
btVector3 & pout,
|
||||
const btVector4 &plane,
|
||||
const btVector3 &vDir,
|
||||
const btVector3 &vPoint,
|
||||
btVector3 &pout,
|
||||
btScalar &tparam,
|
||||
btScalar tmin, btScalar tmax)
|
||||
{
|
||||
|
||||
btScalar _dotdir = vDir.dot(plane);
|
||||
|
||||
if(btFabs(_dotdir)<PLANEDIREPSILON)
|
||||
if (btFabs(_dotdir) < PLANEDIREPSILON)
|
||||
{
|
||||
tparam = tmax;
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
btScalar _dis = bt_distance_point_plane(plane,vPoint);
|
||||
char returnvalue = _dis<0.0f? 2:1;
|
||||
tparam = -_dis/_dotdir;
|
||||
btScalar _dis = bt_distance_point_plane(plane, vPoint);
|
||||
char returnvalue = _dis < 0.0f ? 2 : 1;
|
||||
tparam = -_dis / _dotdir;
|
||||
|
||||
if(tparam<tmin)
|
||||
if (tparam < tmin)
|
||||
{
|
||||
returnvalue = 0;
|
||||
tparam = tmin;
|
||||
}
|
||||
else if(tparam>tmax)
|
||||
else if (tparam > tmax)
|
||||
{
|
||||
returnvalue = 0;
|
||||
tparam = tmax;
|
||||
}
|
||||
pout = tparam*vDir + vPoint;
|
||||
pout = tparam * vDir + vPoint;
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
|
||||
//! Find closest points on segments
|
||||
SIMD_FORCE_INLINE void bt_segment_collision(
|
||||
const btVector3 & vA1,
|
||||
const btVector3 & vA2,
|
||||
const btVector3 & vB1,
|
||||
const btVector3 & vB2,
|
||||
btVector3 & vPointA,
|
||||
btVector3 & vPointB)
|
||||
const btVector3 &vA1,
|
||||
const btVector3 &vA2,
|
||||
const btVector3 &vB1,
|
||||
const btVector3 &vB2,
|
||||
btVector3 &vPointA,
|
||||
btVector3 &vPointB)
|
||||
{
|
||||
btVector3 AD = vA2 - vA1;
|
||||
btVector3 BD = vB2 - vB1;
|
||||
btVector3 N = AD.cross(BD);
|
||||
btScalar tp = N.length2();
|
||||
btVector3 AD = vA2 - vA1;
|
||||
btVector3 BD = vB2 - vB1;
|
||||
btVector3 N = AD.cross(BD);
|
||||
btScalar tp = N.length2();
|
||||
|
||||
btVector4 _M;//plane
|
||||
btVector4 _M; //plane
|
||||
|
||||
if(tp<SIMD_EPSILON)//ARE PARALELE
|
||||
{
|
||||
//project B over A
|
||||
bool invert_b_order = false;
|
||||
_M[0] = vB1.dot(AD);
|
||||
_M[1] = vB2.dot(AD);
|
||||
if (tp < SIMD_EPSILON) //ARE PARALELE
|
||||
{
|
||||
//project B over A
|
||||
bool invert_b_order = false;
|
||||
_M[0] = vB1.dot(AD);
|
||||
_M[1] = vB2.dot(AD);
|
||||
|
||||
if(_M[0]>_M[1])
|
||||
{
|
||||
invert_b_order = true;
|
||||
BT_SWAP_NUMBERS(_M[0],_M[1]);
|
||||
}
|
||||
_M[2] = vA1.dot(AD);
|
||||
_M[3] = vA2.dot(AD);
|
||||
//mid points
|
||||
N[0] = (_M[0]+_M[1])*0.5f;
|
||||
N[1] = (_M[2]+_M[3])*0.5f;
|
||||
if (_M[0] > _M[1])
|
||||
{
|
||||
invert_b_order = true;
|
||||
BT_SWAP_NUMBERS(_M[0], _M[1]);
|
||||
}
|
||||
_M[2] = vA1.dot(AD);
|
||||
_M[3] = vA2.dot(AD);
|
||||
//mid points
|
||||
N[0] = (_M[0] + _M[1]) * 0.5f;
|
||||
N[1] = (_M[2] + _M[3]) * 0.5f;
|
||||
|
||||
if(N[0]<N[1])
|
||||
{
|
||||
if(_M[1]<_M[2])
|
||||
{
|
||||
vPointB = invert_b_order?vB1:vB2;
|
||||
vPointA = vA1;
|
||||
}
|
||||
else if(_M[1]<_M[3])
|
||||
{
|
||||
vPointB = invert_b_order?vB1:vB2;
|
||||
bt_closest_point_on_segment(vPointA,vPointB,vA1,vA2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointA = vA2;
|
||||
bt_closest_point_on_segment(vPointB,vPointA,vB1,vB2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_M[3]<_M[0])
|
||||
{
|
||||
vPointB = invert_b_order?vB2:vB1;
|
||||
vPointA = vA2;
|
||||
}
|
||||
else if(_M[3]<_M[1])
|
||||
{
|
||||
vPointA = vA2;
|
||||
bt_closest_point_on_segment(vPointB,vPointA,vB1,vB2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointB = invert_b_order?vB1:vB2;
|
||||
bt_closest_point_on_segment(vPointA,vPointB,vA1,vA2);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (N[0] < N[1])
|
||||
{
|
||||
if (_M[1] < _M[2])
|
||||
{
|
||||
vPointB = invert_b_order ? vB1 : vB2;
|
||||
vPointA = vA1;
|
||||
}
|
||||
else if (_M[1] < _M[3])
|
||||
{
|
||||
vPointB = invert_b_order ? vB1 : vB2;
|
||||
bt_closest_point_on_segment(vPointA, vPointB, vA1, vA2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointA = vA2;
|
||||
bt_closest_point_on_segment(vPointB, vPointA, vB1, vB2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_M[3] < _M[0])
|
||||
{
|
||||
vPointB = invert_b_order ? vB2 : vB1;
|
||||
vPointA = vA2;
|
||||
}
|
||||
else if (_M[3] < _M[1])
|
||||
{
|
||||
vPointA = vA2;
|
||||
bt_closest_point_on_segment(vPointB, vPointA, vB1, vB2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointB = invert_b_order ? vB1 : vB2;
|
||||
bt_closest_point_on_segment(vPointA, vPointB, vA1, vA2);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
N = N.cross(BD);
|
||||
_M.setValue(N[0],N[1],N[2],vB1.dot(N));
|
||||
N = N.cross(BD);
|
||||
_M.setValue(N[0], N[1], N[2], vB1.dot(N));
|
||||
|
||||
// get point A as the plane collision point
|
||||
bt_line_plane_collision(_M,AD,vA1,vPointA,tp,btScalar(0), btScalar(1));
|
||||
bt_line_plane_collision(_M, AD, vA1, vPointA, tp, btScalar(0), btScalar(1));
|
||||
|
||||
/*Closest point on segment*/
|
||||
vPointB = vPointA - vB1;
|
||||
/*Closest point on segment*/
|
||||
vPointB = vPointA - vB1;
|
||||
tp = vPointB.dot(BD);
|
||||
tp/= BD.dot(BD);
|
||||
tp = BT_CLAMP(tp,0.0f,1.0f);
|
||||
tp /= BD.dot(BD);
|
||||
tp = BT_CLAMP(tp, 0.0f, 1.0f);
|
||||
|
||||
vPointB = tp*BD + vB1;
|
||||
vPointB = tp * BD + vB1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // GIM_VECTOR_H_INCLUDED
|
||||
#endif // GIM_VECTOR_H_INCLUDED
|
||||
|
||||
@@ -27,54 +27,47 @@ subject to the following restrictions:
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void bt_calc_quantization_parameters(
|
||||
btVector3 & outMinBound,
|
||||
btVector3 & outMaxBound,
|
||||
btVector3 & bvhQuantization,
|
||||
const btVector3& srcMinBound,const btVector3& srcMaxBound,
|
||||
btVector3& outMinBound,
|
||||
btVector3& outMaxBound,
|
||||
btVector3& bvhQuantization,
|
||||
const btVector3& srcMinBound, const btVector3& srcMaxBound,
|
||||
btScalar quantizationMargin)
|
||||
{
|
||||
//enlarge the AABB to avoid division by zero when initializing the quantization values
|
||||
btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
|
||||
btVector3 clampValue(quantizationMargin, quantizationMargin, quantizationMargin);
|
||||
outMinBound = srcMinBound - clampValue;
|
||||
outMaxBound = srcMaxBound + clampValue;
|
||||
btVector3 aabbSize = outMaxBound - outMinBound;
|
||||
bvhQuantization = btVector3(btScalar(65535.0),
|
||||
btScalar(65535.0),
|
||||
btScalar(65535.0)) / aabbSize;
|
||||
btScalar(65535.0)) /
|
||||
aabbSize;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void bt_quantize_clamp(
|
||||
unsigned short* out,
|
||||
const btVector3& point,
|
||||
const btVector3 & min_bound,
|
||||
const btVector3 & max_bound,
|
||||
const btVector3 & bvhQuantization)
|
||||
const btVector3& min_bound,
|
||||
const btVector3& max_bound,
|
||||
const btVector3& bvhQuantization)
|
||||
{
|
||||
|
||||
btVector3 clampedPoint(point);
|
||||
clampedPoint.setMax(min_bound);
|
||||
clampedPoint.setMin(max_bound);
|
||||
|
||||
btVector3 v = (clampedPoint - min_bound) * bvhQuantization;
|
||||
out[0] = (unsigned short)(v.getX()+0.5f);
|
||||
out[1] = (unsigned short)(v.getY()+0.5f);
|
||||
out[2] = (unsigned short)(v.getZ()+0.5f);
|
||||
out[0] = (unsigned short)(v.getX() + 0.5f);
|
||||
out[1] = (unsigned short)(v.getY() + 0.5f);
|
||||
out[2] = (unsigned short)(v.getZ() + 0.5f);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 bt_unquantize(
|
||||
const unsigned short* vecIn,
|
||||
const btVector3 & offset,
|
||||
const btVector3 & bvhQuantization)
|
||||
const btVector3& offset,
|
||||
const btVector3& bvhQuantization)
|
||||
{
|
||||
btVector3 vecOut;
|
||||
btVector3 vecOut;
|
||||
vecOut.setValue(
|
||||
(btScalar)(vecIn[0]) / (bvhQuantization.getX()),
|
||||
(btScalar)(vecIn[1]) / (bvhQuantization.getY()),
|
||||
@@ -83,6 +76,4 @@ SIMD_FORCE_INLINE btVector3 bt_unquantize(
|
||||
return vecOut;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // BT_GIMPACT_QUANTIZATION_H_INCLUDED
|
||||
#endif // BT_GIMPACT_QUANTIZATION_H_INCLUDED
|
||||
|
||||
@@ -23,196 +23,181 @@ subject to the following restrictions:
|
||||
|
||||
#include "btTriangleShapeEx.h"
|
||||
|
||||
|
||||
|
||||
void GIM_TRIANGLE_CONTACT::merge_points(const btVector4 & plane,
|
||||
btScalar margin, const btVector3 * points, int point_count)
|
||||
void GIM_TRIANGLE_CONTACT::merge_points(const btVector4& plane,
|
||||
btScalar margin, const btVector3* points, int point_count)
|
||||
{
|
||||
m_point_count = 0;
|
||||
m_penetration_depth= -1000.0f;
|
||||
m_point_count = 0;
|
||||
m_penetration_depth = -1000.0f;
|
||||
|
||||
int point_indices[MAX_TRI_CLIPPING];
|
||||
int point_indices[MAX_TRI_CLIPPING];
|
||||
|
||||
int _k;
|
||||
|
||||
for ( _k=0;_k<point_count;_k++)
|
||||
{
|
||||
btScalar _dist = - bt_distance_point_plane(plane,points[_k]) + margin;
|
||||
for (_k = 0; _k < point_count; _k++)
|
||||
{
|
||||
btScalar _dist = -bt_distance_point_plane(plane, points[_k]) + margin;
|
||||
|
||||
if (_dist>=0.0f)
|
||||
{
|
||||
if (_dist>m_penetration_depth)
|
||||
{
|
||||
m_penetration_depth = _dist;
|
||||
point_indices[0] = _k;
|
||||
m_point_count=1;
|
||||
}
|
||||
else if ((_dist+SIMD_EPSILON)>=m_penetration_depth)
|
||||
{
|
||||
point_indices[m_point_count] = _k;
|
||||
m_point_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_dist >= 0.0f)
|
||||
{
|
||||
if (_dist > m_penetration_depth)
|
||||
{
|
||||
m_penetration_depth = _dist;
|
||||
point_indices[0] = _k;
|
||||
m_point_count = 1;
|
||||
}
|
||||
else if ((_dist + SIMD_EPSILON) >= m_penetration_depth)
|
||||
{
|
||||
point_indices[m_point_count] = _k;
|
||||
m_point_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( _k=0;_k<m_point_count;_k++)
|
||||
{
|
||||
m_points[_k] = points[point_indices[_k]];
|
||||
}
|
||||
for (_k = 0; _k < m_point_count; _k++)
|
||||
{
|
||||
m_points[_k] = points[point_indices[_k]];
|
||||
}
|
||||
}
|
||||
|
||||
///class btPrimitiveTriangle
|
||||
bool btPrimitiveTriangle::overlap_test_conservative(const btPrimitiveTriangle& other)
|
||||
{
|
||||
btScalar total_margin = m_margin + other.m_margin;
|
||||
// classify points on other triangle
|
||||
btScalar dis0 = bt_distance_point_plane(m_plane,other.m_vertices[0]) - total_margin;
|
||||
btScalar total_margin = m_margin + other.m_margin;
|
||||
// classify points on other triangle
|
||||
btScalar dis0 = bt_distance_point_plane(m_plane, other.m_vertices[0]) - total_margin;
|
||||
|
||||
btScalar dis1 = bt_distance_point_plane(m_plane,other.m_vertices[1]) - total_margin;
|
||||
btScalar dis1 = bt_distance_point_plane(m_plane, other.m_vertices[1]) - total_margin;
|
||||
|
||||
btScalar dis2 = bt_distance_point_plane(m_plane,other.m_vertices[2]) - total_margin;
|
||||
btScalar dis2 = bt_distance_point_plane(m_plane, other.m_vertices[2]) - total_margin;
|
||||
|
||||
if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false;
|
||||
if (dis0 > 0.0f && dis1 > 0.0f && dis2 > 0.0f) return false;
|
||||
|
||||
// classify points on this triangle
|
||||
dis0 = bt_distance_point_plane(other.m_plane,m_vertices[0]) - total_margin;
|
||||
// classify points on this triangle
|
||||
dis0 = bt_distance_point_plane(other.m_plane, m_vertices[0]) - total_margin;
|
||||
|
||||
dis1 = bt_distance_point_plane(other.m_plane,m_vertices[1]) - total_margin;
|
||||
dis1 = bt_distance_point_plane(other.m_plane, m_vertices[1]) - total_margin;
|
||||
|
||||
dis2 = bt_distance_point_plane(other.m_plane,m_vertices[2]) - total_margin;
|
||||
dis2 = bt_distance_point_plane(other.m_plane, m_vertices[2]) - total_margin;
|
||||
|
||||
if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false;
|
||||
if (dis0 > 0.0f && dis1 > 0.0f && dis2 > 0.0f) return false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
int btPrimitiveTriangle::clip_triangle(btPrimitiveTriangle & other, btVector3 * clipped_points )
|
||||
int btPrimitiveTriangle::clip_triangle(btPrimitiveTriangle& other, btVector3* clipped_points)
|
||||
{
|
||||
// edge 0
|
||||
// edge 0
|
||||
|
||||
btVector3 temp_points[MAX_TRI_CLIPPING];
|
||||
btVector3 temp_points[MAX_TRI_CLIPPING];
|
||||
|
||||
btVector4 edgeplane;
|
||||
|
||||
btVector4 edgeplane;
|
||||
get_edge_plane(0, edgeplane);
|
||||
|
||||
get_edge_plane(0,edgeplane);
|
||||
int clipped_count = bt_plane_clip_triangle(
|
||||
edgeplane, other.m_vertices[0], other.m_vertices[1], other.m_vertices[2], temp_points);
|
||||
|
||||
if (clipped_count == 0) return 0;
|
||||
|
||||
int clipped_count = bt_plane_clip_triangle(
|
||||
edgeplane,other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],temp_points);
|
||||
btVector3 temp_points1[MAX_TRI_CLIPPING];
|
||||
|
||||
if (clipped_count == 0) return 0;
|
||||
// edge 1
|
||||
get_edge_plane(1, edgeplane);
|
||||
|
||||
btVector3 temp_points1[MAX_TRI_CLIPPING];
|
||||
clipped_count = bt_plane_clip_polygon(edgeplane, temp_points, clipped_count, temp_points1);
|
||||
|
||||
if (clipped_count == 0) return 0;
|
||||
|
||||
// edge 1
|
||||
get_edge_plane(1,edgeplane);
|
||||
// edge 2
|
||||
get_edge_plane(2, edgeplane);
|
||||
|
||||
clipped_count = bt_plane_clip_polygon(
|
||||
edgeplane, temp_points1, clipped_count, clipped_points);
|
||||
|
||||
clipped_count = bt_plane_clip_polygon(edgeplane,temp_points,clipped_count,temp_points1);
|
||||
|
||||
if (clipped_count == 0) return 0;
|
||||
|
||||
// edge 2
|
||||
get_edge_plane(2,edgeplane);
|
||||
|
||||
clipped_count = bt_plane_clip_polygon(
|
||||
edgeplane,temp_points1,clipped_count,clipped_points);
|
||||
|
||||
return clipped_count;
|
||||
return clipped_count;
|
||||
}
|
||||
|
||||
bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts)
|
||||
bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangle& other, GIM_TRIANGLE_CONTACT& contacts)
|
||||
{
|
||||
btScalar margin = m_margin + other.m_margin;
|
||||
btScalar margin = m_margin + other.m_margin;
|
||||
|
||||
btVector3 clipped_points[MAX_TRI_CLIPPING];
|
||||
int clipped_count;
|
||||
//create planes
|
||||
// plane v vs U points
|
||||
btVector3 clipped_points[MAX_TRI_CLIPPING];
|
||||
int clipped_count;
|
||||
//create planes
|
||||
// plane v vs U points
|
||||
|
||||
GIM_TRIANGLE_CONTACT contacts1;
|
||||
GIM_TRIANGLE_CONTACT contacts1;
|
||||
|
||||
contacts1.m_separating_normal = m_plane;
|
||||
contacts1.m_separating_normal = m_plane;
|
||||
|
||||
clipped_count = clip_triangle(other, clipped_points);
|
||||
|
||||
clipped_count = clip_triangle(other,clipped_points);
|
||||
if (clipped_count == 0)
|
||||
{
|
||||
return false; //Reject
|
||||
}
|
||||
|
||||
if (clipped_count == 0 )
|
||||
{
|
||||
return false;//Reject
|
||||
}
|
||||
//find most deep interval face1
|
||||
contacts1.merge_points(contacts1.m_separating_normal, margin, clipped_points, clipped_count);
|
||||
if (contacts1.m_point_count == 0) return false; // too far
|
||||
//Normal pointing to this triangle
|
||||
contacts1.m_separating_normal *= -1.f;
|
||||
|
||||
//find most deep interval face1
|
||||
contacts1.merge_points(contacts1.m_separating_normal,margin,clipped_points,clipped_count);
|
||||
if (contacts1.m_point_count == 0) return false; // too far
|
||||
//Normal pointing to this triangle
|
||||
contacts1.m_separating_normal *= -1.f;
|
||||
//Clip tri1 by tri2 edges
|
||||
GIM_TRIANGLE_CONTACT contacts2;
|
||||
contacts2.m_separating_normal = other.m_plane;
|
||||
|
||||
clipped_count = other.clip_triangle(*this, clipped_points);
|
||||
|
||||
//Clip tri1 by tri2 edges
|
||||
GIM_TRIANGLE_CONTACT contacts2;
|
||||
contacts2.m_separating_normal = other.m_plane;
|
||||
if (clipped_count == 0)
|
||||
{
|
||||
return false; //Reject
|
||||
}
|
||||
|
||||
clipped_count = other.clip_triangle(*this,clipped_points);
|
||||
//find most deep interval face1
|
||||
contacts2.merge_points(contacts2.m_separating_normal, margin, clipped_points, clipped_count);
|
||||
if (contacts2.m_point_count == 0) return false; // too far
|
||||
|
||||
if (clipped_count == 0 )
|
||||
{
|
||||
return false;//Reject
|
||||
}
|
||||
|
||||
//find most deep interval face1
|
||||
contacts2.merge_points(contacts2.m_separating_normal,margin,clipped_points,clipped_count);
|
||||
if (contacts2.m_point_count == 0) return false; // too far
|
||||
|
||||
|
||||
|
||||
|
||||
////check most dir for contacts
|
||||
if (contacts2.m_penetration_depth<contacts1.m_penetration_depth)
|
||||
{
|
||||
contacts.copy_from(contacts2);
|
||||
}
|
||||
else
|
||||
{
|
||||
contacts.copy_from(contacts1);
|
||||
}
|
||||
return true;
|
||||
////check most dir for contacts
|
||||
if (contacts2.m_penetration_depth < contacts1.m_penetration_depth)
|
||||
{
|
||||
contacts.copy_from(contacts2);
|
||||
}
|
||||
else
|
||||
{
|
||||
contacts.copy_from(contacts1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///class btTriangleShapeEx: public btTriangleShape
|
||||
|
||||
bool btTriangleShapeEx::overlap_test_conservative(const btTriangleShapeEx& other)
|
||||
{
|
||||
btScalar total_margin = getMargin() + other.getMargin();
|
||||
btScalar total_margin = getMargin() + other.getMargin();
|
||||
|
||||
btVector4 plane0;
|
||||
buildTriPlane(plane0);
|
||||
btVector4 plane1;
|
||||
other.buildTriPlane(plane1);
|
||||
btVector4 plane0;
|
||||
buildTriPlane(plane0);
|
||||
btVector4 plane1;
|
||||
other.buildTriPlane(plane1);
|
||||
|
||||
// classify points on other triangle
|
||||
btScalar dis0 = bt_distance_point_plane(plane0,other.m_vertices1[0]) - total_margin;
|
||||
// classify points on other triangle
|
||||
btScalar dis0 = bt_distance_point_plane(plane0, other.m_vertices1[0]) - total_margin;
|
||||
|
||||
btScalar dis1 = bt_distance_point_plane(plane0,other.m_vertices1[1]) - total_margin;
|
||||
btScalar dis1 = bt_distance_point_plane(plane0, other.m_vertices1[1]) - total_margin;
|
||||
|
||||
btScalar dis2 = bt_distance_point_plane(plane0,other.m_vertices1[2]) - total_margin;
|
||||
btScalar dis2 = bt_distance_point_plane(plane0, other.m_vertices1[2]) - total_margin;
|
||||
|
||||
if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false;
|
||||
if (dis0 > 0.0f && dis1 > 0.0f && dis2 > 0.0f) return false;
|
||||
|
||||
// classify points on this triangle
|
||||
dis0 = bt_distance_point_plane(plane1,m_vertices1[0]) - total_margin;
|
||||
// classify points on this triangle
|
||||
dis0 = bt_distance_point_plane(plane1, m_vertices1[0]) - total_margin;
|
||||
|
||||
dis1 = bt_distance_point_plane(plane1,m_vertices1[1]) - total_margin;
|
||||
dis1 = bt_distance_point_plane(plane1, m_vertices1[1]) - total_margin;
|
||||
|
||||
dis2 = bt_distance_point_plane(plane1,m_vertices1[2]) - total_margin;
|
||||
dis2 = bt_distance_point_plane(plane1, m_vertices1[2]) - total_margin;
|
||||
|
||||
if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false;
|
||||
if (dis0 > 0.0f && dis1 > 0.0f && dis2 > 0.0f) return false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GIMPACT_TRIANGLE_SHAPE_EX_H
|
||||
#define GIMPACT_TRIANGLE_SHAPE_EX_H
|
||||
|
||||
@@ -31,16 +30,15 @@ subject to the following restrictions:
|
||||
#include "btClipPolygon.h"
|
||||
#include "btGeometryOperations.h"
|
||||
|
||||
|
||||
#define MAX_TRI_CLIPPING 16
|
||||
|
||||
//! Structure for collision
|
||||
struct GIM_TRIANGLE_CONTACT
|
||||
{
|
||||
btScalar m_penetration_depth;
|
||||
int m_point_count;
|
||||
btVector4 m_separating_normal;
|
||||
btVector3 m_points[MAX_TRI_CLIPPING];
|
||||
btScalar m_penetration_depth;
|
||||
int m_point_count;
|
||||
btVector4 m_separating_normal;
|
||||
btVector3 m_points[MAX_TRI_CLIPPING];
|
||||
|
||||
SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT& other)
|
||||
{
|
||||
@@ -48,7 +46,7 @@ struct GIM_TRIANGLE_CONTACT
|
||||
m_separating_normal = other.m_separating_normal;
|
||||
m_point_count = other.m_point_count;
|
||||
int i = m_point_count;
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
m_points[i] = other.m_points[i];
|
||||
}
|
||||
@@ -63,14 +61,11 @@ struct GIM_TRIANGLE_CONTACT
|
||||
copy_from(other);
|
||||
}
|
||||
|
||||
//! classify points that are closer
|
||||
void merge_points(const btVector4 & plane,
|
||||
btScalar margin, const btVector3 * points, int point_count);
|
||||
|
||||
//! classify points that are closer
|
||||
void merge_points(const btVector4& plane,
|
||||
btScalar margin, const btVector3* points, int point_count);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class btPrimitiveTriangle
|
||||
{
|
||||
public:
|
||||
@@ -78,17 +73,15 @@ public:
|
||||
btVector4 m_plane;
|
||||
btScalar m_margin;
|
||||
btScalar m_dummy;
|
||||
btPrimitiveTriangle():m_margin(0.01f)
|
||||
btPrimitiveTriangle() : m_margin(0.01f)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void buildTriPlane()
|
||||
{
|
||||
btVector3 normal = (m_vertices[1]-m_vertices[0]).cross(m_vertices[2]-m_vertices[0]);
|
||||
btVector3 normal = (m_vertices[1] - m_vertices[0]).cross(m_vertices[2] - m_vertices[0]);
|
||||
normal.normalize();
|
||||
m_plane.setValue(normal[0],normal[1],normal[2],m_vertices[0].dot(normal));
|
||||
m_plane.setValue(normal[0], normal[1], normal[2], m_vertices[0].dot(normal));
|
||||
}
|
||||
|
||||
//! Test if triangles could collide
|
||||
@@ -98,14 +91,14 @@ public:
|
||||
/*!
|
||||
\pre this triangle must have its plane calculated.
|
||||
*/
|
||||
SIMD_FORCE_INLINE void get_edge_plane(int edge_index, btVector4 &plane) const
|
||||
{
|
||||
const btVector3 & e0 = m_vertices[edge_index];
|
||||
const btVector3 & e1 = m_vertices[(edge_index+1)%3];
|
||||
bt_edge_plane(e0,e1,m_plane,plane);
|
||||
}
|
||||
SIMD_FORCE_INLINE void get_edge_plane(int edge_index, btVector4& plane) const
|
||||
{
|
||||
const btVector3& e0 = m_vertices[edge_index];
|
||||
const btVector3& e1 = m_vertices[(edge_index + 1) % 3];
|
||||
bt_edge_plane(e0, e1, m_plane, plane);
|
||||
}
|
||||
|
||||
void applyTransform(const btTransform& t)
|
||||
void applyTransform(const btTransform& t)
|
||||
{
|
||||
m_vertices[0] = t(m_vertices[0]);
|
||||
m_vertices[1] = t(m_vertices[1]);
|
||||
@@ -117,44 +110,41 @@ public:
|
||||
\pre clipped_points must have MAX_TRI_CLIPPING size, and this triangle must have its plane calculated.
|
||||
\return the number of clipped points
|
||||
*/
|
||||
int clip_triangle(btPrimitiveTriangle & other, btVector3 * clipped_points );
|
||||
int clip_triangle(btPrimitiveTriangle& other, btVector3* clipped_points);
|
||||
|
||||
//! Find collision using the clipping method
|
||||
/*!
|
||||
\pre this triangle and other must have their triangles calculated
|
||||
*/
|
||||
bool find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts);
|
||||
bool find_triangle_collision_clip_method(btPrimitiveTriangle& other, GIM_TRIANGLE_CONTACT& contacts);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//! Helper class for colliding Bullet Triangle Shapes
|
||||
/*!
|
||||
This class implements a better getAabb method than the previous btTriangleShape class
|
||||
*/
|
||||
class btTriangleShapeEx: public btTriangleShape
|
||||
class btTriangleShapeEx : public btTriangleShape
|
||||
{
|
||||
public:
|
||||
|
||||
btTriangleShapeEx():btTriangleShape(btVector3(0,0,0),btVector3(0,0,0),btVector3(0,0,0))
|
||||
btTriangleShapeEx() : btTriangleShape(btVector3(0, 0, 0), btVector3(0, 0, 0), btVector3(0, 0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
btTriangleShapeEx(const btVector3& p0,const btVector3& p1,const btVector3& p2): btTriangleShape(p0,p1,p2)
|
||||
btTriangleShapeEx(const btVector3& p0, const btVector3& p1, const btVector3& p2) : btTriangleShape(p0, p1, p2)
|
||||
{
|
||||
}
|
||||
|
||||
btTriangleShapeEx(const btTriangleShapeEx & other): btTriangleShape(other.m_vertices1[0],other.m_vertices1[1],other.m_vertices1[2])
|
||||
btTriangleShapeEx(const btTriangleShapeEx& other) : btTriangleShape(other.m_vertices1[0], other.m_vertices1[1], other.m_vertices1[2])
|
||||
{
|
||||
}
|
||||
|
||||
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const
|
||||
virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
|
||||
{
|
||||
btVector3 tv0 = t(m_vertices1[0]);
|
||||
btVector3 tv1 = t(m_vertices1[1]);
|
||||
btVector3 tv2 = t(m_vertices1[2]);
|
||||
|
||||
btAABB trianglebox(tv0,tv1,tv2,m_collisionMargin);
|
||||
btAABB trianglebox(tv0, tv1, tv2, m_collisionMargin);
|
||||
aabbMin = trianglebox.m_min;
|
||||
aabbMax = trianglebox.m_max;
|
||||
}
|
||||
@@ -166,15 +156,14 @@ public:
|
||||
m_vertices1[2] = t(m_vertices1[2]);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void buildTriPlane(btVector4 & plane) const
|
||||
SIMD_FORCE_INLINE void buildTriPlane(btVector4& plane) const
|
||||
{
|
||||
btVector3 normal = (m_vertices1[1]-m_vertices1[0]).cross(m_vertices1[2]-m_vertices1[0]);
|
||||
btVector3 normal = (m_vertices1[1] - m_vertices1[0]).cross(m_vertices1[2] - m_vertices1[0]);
|
||||
normal.normalize();
|
||||
plane.setValue(normal[0],normal[1],normal[2],m_vertices1[0].dot(normal));
|
||||
plane.setValue(normal[0], normal[1], normal[2], m_vertices1[0].dot(normal));
|
||||
}
|
||||
|
||||
bool overlap_test_conservative(const btTriangleShapeEx& other);
|
||||
};
|
||||
|
||||
|
||||
#endif //GIMPACT_TRIANGLE_MESH_SHAPE_H
|
||||
#endif //GIMPACT_TRIANGLE_MESH_SHAPE_H
|
||||
|
||||
@@ -34,47 +34,46 @@ email: projectileman@yahoo.com
|
||||
|
||||
#include "gim_memory.h"
|
||||
|
||||
|
||||
#define GIM_ARRAY_GROW_INCREMENT 2
|
||||
#define GIM_ARRAY_GROW_FACTOR 2
|
||||
|
||||
//! Very simple array container with fast access and simd memory
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
class gim_array
|
||||
{
|
||||
public:
|
||||
//! properties
|
||||
//!@{
|
||||
T *m_data;
|
||||
GUINT m_size;
|
||||
GUINT m_allocated_size;
|
||||
//!@}
|
||||
//! protected operations
|
||||
//!@{
|
||||
//! properties
|
||||
//!@{
|
||||
T* m_data;
|
||||
GUINT m_size;
|
||||
GUINT m_allocated_size;
|
||||
//!@}
|
||||
//! protected operations
|
||||
//!@{
|
||||
|
||||
inline void destroyData()
|
||||
inline void destroyData()
|
||||
{
|
||||
m_allocated_size = 0;
|
||||
if(m_data==NULL) return;
|
||||
m_allocated_size = 0;
|
||||
if (m_data == NULL) return;
|
||||
gim_free(m_data);
|
||||
m_data = NULL;
|
||||
}
|
||||
|
||||
inline bool resizeData(GUINT newsize)
|
||||
{
|
||||
if(newsize==0)
|
||||
if (newsize == 0)
|
||||
{
|
||||
destroyData();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(m_size>0)
|
||||
if (m_size > 0)
|
||||
{
|
||||
m_data = (T*)gim_realloc(m_data,m_size*sizeof(T),newsize*sizeof(T));
|
||||
m_data = (T*)gim_realloc(m_data, m_size * sizeof(T), newsize * sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data = (T*)gim_alloc(newsize*sizeof(T));
|
||||
m_data = (T*)gim_alloc(newsize * sizeof(T));
|
||||
}
|
||||
m_allocated_size = newsize;
|
||||
return true;
|
||||
@@ -82,243 +81,238 @@ public:
|
||||
|
||||
inline bool growingCheck()
|
||||
{
|
||||
if(m_allocated_size<=m_size)
|
||||
if (m_allocated_size <= m_size)
|
||||
{
|
||||
GUINT requestsize = m_size;
|
||||
m_size = m_allocated_size;
|
||||
if(resizeData((requestsize+GIM_ARRAY_GROW_INCREMENT)*GIM_ARRAY_GROW_FACTOR)==false) return false;
|
||||
GUINT requestsize = m_size;
|
||||
m_size = m_allocated_size;
|
||||
if (resizeData((requestsize + GIM_ARRAY_GROW_INCREMENT) * GIM_ARRAY_GROW_FACTOR) == false) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//!@}
|
||||
//! public operations
|
||||
//!@{
|
||||
inline bool reserve(GUINT size)
|
||||
{
|
||||
if(m_allocated_size>=size) return false;
|
||||
return resizeData(size);
|
||||
}
|
||||
//!@}
|
||||
//! public operations
|
||||
//!@{
|
||||
inline bool reserve(GUINT size)
|
||||
{
|
||||
if (m_allocated_size >= size) return false;
|
||||
return resizeData(size);
|
||||
}
|
||||
|
||||
inline void clear_range(GUINT start_range)
|
||||
{
|
||||
while(m_size>start_range)
|
||||
{
|
||||
m_data[--m_size].~T();
|
||||
}
|
||||
}
|
||||
inline void clear_range(GUINT start_range)
|
||||
{
|
||||
while (m_size > start_range)
|
||||
{
|
||||
m_data[--m_size].~T();
|
||||
}
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
if(m_size==0)return;
|
||||
clear_range(0);
|
||||
}
|
||||
inline void clear()
|
||||
{
|
||||
if (m_size == 0) return;
|
||||
clear_range(0);
|
||||
}
|
||||
|
||||
inline void clear_memory()
|
||||
{
|
||||
clear();
|
||||
destroyData();
|
||||
}
|
||||
inline void clear_memory()
|
||||
{
|
||||
clear();
|
||||
destroyData();
|
||||
}
|
||||
|
||||
gim_array()
|
||||
{
|
||||
m_data = 0;
|
||||
m_size = 0;
|
||||
m_allocated_size = 0;
|
||||
}
|
||||
gim_array()
|
||||
{
|
||||
m_data = 0;
|
||||
m_size = 0;
|
||||
m_allocated_size = 0;
|
||||
}
|
||||
|
||||
gim_array(GUINT reservesize)
|
||||
{
|
||||
m_data = 0;
|
||||
m_size = 0;
|
||||
gim_array(GUINT reservesize)
|
||||
{
|
||||
m_data = 0;
|
||||
m_size = 0;
|
||||
|
||||
m_allocated_size = 0;
|
||||
reserve(reservesize);
|
||||
}
|
||||
m_allocated_size = 0;
|
||||
reserve(reservesize);
|
||||
}
|
||||
|
||||
~gim_array()
|
||||
{
|
||||
clear_memory();
|
||||
}
|
||||
~gim_array()
|
||||
{
|
||||
clear_memory();
|
||||
}
|
||||
|
||||
inline GUINT size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
inline GUINT size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline GUINT max_size() const
|
||||
{
|
||||
return m_allocated_size;
|
||||
}
|
||||
inline GUINT max_size() const
|
||||
{
|
||||
return m_allocated_size;
|
||||
}
|
||||
|
||||
inline T & operator[](size_t i)
|
||||
inline T& operator[](size_t i)
|
||||
{
|
||||
return m_data[i];
|
||||
}
|
||||
inline const T & operator[](size_t i) const
|
||||
inline const T& operator[](size_t i) const
|
||||
{
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
inline T * pointer(){ return m_data;}
|
||||
inline const T * pointer() const
|
||||
{ return m_data;}
|
||||
inline T* pointer() { return m_data; }
|
||||
inline const T* pointer() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
|
||||
inline T * get_pointer_at(GUINT i)
|
||||
inline T* get_pointer_at(GUINT i)
|
||||
{
|
||||
return m_data + i;
|
||||
}
|
||||
|
||||
inline const T * get_pointer_at(GUINT i) const
|
||||
inline const T* get_pointer_at(GUINT i) const
|
||||
{
|
||||
return m_data + i;
|
||||
}
|
||||
|
||||
inline T & at(GUINT i)
|
||||
inline T& at(GUINT i)
|
||||
{
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
inline const T & at(GUINT i) const
|
||||
inline const T& at(GUINT i) const
|
||||
{
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
inline T & front()
|
||||
inline T& front()
|
||||
{
|
||||
return *m_data;
|
||||
}
|
||||
|
||||
inline const T & front() const
|
||||
inline const T& front() const
|
||||
{
|
||||
return *m_data;
|
||||
}
|
||||
|
||||
inline T & back()
|
||||
inline T& back()
|
||||
{
|
||||
return m_data[m_size-1];
|
||||
return m_data[m_size - 1];
|
||||
}
|
||||
|
||||
inline const T & back() const
|
||||
inline const T& back() const
|
||||
{
|
||||
return m_data[m_size-1];
|
||||
return m_data[m_size - 1];
|
||||
}
|
||||
|
||||
|
||||
inline void swap(GUINT i, GUINT j)
|
||||
{
|
||||
gim_swap_elements(m_data,i,j);
|
||||
gim_swap_elements(m_data, i, j);
|
||||
}
|
||||
|
||||
inline void push_back(const T & obj)
|
||||
inline void push_back(const T& obj)
|
||||
{
|
||||
this->growingCheck();
|
||||
m_data[m_size] = obj;
|
||||
m_size++;
|
||||
this->growingCheck();
|
||||
m_data[m_size] = obj;
|
||||
m_size++;
|
||||
}
|
||||
|
||||
//!Simply increase the m_size, doesn't call the new element constructor
|
||||
inline void push_back_mem()
|
||||
{
|
||||
this->growingCheck();
|
||||
m_size++;
|
||||
this->growingCheck();
|
||||
m_size++;
|
||||
}
|
||||
|
||||
inline void push_back_memcpy(const T & obj)
|
||||
inline void push_back_memcpy(const T& obj)
|
||||
{
|
||||
this->growingCheck();
|
||||
gim_simd_memcpy(&m_data[m_size],&obj,sizeof(T));
|
||||
m_size++;
|
||||
this->growingCheck();
|
||||
gim_simd_memcpy(&m_data[m_size], &obj, sizeof(T));
|
||||
m_size++;
|
||||
}
|
||||
|
||||
inline void pop_back()
|
||||
{
|
||||
m_size--;
|
||||
m_data[m_size].~T();
|
||||
m_size--;
|
||||
m_data[m_size].~T();
|
||||
}
|
||||
|
||||
//!Simply decrease the m_size, doesn't call the deleted element destructor
|
||||
inline void pop_back_mem()
|
||||
{
|
||||
m_size--;
|
||||
m_size--;
|
||||
}
|
||||
|
||||
//! fast erase
|
||||
//! fast erase
|
||||
inline void erase(GUINT index)
|
||||
{
|
||||
if(index<m_size-1)
|
||||
{
|
||||
swap(index,m_size-1);
|
||||
}
|
||||
pop_back();
|
||||
if (index < m_size - 1)
|
||||
{
|
||||
swap(index, m_size - 1);
|
||||
}
|
||||
pop_back();
|
||||
}
|
||||
|
||||
inline void erase_sorted_mem(GUINT index)
|
||||
{
|
||||
m_size--;
|
||||
for(GUINT i = index;i<m_size;i++)
|
||||
{
|
||||
gim_simd_memcpy(m_data+i,m_data+i+1,sizeof(T));
|
||||
}
|
||||
m_size--;
|
||||
for (GUINT i = index; i < m_size; i++)
|
||||
{
|
||||
gim_simd_memcpy(m_data + i, m_data + i + 1, sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
inline void erase_sorted(GUINT index)
|
||||
{
|
||||
m_data[index].~T();
|
||||
erase_sorted_mem(index);
|
||||
m_data[index].~T();
|
||||
erase_sorted_mem(index);
|
||||
}
|
||||
|
||||
inline void insert_mem(GUINT index)
|
||||
{
|
||||
this->growingCheck();
|
||||
for(GUINT i = m_size;i>index;i--)
|
||||
{
|
||||
gim_simd_memcpy(m_data+i,m_data+i-1,sizeof(T));
|
||||
}
|
||||
m_size++;
|
||||
this->growingCheck();
|
||||
for (GUINT i = m_size; i > index; i--)
|
||||
{
|
||||
gim_simd_memcpy(m_data + i, m_data + i - 1, sizeof(T));
|
||||
}
|
||||
m_size++;
|
||||
}
|
||||
|
||||
inline void insert(const T & obj,GUINT index)
|
||||
inline void insert(const T& obj, GUINT index)
|
||||
{
|
||||
insert_mem(index);
|
||||
m_data[index] = obj;
|
||||
insert_mem(index);
|
||||
m_data[index] = obj;
|
||||
}
|
||||
|
||||
inline void resize(GUINT size, bool call_constructor = true, const T& fillData=T())
|
||||
inline void resize(GUINT size, bool call_constructor = true, const T& fillData = T())
|
||||
{
|
||||
if(size>m_size)
|
||||
{
|
||||
reserve(size);
|
||||
if(call_constructor)
|
||||
{
|
||||
while(m_size<size)
|
||||
{
|
||||
m_data[m_size] = fillData;
|
||||
m_size++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_size = size;
|
||||
}
|
||||
}
|
||||
else if(size<m_size)
|
||||
{
|
||||
if(call_constructor) clear_range(size);
|
||||
m_size = size;
|
||||
}
|
||||
if (size > m_size)
|
||||
{
|
||||
reserve(size);
|
||||
if (call_constructor)
|
||||
{
|
||||
while (m_size < size)
|
||||
{
|
||||
m_data[m_size] = fillData;
|
||||
m_size++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_size = size;
|
||||
}
|
||||
}
|
||||
else if (size < m_size)
|
||||
{
|
||||
if (call_constructor) clear_range(size);
|
||||
m_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
inline void refit()
|
||||
{
|
||||
resizeData(m_size);
|
||||
resizeData(m_size);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // GIM_CONTAINERS_H_INCLUDED
|
||||
#endif // GIM_CONTAINERS_H_INCLUDED
|
||||
|
||||
@@ -35,12 +35,8 @@ email: projectileman@yahoo.com
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "gim_linear_math.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef PLANEDIREPSILON
|
||||
#define PLANEDIREPSILON 0.0000001f
|
||||
#endif
|
||||
@@ -49,77 +45,82 @@ email: projectileman@yahoo.com
|
||||
#define PARALELENORMALS 0.000001f
|
||||
#endif
|
||||
|
||||
#define TRIANGLE_NORMAL(v1,v2,v3,n)\
|
||||
{\
|
||||
vec3f _dif1,_dif2;\
|
||||
VEC_DIFF(_dif1,v2,v1);\
|
||||
VEC_DIFF(_dif2,v3,v1);\
|
||||
VEC_CROSS(n,_dif1,_dif2);\
|
||||
VEC_NORMALIZE(n);\
|
||||
}\
|
||||
#define TRIANGLE_NORMAL(v1, v2, v3, n) \
|
||||
{ \
|
||||
vec3f _dif1, _dif2; \
|
||||
VEC_DIFF(_dif1, v2, v1); \
|
||||
VEC_DIFF(_dif2, v3, v1); \
|
||||
VEC_CROSS(n, _dif1, _dif2); \
|
||||
VEC_NORMALIZE(n); \
|
||||
}
|
||||
|
||||
#define TRIANGLE_NORMAL_FAST(v1,v2,v3,n){\
|
||||
vec3f _dif1,_dif2; \
|
||||
VEC_DIFF(_dif1,v2,v1); \
|
||||
VEC_DIFF(_dif2,v3,v1); \
|
||||
VEC_CROSS(n,_dif1,_dif2); \
|
||||
}\
|
||||
#define TRIANGLE_NORMAL_FAST(v1, v2, v3, n) \
|
||||
{ \
|
||||
vec3f _dif1, _dif2; \
|
||||
VEC_DIFF(_dif1, v2, v1); \
|
||||
VEC_DIFF(_dif2, v3, v1); \
|
||||
VEC_CROSS(n, _dif1, _dif2); \
|
||||
}
|
||||
|
||||
/// plane is a vec4f
|
||||
#define TRIANGLE_PLANE(v1,v2,v3,plane) {\
|
||||
TRIANGLE_NORMAL(v1,v2,v3,plane);\
|
||||
plane[3] = VEC_DOT(v1,plane);\
|
||||
}\
|
||||
#define TRIANGLE_PLANE(v1, v2, v3, plane) \
|
||||
{ \
|
||||
TRIANGLE_NORMAL(v1, v2, v3, plane); \
|
||||
plane[3] = VEC_DOT(v1, plane); \
|
||||
}
|
||||
|
||||
/// plane is a vec4f
|
||||
#define TRIANGLE_PLANE_FAST(v1,v2,v3,plane) {\
|
||||
TRIANGLE_NORMAL_FAST(v1,v2,v3,plane);\
|
||||
plane[3] = VEC_DOT(v1,plane);\
|
||||
}\
|
||||
#define TRIANGLE_PLANE_FAST(v1, v2, v3, plane) \
|
||||
{ \
|
||||
TRIANGLE_NORMAL_FAST(v1, v2, v3, plane); \
|
||||
plane[3] = VEC_DOT(v1, plane); \
|
||||
}
|
||||
|
||||
/// Calc a plane from an edge an a normal. plane is a vec4f
|
||||
#define EDGE_PLANE(e1,e2,n,plane) {\
|
||||
vec3f _dif; \
|
||||
VEC_DIFF(_dif,e2,e1); \
|
||||
VEC_CROSS(plane,_dif,n); \
|
||||
VEC_NORMALIZE(plane); \
|
||||
plane[3] = VEC_DOT(e1,plane);\
|
||||
}\
|
||||
#define EDGE_PLANE(e1, e2, n, plane) \
|
||||
{ \
|
||||
vec3f _dif; \
|
||||
VEC_DIFF(_dif, e2, e1); \
|
||||
VEC_CROSS(plane, _dif, n); \
|
||||
VEC_NORMALIZE(plane); \
|
||||
plane[3] = VEC_DOT(e1, plane); \
|
||||
}
|
||||
|
||||
#define DISTANCE_PLANE_POINT(plane,point) (VEC_DOT(plane,point) - plane[3])
|
||||
#define DISTANCE_PLANE_POINT(plane, point) (VEC_DOT(plane, point) - plane[3])
|
||||
|
||||
#define PROJECT_POINT_PLANE(point,plane,projected) {\
|
||||
GREAL _dis;\
|
||||
_dis = DISTANCE_PLANE_POINT(plane,point);\
|
||||
VEC_SCALE(projected,-_dis,plane);\
|
||||
VEC_SUM(projected,projected,point); \
|
||||
}\
|
||||
#define PROJECT_POINT_PLANE(point, plane, projected) \
|
||||
{ \
|
||||
GREAL _dis; \
|
||||
_dis = DISTANCE_PLANE_POINT(plane, point); \
|
||||
VEC_SCALE(projected, -_dis, plane); \
|
||||
VEC_SUM(projected, projected, point); \
|
||||
}
|
||||
|
||||
//! Verifies if a point is in the plane hull
|
||||
template<typename CLASS_POINT,typename CLASS_PLANE>
|
||||
template <typename CLASS_POINT, typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE bool POINT_IN_HULL(
|
||||
const CLASS_POINT& point,const CLASS_PLANE * planes,GUINT plane_count)
|
||||
const CLASS_POINT &point, const CLASS_PLANE *planes, GUINT plane_count)
|
||||
{
|
||||
GREAL _dis;
|
||||
for (GUINT _i = 0;_i< plane_count;++_i)
|
||||
for (GUINT _i = 0; _i < plane_count; ++_i)
|
||||
{
|
||||
_dis = DISTANCE_PLANE_POINT(planes[_i],point);
|
||||
if(_dis>0.0f) return false;
|
||||
_dis = DISTANCE_PLANE_POINT(planes[_i], point);
|
||||
if (_dis > 0.0f) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename CLASS_POINT,typename CLASS_PLANE>
|
||||
template <typename CLASS_POINT, typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE void PLANE_CLIP_SEGMENT(
|
||||
const CLASS_POINT& s1,
|
||||
const CLASS_POINT &s2,const CLASS_PLANE &plane,CLASS_POINT &clipped)
|
||||
const CLASS_POINT &s1,
|
||||
const CLASS_POINT &s2, const CLASS_PLANE &plane, CLASS_POINT &clipped)
|
||||
{
|
||||
GREAL _dis1,_dis2;
|
||||
_dis1 = DISTANCE_PLANE_POINT(plane,s1);
|
||||
VEC_DIFF(clipped,s2,s1);
|
||||
_dis2 = VEC_DOT(clipped,plane);
|
||||
VEC_SCALE(clipped,-_dis1/_dis2,clipped);
|
||||
VEC_SUM(clipped,clipped,s1);
|
||||
GREAL _dis1, _dis2;
|
||||
_dis1 = DISTANCE_PLANE_POINT(plane, s1);
|
||||
VEC_DIFF(clipped, s2, s1);
|
||||
_dis2 = VEC_DOT(clipped, plane);
|
||||
VEC_SCALE(clipped, -_dis1 / _dis2, clipped);
|
||||
VEC_SUM(clipped, clipped, s1);
|
||||
}
|
||||
|
||||
enum ePLANE_INTERSECTION_TYPE
|
||||
@@ -152,30 +153,30 @@ intersection type must have the following values
|
||||
</ul>
|
||||
*/
|
||||
|
||||
template<typename CLASS_POINT,typename CLASS_PLANE>
|
||||
template <typename CLASS_POINT, typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT2(
|
||||
const CLASS_POINT& s1,
|
||||
const CLASS_POINT &s1,
|
||||
const CLASS_POINT &s2,
|
||||
const CLASS_PLANE &plane,CLASS_POINT &clipped)
|
||||
const CLASS_PLANE &plane, CLASS_POINT &clipped)
|
||||
{
|
||||
GREAL _dis1 = DISTANCE_PLANE_POINT(plane,s1);
|
||||
GREAL _dis2 = DISTANCE_PLANE_POINT(plane,s2);
|
||||
if(_dis1 >-G_EPSILON && _dis2 >-G_EPSILON)
|
||||
GREAL _dis1 = DISTANCE_PLANE_POINT(plane, s1);
|
||||
GREAL _dis2 = DISTANCE_PLANE_POINT(plane, s2);
|
||||
if (_dis1 > -G_EPSILON && _dis2 > -G_EPSILON)
|
||||
{
|
||||
if(_dis1<_dis2) return G_FRONT_PLANE_S1;
|
||||
return G_FRONT_PLANE_S2;
|
||||
if (_dis1 < _dis2) return G_FRONT_PLANE_S1;
|
||||
return G_FRONT_PLANE_S2;
|
||||
}
|
||||
else if(_dis1 <G_EPSILON && _dis2 <G_EPSILON)
|
||||
else if (_dis1 < G_EPSILON && _dis2 < G_EPSILON)
|
||||
{
|
||||
if(_dis1>_dis2) return G_BACK_PLANE_S1;
|
||||
return G_BACK_PLANE_S2;
|
||||
if (_dis1 > _dis2) return G_BACK_PLANE_S1;
|
||||
return G_BACK_PLANE_S2;
|
||||
}
|
||||
|
||||
VEC_DIFF(clipped,s2,s1);
|
||||
_dis2 = VEC_DOT(clipped,plane);
|
||||
VEC_SCALE(clipped,-_dis1/_dis2,clipped);
|
||||
VEC_SUM(clipped,clipped,s1);
|
||||
if(_dis1<_dis2) return G_COLLIDE_PLANE_S1;
|
||||
VEC_DIFF(clipped, s2, s1);
|
||||
_dis2 = VEC_DOT(clipped, plane);
|
||||
VEC_SCALE(clipped, -_dis1 / _dis2, clipped);
|
||||
VEC_SUM(clipped, clipped, s1);
|
||||
if (_dis1 < _dis2) return G_COLLIDE_PLANE_S1;
|
||||
return G_COLLIDE_PLANE_S2;
|
||||
}
|
||||
|
||||
@@ -194,43 +195,42 @@ intersection_type must have the following values
|
||||
<li> 5 : Segment collides plane, s2 in back
|
||||
</ul>
|
||||
*/
|
||||
template<typename CLASS_POINT,typename CLASS_PLANE>
|
||||
template <typename CLASS_POINT, typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT_CLOSEST(
|
||||
const CLASS_POINT& s1,
|
||||
const CLASS_POINT &s1,
|
||||
const CLASS_POINT &s2,
|
||||
const CLASS_PLANE &plane,
|
||||
CLASS_POINT &clipped1,CLASS_POINT &clipped2)
|
||||
CLASS_POINT &clipped1, CLASS_POINT &clipped2)
|
||||
{
|
||||
eLINE_PLANE_INTERSECTION_TYPE intersection_type = PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped1);
|
||||
switch(intersection_type)
|
||||
eLINE_PLANE_INTERSECTION_TYPE intersection_type = PLANE_CLIP_SEGMENT2(s1, s2, plane, clipped1);
|
||||
switch (intersection_type)
|
||||
{
|
||||
case G_FRONT_PLANE_S1:
|
||||
VEC_COPY(clipped1,s1);
|
||||
VEC_COPY(clipped2,s2);
|
||||
break;
|
||||
case G_FRONT_PLANE_S2:
|
||||
VEC_COPY(clipped1,s2);
|
||||
VEC_COPY(clipped2,s1);
|
||||
break;
|
||||
case G_BACK_PLANE_S1:
|
||||
VEC_COPY(clipped1,s1);
|
||||
VEC_COPY(clipped2,s2);
|
||||
break;
|
||||
case G_BACK_PLANE_S2:
|
||||
VEC_COPY(clipped1,s2);
|
||||
VEC_COPY(clipped2,s1);
|
||||
break;
|
||||
case G_COLLIDE_PLANE_S1:
|
||||
VEC_COPY(clipped2,s1);
|
||||
break;
|
||||
case G_COLLIDE_PLANE_S2:
|
||||
VEC_COPY(clipped2,s2);
|
||||
break;
|
||||
case G_FRONT_PLANE_S1:
|
||||
VEC_COPY(clipped1, s1);
|
||||
VEC_COPY(clipped2, s2);
|
||||
break;
|
||||
case G_FRONT_PLANE_S2:
|
||||
VEC_COPY(clipped1, s2);
|
||||
VEC_COPY(clipped2, s1);
|
||||
break;
|
||||
case G_BACK_PLANE_S1:
|
||||
VEC_COPY(clipped1, s1);
|
||||
VEC_COPY(clipped2, s2);
|
||||
break;
|
||||
case G_BACK_PLANE_S2:
|
||||
VEC_COPY(clipped1, s2);
|
||||
VEC_COPY(clipped2, s1);
|
||||
break;
|
||||
case G_COLLIDE_PLANE_S1:
|
||||
VEC_COPY(clipped2, s1);
|
||||
break;
|
||||
case G_COLLIDE_PLANE_S2:
|
||||
VEC_COPY(clipped2, s2);
|
||||
break;
|
||||
}
|
||||
return intersection_type;
|
||||
}
|
||||
|
||||
|
||||
//! Finds the 2 smallest cartesian coordinates of a plane normal
|
||||
#define PLANE_MINOR_AXES(plane, i0, i1) VEC_MINOR_AXES(plane, i0, i1)
|
||||
|
||||
@@ -239,23 +239,23 @@ SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT_CLOSEST(
|
||||
Intersects plane in one way only. The ray must face the plane (normals must be in opossite directions).<br/>
|
||||
It uses the PLANEDIREPSILON constant.
|
||||
*/
|
||||
template<typename T,typename CLASS_POINT,typename CLASS_PLANE>
|
||||
template <typename T, typename CLASS_POINT, typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE bool RAY_PLANE_COLLISION(
|
||||
const CLASS_PLANE & plane,
|
||||
const CLASS_POINT & vDir,
|
||||
const CLASS_POINT & vPoint,
|
||||
CLASS_POINT & pout,T &tparam)
|
||||
const CLASS_PLANE &plane,
|
||||
const CLASS_POINT &vDir,
|
||||
const CLASS_POINT &vPoint,
|
||||
CLASS_POINT &pout, T &tparam)
|
||||
{
|
||||
GREAL _dis,_dotdir;
|
||||
_dotdir = VEC_DOT(plane,vDir);
|
||||
if(_dotdir<PLANEDIREPSILON)
|
||||
GREAL _dis, _dotdir;
|
||||
_dotdir = VEC_DOT(plane, vDir);
|
||||
if (_dotdir < PLANEDIREPSILON)
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
_dis = DISTANCE_PLANE_POINT(plane,vPoint);
|
||||
tparam = -_dis/_dotdir;
|
||||
VEC_SCALE(pout,tparam,vDir);
|
||||
VEC_SUM(pout,vPoint,pout);
|
||||
_dis = DISTANCE_PLANE_POINT(plane, vPoint);
|
||||
tparam = -_dis / _dotdir;
|
||||
VEC_SCALE(pout, tparam, vDir);
|
||||
VEC_SUM(pout, vPoint, pout);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -266,39 +266,39 @@ SIMD_FORCE_INLINE bool RAY_PLANE_COLLISION(
|
||||
-1 if the ray collides in front
|
||||
-2 if the ray collides in back
|
||||
*/
|
||||
template<typename T,typename CLASS_POINT,typename CLASS_PLANE>
|
||||
template <typename T, typename CLASS_POINT, typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE GUINT LINE_PLANE_COLLISION(
|
||||
const CLASS_PLANE & plane,
|
||||
const CLASS_POINT & vDir,
|
||||
const CLASS_POINT & vPoint,
|
||||
CLASS_POINT & pout,
|
||||
const CLASS_PLANE &plane,
|
||||
const CLASS_POINT &vDir,
|
||||
const CLASS_POINT &vPoint,
|
||||
CLASS_POINT &pout,
|
||||
T &tparam,
|
||||
T tmin, T tmax)
|
||||
{
|
||||
GREAL _dis,_dotdir;
|
||||
_dotdir = VEC_DOT(plane,vDir);
|
||||
if(btFabs(_dotdir)<PLANEDIREPSILON)
|
||||
GREAL _dis, _dotdir;
|
||||
_dotdir = VEC_DOT(plane, vDir);
|
||||
if (btFabs(_dotdir) < PLANEDIREPSILON)
|
||||
{
|
||||
tparam = tmax;
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
_dis = DISTANCE_PLANE_POINT(plane,vPoint);
|
||||
char returnvalue = _dis<0.0f?2:1;
|
||||
tparam = -_dis/_dotdir;
|
||||
_dis = DISTANCE_PLANE_POINT(plane, vPoint);
|
||||
char returnvalue = _dis < 0.0f ? 2 : 1;
|
||||
tparam = -_dis / _dotdir;
|
||||
|
||||
if(tparam<tmin)
|
||||
if (tparam < tmin)
|
||||
{
|
||||
returnvalue = 0;
|
||||
tparam = tmin;
|
||||
}
|
||||
else if(tparam>tmax)
|
||||
else if (tparam > tmax)
|
||||
{
|
||||
returnvalue = 0;
|
||||
tparam = tmax;
|
||||
}
|
||||
|
||||
VEC_SCALE(pout,tparam,vDir);
|
||||
VEC_SUM(pout,vPoint,pout);
|
||||
VEC_SCALE(pout, tparam, vDir);
|
||||
VEC_SUM(pout, vPoint, pout);
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
@@ -312,24 +312,24 @@ SIMD_FORCE_INLINE GUINT LINE_PLANE_COLLISION(
|
||||
\return true if the planes intersect, 0 if paralell.
|
||||
|
||||
*/
|
||||
template<typename CLASS_POINT,typename CLASS_PLANE>
|
||||
template <typename CLASS_POINT, typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE bool INTERSECT_PLANES(
|
||||
const CLASS_PLANE &p1,
|
||||
const CLASS_PLANE &p2,
|
||||
CLASS_POINT &p,
|
||||
CLASS_POINT &d)
|
||||
const CLASS_PLANE &p1,
|
||||
const CLASS_PLANE &p2,
|
||||
CLASS_POINT &p,
|
||||
CLASS_POINT &d)
|
||||
{
|
||||
VEC_CROSS(d,p1,p2);
|
||||
GREAL denom = VEC_DOT(d, d);
|
||||
if(GIM_IS_ZERO(denom)) return false;
|
||||
VEC_CROSS(d, p1, p2);
|
||||
GREAL denom = VEC_DOT(d, d);
|
||||
if (GIM_IS_ZERO(denom)) return false;
|
||||
vec3f _n;
|
||||
_n[0]=p1[3]*p2[0] - p2[3]*p1[0];
|
||||
_n[1]=p1[3]*p2[1] - p2[3]*p1[1];
|
||||
_n[2]=p1[3]*p2[2] - p2[3]*p1[2];
|
||||
VEC_CROSS(p,_n,d);
|
||||
p[0]/=denom;
|
||||
p[1]/=denom;
|
||||
p[2]/=denom;
|
||||
_n[0] = p1[3] * p2[0] - p2[3] * p1[0];
|
||||
_n[1] = p1[3] * p2[1] - p2[3] * p1[1];
|
||||
_n[2] = p1[3] * p2[2] - p2[3] * p1[2];
|
||||
VEC_CROSS(p, _n, d);
|
||||
p[0] /= denom;
|
||||
p[1] /= denom;
|
||||
p[2] /= denom;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -337,32 +337,31 @@ SIMD_FORCE_INLINE bool INTERSECT_PLANES(
|
||||
|
||||
/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
|
||||
*/
|
||||
template<typename CLASS_POINT>
|
||||
template <typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void CLOSEST_POINT_ON_SEGMENT(
|
||||
CLASS_POINT & cp, const CLASS_POINT & v,
|
||||
const CLASS_POINT &e1,const CLASS_POINT &e2)
|
||||
CLASS_POINT &cp, const CLASS_POINT &v,
|
||||
const CLASS_POINT &e1, const CLASS_POINT &e2)
|
||||
{
|
||||
vec3f _n;
|
||||
VEC_DIFF(_n,e2,e1);
|
||||
VEC_DIFF(cp,v,e1);
|
||||
vec3f _n;
|
||||
VEC_DIFF(_n, e2, e1);
|
||||
VEC_DIFF(cp, v, e1);
|
||||
GREAL _scalar = VEC_DOT(cp, _n);
|
||||
_scalar/= VEC_DOT(_n, _n);
|
||||
if(_scalar <0.0f)
|
||||
_scalar /= VEC_DOT(_n, _n);
|
||||
if (_scalar < 0.0f)
|
||||
{
|
||||
VEC_COPY(cp,e1);
|
||||
VEC_COPY(cp, e1);
|
||||
}
|
||||
else if(_scalar >1.0f)
|
||||
else if (_scalar > 1.0f)
|
||||
{
|
||||
VEC_COPY(cp,e2);
|
||||
VEC_COPY(cp, e2);
|
||||
}
|
||||
else
|
||||
{
|
||||
VEC_SCALE(cp,_scalar,_n);
|
||||
VEC_SUM(cp,cp,e1);
|
||||
VEC_SCALE(cp, _scalar, _n);
|
||||
VEC_SUM(cp, cp, e1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Finds the line params where these lines intersect.
|
||||
|
||||
\param dir1 Direction of line 1
|
||||
@@ -374,118 +373,114 @@ SIMD_FORCE_INLINE void CLOSEST_POINT_ON_SEGMENT(
|
||||
\param dointersect 0 if the lines won't intersect, else 1
|
||||
|
||||
*/
|
||||
template<typename T,typename CLASS_POINT>
|
||||
template <typename T, typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE bool LINE_INTERSECTION_PARAMS(
|
||||
const CLASS_POINT & dir1,
|
||||
CLASS_POINT & point1,
|
||||
const CLASS_POINT & dir2,
|
||||
CLASS_POINT & point2,
|
||||
T& t1,T& t2)
|
||||
const CLASS_POINT &dir1,
|
||||
CLASS_POINT &point1,
|
||||
const CLASS_POINT &dir2,
|
||||
CLASS_POINT &point2,
|
||||
T &t1, T &t2)
|
||||
{
|
||||
GREAL det;
|
||||
GREAL e1e1 = VEC_DOT(dir1,dir1);
|
||||
GREAL e1e2 = VEC_DOT(dir1,dir2);
|
||||
GREAL e2e2 = VEC_DOT(dir2,dir2);
|
||||
GREAL det;
|
||||
GREAL e1e1 = VEC_DOT(dir1, dir1);
|
||||
GREAL e1e2 = VEC_DOT(dir1, dir2);
|
||||
GREAL e2e2 = VEC_DOT(dir2, dir2);
|
||||
vec3f p1p2;
|
||||
VEC_DIFF(p1p2,point1,point2);
|
||||
GREAL p1p2e1 = VEC_DOT(p1p2,dir1);
|
||||
GREAL p1p2e2 = VEC_DOT(p1p2,dir2);
|
||||
det = e1e2*e1e2 - e1e1*e2e2;
|
||||
if(GIM_IS_ZERO(det)) return false;
|
||||
t1 = (e1e2*p1p2e2 - e2e2*p1p2e1)/det;
|
||||
t2 = (e1e1*p1p2e2 - e1e2*p1p2e1)/det;
|
||||
VEC_DIFF(p1p2, point1, point2);
|
||||
GREAL p1p2e1 = VEC_DOT(p1p2, dir1);
|
||||
GREAL p1p2e2 = VEC_DOT(p1p2, dir2);
|
||||
det = e1e2 * e1e2 - e1e1 * e2e2;
|
||||
if (GIM_IS_ZERO(det)) return false;
|
||||
t1 = (e1e2 * p1p2e2 - e2e2 * p1p2e1) / det;
|
||||
t2 = (e1e1 * p1p2e2 - e1e2 * p1p2e1) / det;
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Find closest points on segments
|
||||
template<typename CLASS_POINT>
|
||||
template <typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void SEGMENT_COLLISION(
|
||||
const CLASS_POINT & vA1,
|
||||
const CLASS_POINT & vA2,
|
||||
const CLASS_POINT & vB1,
|
||||
const CLASS_POINT & vB2,
|
||||
CLASS_POINT & vPointA,
|
||||
CLASS_POINT & vPointB)
|
||||
const CLASS_POINT &vA1,
|
||||
const CLASS_POINT &vA2,
|
||||
const CLASS_POINT &vB1,
|
||||
const CLASS_POINT &vB2,
|
||||
CLASS_POINT &vPointA,
|
||||
CLASS_POINT &vPointB)
|
||||
{
|
||||
CLASS_POINT _AD,_BD,n;
|
||||
vec4f _M;//plane
|
||||
VEC_DIFF(_AD,vA2,vA1);
|
||||
VEC_DIFF(_BD,vB2,vB1);
|
||||
VEC_CROSS(n,_AD,_BD);
|
||||
GREAL _tp = VEC_DOT(n,n);
|
||||
if(_tp<G_EPSILON)//ARE PARALELE
|
||||
{
|
||||
//project B over A
|
||||
bool invert_b_order = false;
|
||||
_M[0] = VEC_DOT(vB1,_AD);
|
||||
_M[1] = VEC_DOT(vB2,_AD);
|
||||
if(_M[0]>_M[1])
|
||||
{
|
||||
invert_b_order = true;
|
||||
GIM_SWAP_NUMBERS(_M[0],_M[1]);
|
||||
}
|
||||
_M[2] = VEC_DOT(vA1,_AD);
|
||||
_M[3] = VEC_DOT(vA2,_AD);
|
||||
//mid points
|
||||
n[0] = (_M[0]+_M[1])*0.5f;
|
||||
n[1] = (_M[2]+_M[3])*0.5f;
|
||||
CLASS_POINT _AD, _BD, n;
|
||||
vec4f _M; //plane
|
||||
VEC_DIFF(_AD, vA2, vA1);
|
||||
VEC_DIFF(_BD, vB2, vB1);
|
||||
VEC_CROSS(n, _AD, _BD);
|
||||
GREAL _tp = VEC_DOT(n, n);
|
||||
if (_tp < G_EPSILON) //ARE PARALELE
|
||||
{
|
||||
//project B over A
|
||||
bool invert_b_order = false;
|
||||
_M[0] = VEC_DOT(vB1, _AD);
|
||||
_M[1] = VEC_DOT(vB2, _AD);
|
||||
if (_M[0] > _M[1])
|
||||
{
|
||||
invert_b_order = true;
|
||||
GIM_SWAP_NUMBERS(_M[0], _M[1]);
|
||||
}
|
||||
_M[2] = VEC_DOT(vA1, _AD);
|
||||
_M[3] = VEC_DOT(vA2, _AD);
|
||||
//mid points
|
||||
n[0] = (_M[0] + _M[1]) * 0.5f;
|
||||
n[1] = (_M[2] + _M[3]) * 0.5f;
|
||||
|
||||
if(n[0]<n[1])
|
||||
{
|
||||
if(_M[1]<_M[2])
|
||||
{
|
||||
vPointB = invert_b_order?vB1:vB2;
|
||||
vPointA = vA1;
|
||||
}
|
||||
else if(_M[1]<_M[3])
|
||||
{
|
||||
vPointB = invert_b_order?vB1:vB2;
|
||||
CLOSEST_POINT_ON_SEGMENT(vPointA,vPointB,vA1,vA2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointA = vA2;
|
||||
CLOSEST_POINT_ON_SEGMENT(vPointB,vPointA,vB1,vB2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_M[3]<_M[0])
|
||||
{
|
||||
vPointB = invert_b_order?vB2:vB1;
|
||||
vPointA = vA2;
|
||||
}
|
||||
else if(_M[3]<_M[1])
|
||||
{
|
||||
vPointA = vA2;
|
||||
CLOSEST_POINT_ON_SEGMENT(vPointB,vPointA,vB1,vB2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointB = invert_b_order?vB1:vB2;
|
||||
CLOSEST_POINT_ON_SEGMENT(vPointA,vPointB,vA1,vA2);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (n[0] < n[1])
|
||||
{
|
||||
if (_M[1] < _M[2])
|
||||
{
|
||||
vPointB = invert_b_order ? vB1 : vB2;
|
||||
vPointA = vA1;
|
||||
}
|
||||
else if (_M[1] < _M[3])
|
||||
{
|
||||
vPointB = invert_b_order ? vB1 : vB2;
|
||||
CLOSEST_POINT_ON_SEGMENT(vPointA, vPointB, vA1, vA2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointA = vA2;
|
||||
CLOSEST_POINT_ON_SEGMENT(vPointB, vPointA, vB1, vB2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_M[3] < _M[0])
|
||||
{
|
||||
vPointB = invert_b_order ? vB2 : vB1;
|
||||
vPointA = vA2;
|
||||
}
|
||||
else if (_M[3] < _M[1])
|
||||
{
|
||||
vPointA = vA2;
|
||||
CLOSEST_POINT_ON_SEGMENT(vPointB, vPointA, vB1, vB2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointB = invert_b_order ? vB1 : vB2;
|
||||
CLOSEST_POINT_ON_SEGMENT(vPointA, vPointB, vA1, vA2);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VEC_CROSS(_M, n, _BD);
|
||||
_M[3] = VEC_DOT(_M, vB1);
|
||||
|
||||
VEC_CROSS(_M,n,_BD);
|
||||
_M[3] = VEC_DOT(_M,vB1);
|
||||
|
||||
LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,btScalar(0), btScalar(1));
|
||||
/*Closest point on segment*/
|
||||
VEC_DIFF(vPointB,vPointA,vB1);
|
||||
LINE_PLANE_COLLISION(_M, _AD, vA1, vPointA, _tp, btScalar(0), btScalar(1));
|
||||
/*Closest point on segment*/
|
||||
VEC_DIFF(vPointB, vPointA, vB1);
|
||||
_tp = VEC_DOT(vPointB, _BD);
|
||||
_tp/= VEC_DOT(_BD, _BD);
|
||||
_tp = GIM_CLAMP(_tp,0.0f,1.0f);
|
||||
VEC_SCALE(vPointB,_tp,_BD);
|
||||
VEC_SUM(vPointB,vPointB,vB1);
|
||||
_tp /= VEC_DOT(_BD, _BD);
|
||||
_tp = GIM_CLAMP(_tp, 0.0f, 1.0f);
|
||||
VEC_SCALE(vPointB, _tp, _BD);
|
||||
VEC_SUM(vPointB, vPointB, vB1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//! Line box intersection in one dimension
|
||||
/*!
|
||||
|
||||
@@ -497,37 +492,36 @@ SIMD_FORCE_INLINE void SEGMENT_COLLISION(
|
||||
*\param tlast the maximum projection. Assign to INFINITY at first.
|
||||
*\return true if there is an intersection.
|
||||
*/
|
||||
template<typename T>
|
||||
SIMD_FORCE_INLINE bool BOX_AXIS_INTERSECT(T pos, T dir,T bmin, T bmax, T & tfirst, T & tlast)
|
||||
template <typename T>
|
||||
SIMD_FORCE_INLINE bool BOX_AXIS_INTERSECT(T pos, T dir, T bmin, T bmax, T &tfirst, T &tlast)
|
||||
{
|
||||
if(GIM_IS_ZERO(dir))
|
||||
if (GIM_IS_ZERO(dir))
|
||||
{
|
||||
return !(pos < bmin || pos > bmax);
|
||||
return !(pos < bmin || pos > bmax);
|
||||
}
|
||||
GREAL a0 = (bmin - pos) / dir;
|
||||
GREAL a1 = (bmax - pos) / dir;
|
||||
if(a0 > a1) GIM_SWAP_NUMBERS(a0, a1);
|
||||
if (a0 > a1) GIM_SWAP_NUMBERS(a0, a1);
|
||||
tfirst = GIM_MAX(a0, tfirst);
|
||||
tlast = GIM_MIN(a1, tlast);
|
||||
if (tlast < tfirst) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! Sorts 3 componets
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
SIMD_FORCE_INLINE void SORT_3_INDICES(
|
||||
const T * values,
|
||||
GUINT * order_indices)
|
||||
const T *values,
|
||||
GUINT *order_indices)
|
||||
{
|
||||
//get minimum
|
||||
order_indices[0] = values[0] < values[1] ? (values[0] < values[2] ? 0 : 2) : (values[1] < values[2] ? 1 : 2);
|
||||
|
||||
//get second and third
|
||||
GUINT i0 = (order_indices[0] + 1)%3;
|
||||
GUINT i1 = (i0 + 1)%3;
|
||||
GUINT i0 = (order_indices[0] + 1) % 3;
|
||||
GUINT i1 = (i0 + 1) % 3;
|
||||
|
||||
if(values[i0] < values[i1])
|
||||
if (values[i0] < values[i1])
|
||||
{
|
||||
order_indices[1] = i0;
|
||||
order_indices[2] = i1;
|
||||
@@ -539,8 +533,4 @@ SIMD_FORCE_INLINE void SORT_3_INDICES(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // GIM_VECTOR_H_INCLUDED
|
||||
#endif // GIM_VECTOR_H_INCLUDED
|
||||
|
||||
@@ -34,34 +34,32 @@ email: projectileman@yahoo.com
|
||||
|
||||
#include "gim_array.h"
|
||||
|
||||
|
||||
#define GUINT_BIT_COUNT 32
|
||||
#define GUINT_EXPONENT 5
|
||||
|
||||
class gim_bitset
|
||||
{
|
||||
public:
|
||||
gim_array<GUINT> m_container;
|
||||
gim_array<GUINT> m_container;
|
||||
|
||||
gim_bitset()
|
||||
{
|
||||
gim_bitset()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
gim_bitset(GUINT bits_count)
|
||||
{
|
||||
resize(bits_count);
|
||||
}
|
||||
|
||||
gim_bitset(GUINT bits_count)
|
||||
{
|
||||
resize(bits_count);
|
||||
}
|
||||
|
||||
~gim_bitset()
|
||||
{
|
||||
}
|
||||
~gim_bitset()
|
||||
{
|
||||
}
|
||||
|
||||
inline bool resize(GUINT newsize)
|
||||
{
|
||||
GUINT oldsize = m_container.size();
|
||||
m_container.resize(newsize/GUINT_BIT_COUNT + 1,false);
|
||||
while(oldsize<m_container.size())
|
||||
m_container.resize(newsize / GUINT_BIT_COUNT + 1, false);
|
||||
while (oldsize < m_container.size())
|
||||
{
|
||||
m_container[oldsize] = 0;
|
||||
}
|
||||
@@ -70,12 +68,12 @@ public:
|
||||
|
||||
inline GUINT size()
|
||||
{
|
||||
return m_container.size()*GUINT_BIT_COUNT;
|
||||
return m_container.size() * GUINT_BIT_COUNT;
|
||||
}
|
||||
|
||||
inline void set_all()
|
||||
{
|
||||
for(GUINT i = 0;i<m_container.size();++i)
|
||||
for (GUINT i = 0; i < m_container.size(); ++i)
|
||||
{
|
||||
m_container[i] = 0xffffffff;
|
||||
}
|
||||
@@ -83,7 +81,7 @@ public:
|
||||
|
||||
inline void clear_all()
|
||||
{
|
||||
for(GUINT i = 0;i<m_container.size();++i)
|
||||
for (GUINT i = 0; i < m_container.size(); ++i)
|
||||
{
|
||||
m_container[i] = 0;
|
||||
}
|
||||
@@ -91,33 +89,29 @@ public:
|
||||
|
||||
inline void set(GUINT bit_index)
|
||||
{
|
||||
if(bit_index>=size())
|
||||
if (bit_index >= size())
|
||||
{
|
||||
resize(bit_index);
|
||||
}
|
||||
m_container[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT-1)));
|
||||
m_container[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT - 1)));
|
||||
}
|
||||
|
||||
///Return 0 or 1
|
||||
inline char get(GUINT bit_index)
|
||||
{
|
||||
if(bit_index>=size())
|
||||
if (bit_index >= size())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
char value = m_container[bit_index >> GUINT_EXPONENT] &
|
||||
(1 << (bit_index & (GUINT_BIT_COUNT-1)));
|
||||
(1 << (bit_index & (GUINT_BIT_COUNT - 1)));
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void clear(GUINT bit_index)
|
||||
{
|
||||
m_container[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT-1)));
|
||||
m_container[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT - 1)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // GIM_CONTAINERS_H_INCLUDED
|
||||
#endif // GIM_CONTAINERS_H_INCLUDED
|
||||
|
||||
@@ -35,8 +35,6 @@ email: projectileman@yahoo.com
|
||||
#include "gim_basic_geometry_operations.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
|
||||
|
||||
//SIMD_FORCE_INLINE bool test_cross_edge_box(
|
||||
// const btVector3 & edge,
|
||||
// const btVector3 & absolute_edge,
|
||||
@@ -99,52 +97,50 @@ email: projectileman@yahoo.com
|
||||
|
||||
#ifndef TEST_CROSS_EDGE_BOX_MCR
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\
|
||||
{\
|
||||
const btScalar dir0 = -edge[i_dir_0];\
|
||||
const btScalar dir1 = edge[i_dir_1];\
|
||||
btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\
|
||||
btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\
|
||||
if(pmin>pmax)\
|
||||
{\
|
||||
GIM_SWAP_NUMBERS(pmin,pmax); \
|
||||
}\
|
||||
const btScalar abs_dir0 = absolute_edge[i_dir_0];\
|
||||
const btScalar abs_dir1 = absolute_edge[i_dir_1];\
|
||||
const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\
|
||||
if(pmin>rad || -rad>pmax) return false;\
|
||||
}\
|
||||
#define TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, i_dir_0, i_dir_1, i_comp_0, i_comp_1) \
|
||||
{ \
|
||||
const btScalar dir0 = -edge[i_dir_0]; \
|
||||
const btScalar dir1 = edge[i_dir_1]; \
|
||||
btScalar pmin = pointa[i_comp_0] * dir0 + pointa[i_comp_1] * dir1; \
|
||||
btScalar pmax = pointb[i_comp_0] * dir0 + pointb[i_comp_1] * dir1; \
|
||||
if (pmin > pmax) \
|
||||
{ \
|
||||
GIM_SWAP_NUMBERS(pmin, pmax); \
|
||||
} \
|
||||
const btScalar abs_dir0 = absolute_edge[i_dir_0]; \
|
||||
const btScalar abs_dir1 = absolute_edge[i_dir_1]; \
|
||||
const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1; \
|
||||
if (pmin > rad || -rad > pmax) return false; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
|
||||
{\
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\
|
||||
}\
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
|
||||
{\
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\
|
||||
}\
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
|
||||
{\
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\
|
||||
}\
|
||||
#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \
|
||||
{ \
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 2, 1, 1, 2); \
|
||||
}
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \
|
||||
{ \
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 0, 2, 2, 0); \
|
||||
}
|
||||
|
||||
#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \
|
||||
{ \
|
||||
TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 1, 0, 0, 1); \
|
||||
}
|
||||
|
||||
//! Class for transforming a model1 to the space of model0
|
||||
class GIM_BOX_BOX_TRANSFORM_CACHE
|
||||
{
|
||||
public:
|
||||
btVector3 m_T1to0;//!< Transforms translation of model1 to model 0
|
||||
btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1
|
||||
btMatrix3x3 m_AR;//!< Absolute value of m_R1to0
|
||||
btVector3 m_T1to0; //!< Transforms translation of model1 to model 0
|
||||
btMatrix3x3 m_R1to0; //!< Transforms Rotation of model1 to model 0, equal to R0' * R1
|
||||
btMatrix3x3 m_AR; //!< Absolute value of m_R1to0
|
||||
|
||||
SIMD_FORCE_INLINE void calc_absolute_matrix()
|
||||
{
|
||||
static const btVector3 vepsi(1e-6f,1e-6f,1e-6f);
|
||||
static const btVector3 vepsi(1e-6f, 1e-6f, 1e-6f);
|
||||
m_AR[0] = vepsi + m_R1to0[0].absolute();
|
||||
m_AR[1] = vepsi + m_R1to0[1].absolute();
|
||||
m_AR[2] = vepsi + m_R1to0[2].absolute();
|
||||
@@ -154,42 +150,40 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GIM_BOX_BOX_TRANSFORM_CACHE(mat4f trans1_to_0)
|
||||
GIM_BOX_BOX_TRANSFORM_CACHE(mat4f trans1_to_0)
|
||||
{
|
||||
COPY_MATRIX_3X3(m_R1to0,trans1_to_0)
|
||||
MAT_GET_TRANSLATION(trans1_to_0,m_T1to0)
|
||||
COPY_MATRIX_3X3(m_R1to0, trans1_to_0)
|
||||
MAT_GET_TRANSLATION(trans1_to_0, m_T1to0)
|
||||
calc_absolute_matrix();
|
||||
}
|
||||
|
||||
//! Calc the transformation relative 1 to 0. Inverts matrics by transposing
|
||||
SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1)
|
||||
SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform &trans0, const btTransform &trans1)
|
||||
{
|
||||
|
||||
m_R1to0 = trans0.getBasis().transpose();
|
||||
m_T1to0 = m_R1to0 * (-trans0.getOrigin());
|
||||
|
||||
m_T1to0 += m_R1to0*trans1.getOrigin();
|
||||
m_T1to0 += m_R1to0 * trans1.getOrigin();
|
||||
m_R1to0 *= trans1.getBasis();
|
||||
|
||||
calc_absolute_matrix();
|
||||
}
|
||||
|
||||
//! Calcs the full invertion of the matrices. Useful for scaling matrices
|
||||
SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1)
|
||||
SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform &trans0, const btTransform &trans1)
|
||||
{
|
||||
m_R1to0 = trans0.getBasis().inverse();
|
||||
m_T1to0 = m_R1to0 * (-trans0.getOrigin());
|
||||
|
||||
m_T1to0 += m_R1to0*trans1.getOrigin();
|
||||
m_T1to0 += m_R1to0 * trans1.getOrigin();
|
||||
m_R1to0 *= trans1.getBasis();
|
||||
|
||||
calc_absolute_matrix();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point)
|
||||
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point)
|
||||
{
|
||||
return point.dot3(m_R1to0[0], m_R1to0[1], m_R1to0[2]) + m_T1to0;
|
||||
return point.dot3(m_R1to0[0], m_R1to0[1], m_R1to0[2]) + m_T1to0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -205,34 +199,34 @@ public:
|
||||
btVector3 m_max;
|
||||
|
||||
GIM_AABB()
|
||||
{}
|
||||
|
||||
|
||||
GIM_AABB(const btVector3 & V1,
|
||||
const btVector3 & V2,
|
||||
const btVector3 & V3)
|
||||
{
|
||||
m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
|
||||
m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
|
||||
m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
|
||||
|
||||
m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
|
||||
m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
|
||||
m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
|
||||
}
|
||||
|
||||
GIM_AABB(const btVector3 & V1,
|
||||
const btVector3 & V2,
|
||||
const btVector3 & V3,
|
||||
GIM_AABB(const btVector3 &V1,
|
||||
const btVector3 &V2,
|
||||
const btVector3 &V3)
|
||||
{
|
||||
m_min[0] = GIM_MIN3(V1[0], V2[0], V3[0]);
|
||||
m_min[1] = GIM_MIN3(V1[1], V2[1], V3[1]);
|
||||
m_min[2] = GIM_MIN3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_max[0] = GIM_MAX3(V1[0], V2[0], V3[0]);
|
||||
m_max[1] = GIM_MAX3(V1[1], V2[1], V3[1]);
|
||||
m_max[2] = GIM_MAX3(V1[2], V2[2], V3[2]);
|
||||
}
|
||||
|
||||
GIM_AABB(const btVector3 &V1,
|
||||
const btVector3 &V2,
|
||||
const btVector3 &V3,
|
||||
GREAL margin)
|
||||
{
|
||||
m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
|
||||
m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
|
||||
m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
|
||||
m_min[0] = GIM_MIN3(V1[0], V2[0], V3[0]);
|
||||
m_min[1] = GIM_MIN3(V1[1], V2[1], V3[1]);
|
||||
m_min[2] = GIM_MIN3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
|
||||
m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
|
||||
m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
|
||||
m_max[0] = GIM_MAX3(V1[0], V2[0], V3[0]);
|
||||
m_max[1] = GIM_MAX3(V1[1], V2[1], V3[1]);
|
||||
m_max[2] = GIM_MAX3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_min[0] -= margin;
|
||||
m_min[1] -= margin;
|
||||
@@ -242,13 +236,11 @@ public:
|
||||
m_max[2] += margin;
|
||||
}
|
||||
|
||||
GIM_AABB(const GIM_AABB &other):
|
||||
m_min(other.m_min),m_max(other.m_max)
|
||||
GIM_AABB(const GIM_AABB &other) : m_min(other.m_min), m_max(other.m_max)
|
||||
{
|
||||
}
|
||||
|
||||
GIM_AABB(const GIM_AABB &other,btScalar margin ):
|
||||
m_min(other.m_min),m_max(other.m_max)
|
||||
GIM_AABB(const GIM_AABB &other, btScalar margin) : m_min(other.m_min), m_max(other.m_max)
|
||||
{
|
||||
m_min[0] -= margin;
|
||||
m_min[1] -= margin;
|
||||
@@ -289,34 +281,34 @@ public:
|
||||
m_max[2] = other.m_max[2] + margin;
|
||||
}
|
||||
|
||||
template<typename CLASS_POINT>
|
||||
template <typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void calc_from_triangle(
|
||||
const CLASS_POINT & V1,
|
||||
const CLASS_POINT & V2,
|
||||
const CLASS_POINT & V3)
|
||||
const CLASS_POINT &V1,
|
||||
const CLASS_POINT &V2,
|
||||
const CLASS_POINT &V3)
|
||||
{
|
||||
m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
|
||||
m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
|
||||
m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
|
||||
m_min[0] = GIM_MIN3(V1[0], V2[0], V3[0]);
|
||||
m_min[1] = GIM_MIN3(V1[1], V2[1], V3[1]);
|
||||
m_min[2] = GIM_MIN3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
|
||||
m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
|
||||
m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
|
||||
m_max[0] = GIM_MAX3(V1[0], V2[0], V3[0]);
|
||||
m_max[1] = GIM_MAX3(V1[1], V2[1], V3[1]);
|
||||
m_max[2] = GIM_MAX3(V1[2], V2[2], V3[2]);
|
||||
}
|
||||
|
||||
template<typename CLASS_POINT>
|
||||
template <typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void calc_from_triangle_margin(
|
||||
const CLASS_POINT & V1,
|
||||
const CLASS_POINT & V2,
|
||||
const CLASS_POINT & V3, btScalar margin)
|
||||
const CLASS_POINT &V1,
|
||||
const CLASS_POINT &V2,
|
||||
const CLASS_POINT &V3, btScalar margin)
|
||||
{
|
||||
m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
|
||||
m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
|
||||
m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
|
||||
m_min[0] = GIM_MIN3(V1[0], V2[0], V3[0]);
|
||||
m_min[1] = GIM_MIN3(V1[1], V2[1], V3[1]);
|
||||
m_min[2] = GIM_MIN3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
|
||||
m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
|
||||
m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
|
||||
m_max[0] = GIM_MAX3(V1[0], V2[0], V3[0]);
|
||||
m_max[1] = GIM_MAX3(V1[1], V2[1], V3[1]);
|
||||
m_max[2] = GIM_MAX3(V1[2], V2[2], V3[2]);
|
||||
|
||||
m_min[0] -= margin;
|
||||
m_min[1] -= margin;
|
||||
@@ -327,74 +319,73 @@ public:
|
||||
}
|
||||
|
||||
//! Apply a transform to an AABB
|
||||
SIMD_FORCE_INLINE void appy_transform(const btTransform & trans)
|
||||
SIMD_FORCE_INLINE void appy_transform(const btTransform &trans)
|
||||
{
|
||||
btVector3 center = (m_max+m_min)*0.5f;
|
||||
btVector3 center = (m_max + m_min) * 0.5f;
|
||||
btVector3 extends = m_max - center;
|
||||
// Compute new center
|
||||
center = trans(center);
|
||||
|
||||
btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(),
|
||||
trans.getBasis().getRow(1).absolute(),
|
||||
trans.getBasis().getRow(2).absolute());
|
||||
|
||||
btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(),
|
||||
trans.getBasis().getRow(1).absolute(),
|
||||
trans.getBasis().getRow(2).absolute());
|
||||
|
||||
m_min = center - textends;
|
||||
m_max = center + textends;
|
||||
}
|
||||
|
||||
//! Merges a Box
|
||||
SIMD_FORCE_INLINE void merge(const GIM_AABB & box)
|
||||
SIMD_FORCE_INLINE void merge(const GIM_AABB &box)
|
||||
{
|
||||
m_min[0] = GIM_MIN(m_min[0],box.m_min[0]);
|
||||
m_min[1] = GIM_MIN(m_min[1],box.m_min[1]);
|
||||
m_min[2] = GIM_MIN(m_min[2],box.m_min[2]);
|
||||
m_min[0] = GIM_MIN(m_min[0], box.m_min[0]);
|
||||
m_min[1] = GIM_MIN(m_min[1], box.m_min[1]);
|
||||
m_min[2] = GIM_MIN(m_min[2], box.m_min[2]);
|
||||
|
||||
m_max[0] = GIM_MAX(m_max[0],box.m_max[0]);
|
||||
m_max[1] = GIM_MAX(m_max[1],box.m_max[1]);
|
||||
m_max[2] = GIM_MAX(m_max[2],box.m_max[2]);
|
||||
m_max[0] = GIM_MAX(m_max[0], box.m_max[0]);
|
||||
m_max[1] = GIM_MAX(m_max[1], box.m_max[1]);
|
||||
m_max[2] = GIM_MAX(m_max[2], box.m_max[2]);
|
||||
}
|
||||
|
||||
//! Merges a point
|
||||
template<typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point)
|
||||
template <typename CLASS_POINT>
|
||||
SIMD_FORCE_INLINE void merge_point(const CLASS_POINT &point)
|
||||
{
|
||||
m_min[0] = GIM_MIN(m_min[0],point[0]);
|
||||
m_min[1] = GIM_MIN(m_min[1],point[1]);
|
||||
m_min[2] = GIM_MIN(m_min[2],point[2]);
|
||||
m_min[0] = GIM_MIN(m_min[0], point[0]);
|
||||
m_min[1] = GIM_MIN(m_min[1], point[1]);
|
||||
m_min[2] = GIM_MIN(m_min[2], point[2]);
|
||||
|
||||
m_max[0] = GIM_MAX(m_max[0],point[0]);
|
||||
m_max[1] = GIM_MAX(m_max[1],point[1]);
|
||||
m_max[2] = GIM_MAX(m_max[2],point[2]);
|
||||
m_max[0] = GIM_MAX(m_max[0], point[0]);
|
||||
m_max[1] = GIM_MAX(m_max[1], point[1]);
|
||||
m_max[2] = GIM_MAX(m_max[2], point[2]);
|
||||
}
|
||||
|
||||
//! Gets the extend and center
|
||||
SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend) const
|
||||
SIMD_FORCE_INLINE void get_center_extend(btVector3 ¢er, btVector3 &extend) const
|
||||
{
|
||||
center = (m_max+m_min)*0.5f;
|
||||
center = (m_max + m_min) * 0.5f;
|
||||
extend = m_max - center;
|
||||
}
|
||||
|
||||
//! Finds the intersecting box between this box and the other.
|
||||
SIMD_FORCE_INLINE void find_intersection(const GIM_AABB & other, GIM_AABB & intersection) const
|
||||
SIMD_FORCE_INLINE void find_intersection(const GIM_AABB &other, GIM_AABB &intersection) const
|
||||
{
|
||||
intersection.m_min[0] = GIM_MAX(other.m_min[0],m_min[0]);
|
||||
intersection.m_min[1] = GIM_MAX(other.m_min[1],m_min[1]);
|
||||
intersection.m_min[2] = GIM_MAX(other.m_min[2],m_min[2]);
|
||||
intersection.m_min[0] = GIM_MAX(other.m_min[0], m_min[0]);
|
||||
intersection.m_min[1] = GIM_MAX(other.m_min[1], m_min[1]);
|
||||
intersection.m_min[2] = GIM_MAX(other.m_min[2], m_min[2]);
|
||||
|
||||
intersection.m_max[0] = GIM_MIN(other.m_max[0],m_max[0]);
|
||||
intersection.m_max[1] = GIM_MIN(other.m_max[1],m_max[1]);
|
||||
intersection.m_max[2] = GIM_MIN(other.m_max[2],m_max[2]);
|
||||
intersection.m_max[0] = GIM_MIN(other.m_max[0], m_max[0]);
|
||||
intersection.m_max[1] = GIM_MIN(other.m_max[1], m_max[1]);
|
||||
intersection.m_max[2] = GIM_MIN(other.m_max[2], m_max[2]);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool has_collision(const GIM_AABB & other) const
|
||||
SIMD_FORCE_INLINE bool has_collision(const GIM_AABB &other) const
|
||||
{
|
||||
if(m_min[0] > other.m_max[0] ||
|
||||
m_max[0] < other.m_min[0] ||
|
||||
m_min[1] > other.m_max[1] ||
|
||||
m_max[1] < other.m_min[1] ||
|
||||
m_min[2] > other.m_max[2] ||
|
||||
m_max[2] < other.m_min[2])
|
||||
if (m_min[0] > other.m_max[0] ||
|
||||
m_max[0] < other.m_min[0] ||
|
||||
m_min[1] > other.m_max[1] ||
|
||||
m_max[1] < other.m_min[1] ||
|
||||
m_min[2] > other.m_max[2] ||
|
||||
m_max[2] < other.m_min[2])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -406,35 +397,34 @@ public:
|
||||
\param vorigin A vec3f with the origin of the ray
|
||||
\param vdir A vec3f with the direction of the ray
|
||||
*/
|
||||
SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir)
|
||||
SIMD_FORCE_INLINE bool collide_ray(const btVector3 &vorigin, const btVector3 &vdir)
|
||||
{
|
||||
btVector3 extents,center;
|
||||
this->get_center_extend(center,extents);;
|
||||
btVector3 extents, center;
|
||||
this->get_center_extend(center, extents);
|
||||
;
|
||||
|
||||
btScalar Dx = vorigin[0] - center[0];
|
||||
if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return false;
|
||||
if (GIM_GREATER(Dx, extents[0]) && Dx * vdir[0] >= 0.0f) return false;
|
||||
btScalar Dy = vorigin[1] - center[1];
|
||||
if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return false;
|
||||
if (GIM_GREATER(Dy, extents[1]) && Dy * vdir[1] >= 0.0f) return false;
|
||||
btScalar Dz = vorigin[2] - center[2];
|
||||
if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return false;
|
||||
|
||||
if (GIM_GREATER(Dz, extents[2]) && Dz * vdir[2] >= 0.0f) return false;
|
||||
|
||||
btScalar f = vdir[1] * Dz - vdir[2] * Dy;
|
||||
if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false;
|
||||
if (btFabs(f) > extents[1] * btFabs(vdir[2]) + extents[2] * btFabs(vdir[1])) return false;
|
||||
f = vdir[2] * Dx - vdir[0] * Dz;
|
||||
if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false;
|
||||
if (btFabs(f) > extents[0] * btFabs(vdir[2]) + extents[2] * btFabs(vdir[0])) return false;
|
||||
f = vdir[0] * Dy - vdir[1] * Dx;
|
||||
if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false;
|
||||
if (btFabs(f) > extents[0] * btFabs(vdir[1]) + extents[1] * btFabs(vdir[0])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const
|
||||
SIMD_FORCE_INLINE void projection_interval(const btVector3 &direction, btScalar &vmin, btScalar &vmax) const
|
||||
{
|
||||
btVector3 center = (m_max+m_min)*0.5f;
|
||||
btVector3 extend = m_max-center;
|
||||
btVector3 center = (m_max + m_min) * 0.5f;
|
||||
btVector3 extend = m_max - center;
|
||||
|
||||
btScalar _fOrigin = direction.dot(center);
|
||||
btScalar _fOrigin = direction.dot(center);
|
||||
btScalar _fMaximumExtent = extend.dot(direction.absolute());
|
||||
vmin = _fOrigin - _fMaximumExtent;
|
||||
vmax = _fOrigin + _fMaximumExtent;
|
||||
@@ -442,22 +432,22 @@ public:
|
||||
|
||||
SIMD_FORCE_INLINE ePLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const
|
||||
{
|
||||
btScalar _fmin,_fmax;
|
||||
this->projection_interval(plane,_fmin,_fmax);
|
||||
btScalar _fmin, _fmax;
|
||||
this->projection_interval(plane, _fmin, _fmax);
|
||||
|
||||
if(plane[3] > _fmax + BOX_PLANE_EPSILON)
|
||||
if (plane[3] > _fmax + BOX_PLANE_EPSILON)
|
||||
{
|
||||
return G_BACK_PLANE; // 0
|
||||
return G_BACK_PLANE; // 0
|
||||
}
|
||||
|
||||
if(plane[3]+BOX_PLANE_EPSILON >=_fmin)
|
||||
if (plane[3] + BOX_PLANE_EPSILON >= _fmin)
|
||||
{
|
||||
return G_COLLIDE_PLANE; //1
|
||||
return G_COLLIDE_PLANE; //1
|
||||
}
|
||||
return G_FRONT_PLANE;//2
|
||||
return G_FRONT_PLANE; //2
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool overlapping_trans_conservative(const GIM_AABB & box, btTransform & trans1_to_0)
|
||||
SIMD_FORCE_INLINE bool overlapping_trans_conservative(const GIM_AABB &box, btTransform &trans1_to_0)
|
||||
{
|
||||
GIM_AABB tbox = box;
|
||||
tbox.appy_transform(trans1_to_0);
|
||||
@@ -466,52 +456,50 @@ public:
|
||||
|
||||
//! transcache is the transformation cache from box to this AABB
|
||||
SIMD_FORCE_INLINE bool overlapping_trans_cache(
|
||||
const GIM_AABB & box,const GIM_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest)
|
||||
const GIM_AABB &box, const GIM_BOX_BOX_TRANSFORM_CACHE &transcache, bool fulltest)
|
||||
{
|
||||
|
||||
//Taken from OPCODE
|
||||
btVector3 ea,eb;//extends
|
||||
btVector3 ca,cb;//extends
|
||||
get_center_extend(ca,ea);
|
||||
box.get_center_extend(cb,eb);
|
||||
|
||||
btVector3 ea, eb; //extends
|
||||
btVector3 ca, cb; //extends
|
||||
get_center_extend(ca, ea);
|
||||
box.get_center_extend(cb, eb);
|
||||
|
||||
btVector3 T;
|
||||
btScalar t,t2;
|
||||
btScalar t, t2;
|
||||
int i;
|
||||
|
||||
// Class I : A's basis vectors
|
||||
for(i=0;i<3;i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i];
|
||||
T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i];
|
||||
t = transcache.m_AR[i].dot(eb) + ea[i];
|
||||
if(GIM_GREATER(T[i], t)) return false;
|
||||
if (GIM_GREATER(T[i], t)) return false;
|
||||
}
|
||||
// Class II : B's basis vectors
|
||||
for(i=0;i<3;i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
t = MAT_DOT_COL(transcache.m_R1to0,T,i);
|
||||
t2 = MAT_DOT_COL(transcache.m_AR,ea,i) + eb[i];
|
||||
if(GIM_GREATER(t,t2)) return false;
|
||||
t = MAT_DOT_COL(transcache.m_R1to0, T, i);
|
||||
t2 = MAT_DOT_COL(transcache.m_AR, ea, i) + eb[i];
|
||||
if (GIM_GREATER(t, t2)) return false;
|
||||
}
|
||||
// Class III : 9 cross products
|
||||
if(fulltest)
|
||||
if (fulltest)
|
||||
{
|
||||
int j,m,n,o,p,q,r;
|
||||
for(i=0;i<3;i++)
|
||||
int j, m, n, o, p, q, r;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
m = (i+1)%3;
|
||||
n = (i+2)%3;
|
||||
o = i==0?1:0;
|
||||
p = i==2?1:2;
|
||||
for(j=0;j<3;j++)
|
||||
m = (i + 1) % 3;
|
||||
n = (i + 2) % 3;
|
||||
o = i == 0 ? 1 : 0;
|
||||
p = i == 2 ? 1 : 2;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
q = j==2?1:2;
|
||||
r = j==0?1:0;
|
||||
t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j];
|
||||
t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] +
|
||||
eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r];
|
||||
if(GIM_GREATER(t,t2)) return false;
|
||||
q = j == 2 ? 1 : 2;
|
||||
r = j == 0 ? 1 : 0;
|
||||
t = T[n] * transcache.m_R1to0[m][j] - T[m] * transcache.m_R1to0[n][j];
|
||||
t2 = ea[o] * transcache.m_AR[p][j] + ea[p] * transcache.m_AR[o][j] +
|
||||
eb[r] * transcache.m_AR[i][q] + eb[q] * transcache.m_AR[i][r];
|
||||
if (GIM_GREATER(t, t2)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,7 +508,7 @@ public:
|
||||
|
||||
//! Simple test for planes.
|
||||
SIMD_FORCE_INLINE bool collide_plane(
|
||||
const btVector4 & plane)
|
||||
const btVector4 &plane)
|
||||
{
|
||||
ePLANE_INTERSECTION_TYPE classify = plane_classify(plane);
|
||||
return (classify == G_COLLIDE_PLANE);
|
||||
@@ -528,15 +516,15 @@ public:
|
||||
|
||||
//! test for a triangle, with edges
|
||||
SIMD_FORCE_INLINE bool collide_triangle_exact(
|
||||
const btVector3 & p1,
|
||||
const btVector3 & p2,
|
||||
const btVector3 & p3,
|
||||
const btVector4 & triangle_plane)
|
||||
const btVector3 &p1,
|
||||
const btVector3 &p2,
|
||||
const btVector3 &p3,
|
||||
const btVector4 &triangle_plane)
|
||||
{
|
||||
if(!collide_plane(triangle_plane)) return false;
|
||||
if (!collide_plane(triangle_plane)) return false;
|
||||
|
||||
btVector3 center,extends;
|
||||
this->get_center_extend(center,extends);
|
||||
btVector3 center, extends;
|
||||
this->get_center_extend(center, extends);
|
||||
|
||||
const btVector3 v1(p1 - center);
|
||||
const btVector3 v2(p2 - center);
|
||||
@@ -546,30 +534,29 @@ public:
|
||||
btVector3 diff(v2 - v1);
|
||||
btVector3 abs_diff = diff.absolute();
|
||||
//Test With X axis
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends);
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v1, v3, extends);
|
||||
//Test With Y axis
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends);
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v1, v3, extends);
|
||||
//Test With Z axis
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends);
|
||||
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v1, v3, extends);
|
||||
|
||||
diff = v3 - v2;
|
||||
abs_diff = diff.absolute();
|
||||
//Test With X axis
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends);
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v2, v1, extends);
|
||||
//Test With Y axis
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends);
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v2, v1, extends);
|
||||
//Test With Z axis
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends);
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v2, v1, extends);
|
||||
|
||||
diff = v1 - v3;
|
||||
abs_diff = diff.absolute();
|
||||
//Test With X axis
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends);
|
||||
TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v3, v2, extends);
|
||||
//Test With Y axis
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends);
|
||||
TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v3, v2, extends);
|
||||
//Test With Z axis
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends);
|
||||
TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v3, v2, extends);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -577,17 +564,15 @@ public:
|
||||
|
||||
#ifndef BT_BOX_COLLISION_H_INCLUDED
|
||||
//! Compairison of transformation objects
|
||||
SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2)
|
||||
SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform &t1, const btTransform &t2)
|
||||
{
|
||||
if(!(t1.getOrigin() == t2.getOrigin()) ) return false;
|
||||
if (!(t1.getOrigin() == t2.getOrigin())) return false;
|
||||
|
||||
if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false;
|
||||
if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false;
|
||||
if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false;
|
||||
if (!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0))) return false;
|
||||
if (!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1))) return false;
|
||||
if (!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2))) return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // GIM_BOX_COLLISION_H_INCLUDED
|
||||
#endif // GIM_BOX_COLLISION_H_INCLUDED
|
||||
|
||||
@@ -28,67 +28,64 @@ email: projectileman@yahoo.com
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "gim_box_set.h"
|
||||
|
||||
|
||||
GUINT GIM_BOX_TREE::_calc_splitting_axis(
|
||||
gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex, GUINT endIndex)
|
||||
gim_array<GIM_AABB_DATA>& primitive_boxes, GUINT startIndex, GUINT endIndex)
|
||||
{
|
||||
GUINT i;
|
||||
|
||||
btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
GUINT numIndices = endIndex-startIndex;
|
||||
btVector3 means(btScalar(0.), btScalar(0.), btScalar(0.));
|
||||
btVector3 variance(btScalar(0.), btScalar(0.), btScalar(0.));
|
||||
GUINT numIndices = endIndex - startIndex;
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means+=center;
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
means += center;
|
||||
}
|
||||
means *= (btScalar(1.)/(btScalar)numIndices);
|
||||
means *= (btScalar(1.) / (btScalar)numIndices);
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
btVector3 diff2 = center-means;
|
||||
btVector3 center = btScalar(0.5) * (primitive_boxes[i].m_bound.m_max +
|
||||
primitive_boxes[i].m_bound.m_min);
|
||||
btVector3 diff2 = center - means;
|
||||
diff2 = diff2 * diff2;
|
||||
variance += diff2;
|
||||
}
|
||||
variance *= (btScalar(1.)/ ((btScalar)numIndices-1) );
|
||||
variance *= (btScalar(1.) / ((btScalar)numIndices - 1));
|
||||
|
||||
return variance.maxAxis();
|
||||
}
|
||||
|
||||
|
||||
GUINT GIM_BOX_TREE::_sort_and_calc_splitting_index(
|
||||
gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex,
|
||||
gim_array<GIM_AABB_DATA>& primitive_boxes, GUINT startIndex,
|
||||
GUINT endIndex, GUINT splitAxis)
|
||||
{
|
||||
GUINT i;
|
||||
GUINT splitIndex =startIndex;
|
||||
GUINT splitIndex = startIndex;
|
||||
GUINT numIndices = endIndex - startIndex;
|
||||
|
||||
// average of centers
|
||||
btScalar splitValue = 0.0f;
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
splitValue+= 0.5f*(primitive_boxes[i].m_bound.m_max[splitAxis] +
|
||||
primitive_boxes[i].m_bound.m_min[splitAxis]);
|
||||
splitValue += 0.5f * (primitive_boxes[i].m_bound.m_max[splitAxis] +
|
||||
primitive_boxes[i].m_bound.m_min[splitAxis]);
|
||||
}
|
||||
splitValue /= (btScalar)numIndices;
|
||||
|
||||
//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
for (i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
btScalar center = 0.5f*(primitive_boxes[i].m_bound.m_max[splitAxis] +
|
||||
primitive_boxes[i].m_bound.m_min[splitAxis]);
|
||||
btScalar center = 0.5f * (primitive_boxes[i].m_bound.m_max[splitAxis] +
|
||||
primitive_boxes[i].m_bound.m_min[splitAxis]);
|
||||
if (center > splitValue)
|
||||
{
|
||||
//swap
|
||||
primitive_boxes.swap(i,splitIndex);
|
||||
primitive_boxes.swap(i, splitIndex);
|
||||
splitIndex++;
|
||||
}
|
||||
}
|
||||
@@ -102,28 +99,27 @@ GUINT GIM_BOX_TREE::_sort_and_calc_splitting_index(
|
||||
//bool unbalanced2 = true;
|
||||
|
||||
//this should be safe too:
|
||||
GUINT rangeBalancedIndices = numIndices/3;
|
||||
bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
|
||||
GUINT rangeBalancedIndices = numIndices / 3;
|
||||
bool unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices)));
|
||||
|
||||
if (unbalanced)
|
||||
{
|
||||
splitIndex = startIndex+ (numIndices>>1);
|
||||
splitIndex = startIndex + (numIndices >> 1);
|
||||
}
|
||||
|
||||
btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
|
||||
btAssert(!((splitIndex == startIndex) || (splitIndex == (endIndex))));
|
||||
|
||||
return splitIndex;
|
||||
}
|
||||
|
||||
|
||||
void GIM_BOX_TREE::_build_sub_tree(gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex, GUINT endIndex)
|
||||
void GIM_BOX_TREE::_build_sub_tree(gim_array<GIM_AABB_DATA>& primitive_boxes, GUINT startIndex, GUINT endIndex)
|
||||
{
|
||||
GUINT current_index = m_num_nodes++;
|
||||
|
||||
btAssert((endIndex-startIndex)>0);
|
||||
btAssert((endIndex - startIndex) > 0);
|
||||
|
||||
if((endIndex-startIndex) == 1) //we got a leaf
|
||||
{
|
||||
if ((endIndex - startIndex) == 1) //we got a leaf
|
||||
{
|
||||
m_node_array[current_index].m_left = 0;
|
||||
m_node_array[current_index].m_right = 0;
|
||||
m_node_array[current_index].m_escapeIndex = 0;
|
||||
@@ -138,8 +134,8 @@ void GIM_BOX_TREE::_build_sub_tree(gim_array<GIM_AABB_DATA> & primitive_boxes, G
|
||||
GUINT splitIndex;
|
||||
|
||||
//calc this node bounding box
|
||||
m_node_array[current_index].m_bound.invalidate();
|
||||
for (splitIndex=startIndex;splitIndex<endIndex;splitIndex++)
|
||||
m_node_array[current_index].m_bound.invalidate();
|
||||
for (splitIndex = startIndex; splitIndex < endIndex; splitIndex++)
|
||||
{
|
||||
m_node_array[current_index].m_bound.merge(primitive_boxes[splitIndex].m_bound);
|
||||
}
|
||||
@@ -147,36 +143,34 @@ void GIM_BOX_TREE::_build_sub_tree(gim_array<GIM_AABB_DATA> & primitive_boxes, G
|
||||
//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
|
||||
|
||||
//split axis
|
||||
splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex);
|
||||
splitIndex = _calc_splitting_axis(primitive_boxes, startIndex, endIndex);
|
||||
|
||||
splitIndex = _sort_and_calc_splitting_index(
|
||||
primitive_boxes,startIndex,endIndex,splitIndex);
|
||||
primitive_boxes, startIndex, endIndex, splitIndex);
|
||||
|
||||
//configure this inner node : the left node index
|
||||
m_node_array[current_index].m_left = m_num_nodes;
|
||||
//build left child tree
|
||||
_build_sub_tree(primitive_boxes, startIndex, splitIndex );
|
||||
_build_sub_tree(primitive_boxes, startIndex, splitIndex);
|
||||
|
||||
//configure this inner node : the right node index
|
||||
m_node_array[current_index].m_right = m_num_nodes;
|
||||
|
||||
//build right child tree
|
||||
_build_sub_tree(primitive_boxes, splitIndex ,endIndex);
|
||||
_build_sub_tree(primitive_boxes, splitIndex, endIndex);
|
||||
|
||||
//configure this inner node : the escape index
|
||||
m_node_array[current_index].m_escapeIndex = m_num_nodes - current_index;
|
||||
m_node_array[current_index].m_escapeIndex = m_num_nodes - current_index;
|
||||
}
|
||||
|
||||
//! stackless build tree
|
||||
void GIM_BOX_TREE::build_tree(
|
||||
gim_array<GIM_AABB_DATA> & primitive_boxes)
|
||||
gim_array<GIM_AABB_DATA>& primitive_boxes)
|
||||
{
|
||||
// initialize node count to 0
|
||||
m_num_nodes = 0;
|
||||
// allocate nodes
|
||||
m_node_array.resize(primitive_boxes.size()*2);
|
||||
|
||||
m_node_array.resize(primitive_boxes.size() * 2);
|
||||
|
||||
_build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,54 +33,51 @@ email: projectileman@yahoo.com
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "gim_array.h"
|
||||
#include "gim_radixsort.h"
|
||||
#include "gim_box_collision.h"
|
||||
#include "gim_tri_collision.h"
|
||||
|
||||
|
||||
|
||||
//! Overlapping pair
|
||||
struct GIM_PAIR
|
||||
{
|
||||
GUINT m_index1;
|
||||
GUINT m_index2;
|
||||
GIM_PAIR()
|
||||
{}
|
||||
GUINT m_index1;
|
||||
GUINT m_index2;
|
||||
GIM_PAIR()
|
||||
{
|
||||
}
|
||||
|
||||
GIM_PAIR(const GIM_PAIR & p)
|
||||
{
|
||||
m_index1 = p.m_index1;
|
||||
m_index2 = p.m_index2;
|
||||
GIM_PAIR(const GIM_PAIR& p)
|
||||
{
|
||||
m_index1 = p.m_index1;
|
||||
m_index2 = p.m_index2;
|
||||
}
|
||||
|
||||
GIM_PAIR(GUINT index1, GUINT index2)
|
||||
{
|
||||
m_index1 = index1;
|
||||
m_index2 = index2;
|
||||
{
|
||||
m_index1 = index1;
|
||||
m_index2 = index2;
|
||||
}
|
||||
};
|
||||
|
||||
//! A pairset array
|
||||
class gim_pair_set: public gim_array<GIM_PAIR>
|
||||
class gim_pair_set : public gim_array<GIM_PAIR>
|
||||
{
|
||||
public:
|
||||
gim_pair_set():gim_array<GIM_PAIR>(32)
|
||||
gim_pair_set() : gim_array<GIM_PAIR>(32)
|
||||
{
|
||||
}
|
||||
inline void push_pair(GUINT index1,GUINT index2)
|
||||
inline void push_pair(GUINT index1, GUINT index2)
|
||||
{
|
||||
push_back(GIM_PAIR(index1,index2));
|
||||
push_back(GIM_PAIR(index1, index2));
|
||||
}
|
||||
|
||||
inline void push_pair_inv(GUINT index1,GUINT index2)
|
||||
inline void push_pair_inv(GUINT index1, GUINT index2)
|
||||
{
|
||||
push_back(GIM_PAIR(index2,index1));
|
||||
push_back(GIM_PAIR(index2, index1));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! Prototype Base class for primitive classification
|
||||
/*!
|
||||
This class is a wrapper for primitive collections.
|
||||
@@ -90,16 +87,14 @@ This class can manage Compound shapes and trimeshes, and if it is managing trime
|
||||
class GIM_PRIMITIVE_MANAGER_PROTOTYPE
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~GIM_PRIMITIVE_MANAGER_PROTOTYPE() {}
|
||||
//! determines if this manager consist on only triangles, which special case will be optimized
|
||||
virtual bool is_trimesh() = 0;
|
||||
virtual GUINT get_primitive_count() = 0;
|
||||
virtual void get_primitive_box(GUINT prim_index ,GIM_AABB & primbox) = 0;
|
||||
virtual void get_primitive_triangle(GUINT prim_index,GIM_TRIANGLE & triangle) = 0;
|
||||
virtual void get_primitive_box(GUINT prim_index, GIM_AABB& primbox) = 0;
|
||||
virtual void get_primitive_triangle(GUINT prim_index, GIM_TRIANGLE& triangle) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct GIM_AABB_DATA
|
||||
{
|
||||
GIM_AABB m_bound;
|
||||
@@ -110,22 +105,22 @@ struct GIM_AABB_DATA
|
||||
struct GIM_BOX_TREE_NODE
|
||||
{
|
||||
GIM_AABB m_bound;
|
||||
GUINT m_left;//!< Left subtree
|
||||
GUINT m_right;//!< Right subtree
|
||||
GUINT m_escapeIndex;//!< Scape index for traversing
|
||||
GUINT m_data;//!< primitive index if apply
|
||||
GUINT m_left; //!< Left subtree
|
||||
GUINT m_right; //!< Right subtree
|
||||
GUINT m_escapeIndex; //!< Scape index for traversing
|
||||
GUINT m_data; //!< primitive index if apply
|
||||
|
||||
GIM_BOX_TREE_NODE()
|
||||
{
|
||||
m_left = 0;
|
||||
m_right = 0;
|
||||
m_escapeIndex = 0;
|
||||
m_data = 0;
|
||||
m_left = 0;
|
||||
m_right = 0;
|
||||
m_escapeIndex = 0;
|
||||
m_data = 0;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool is_leaf_node() const
|
||||
{
|
||||
return (!m_left && !m_right);
|
||||
return (!m_left && !m_right);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -135,14 +130,16 @@ class GIM_BOX_TREE
|
||||
protected:
|
||||
GUINT m_num_nodes;
|
||||
gim_array<GIM_BOX_TREE_NODE> m_node_array;
|
||||
|
||||
protected:
|
||||
GUINT _sort_and_calc_splitting_index(
|
||||
gim_array<GIM_AABB_DATA> & primitive_boxes,
|
||||
GUINT startIndex, GUINT endIndex, GUINT splitAxis);
|
||||
gim_array<GIM_AABB_DATA>& primitive_boxes,
|
||||
GUINT startIndex, GUINT endIndex, GUINT splitAxis);
|
||||
|
||||
GUINT _calc_splitting_axis(gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex, GUINT endIndex);
|
||||
GUINT _calc_splitting_axis(gim_array<GIM_AABB_DATA>& primitive_boxes, GUINT startIndex, GUINT endIndex);
|
||||
|
||||
void _build_sub_tree(gim_array<GIM_AABB_DATA>& primitive_boxes, GUINT startIndex, GUINT endIndex);
|
||||
|
||||
void _build_sub_tree(gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex, GUINT endIndex);
|
||||
public:
|
||||
GIM_BOX_TREE()
|
||||
{
|
||||
@@ -151,7 +148,7 @@ public:
|
||||
|
||||
//! prototype functions for box tree management
|
||||
//!@{
|
||||
void build_tree(gim_array<GIM_AABB_DATA> & primitive_boxes);
|
||||
void build_tree(gim_array<GIM_AABB_DATA>& primitive_boxes);
|
||||
|
||||
SIMD_FORCE_INLINE void clearNodes()
|
||||
{
|
||||
@@ -176,22 +173,22 @@ public:
|
||||
return m_node_array[nodeindex].m_data;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB & bound) const
|
||||
SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB& bound) const
|
||||
{
|
||||
bound = m_node_array[nodeindex].m_bound;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB & bound)
|
||||
SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB& bound)
|
||||
{
|
||||
m_node_array[nodeindex].m_bound = bound;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE GUINT getLeftNodeIndex(GUINT nodeindex) const
|
||||
SIMD_FORCE_INLINE GUINT getLeftNodeIndex(GUINT nodeindex) const
|
||||
{
|
||||
return m_node_array[nodeindex].m_left;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE GUINT getRightNodeIndex(GUINT nodeindex) const
|
||||
SIMD_FORCE_INLINE GUINT getRightNodeIndex(GUINT nodeindex) const
|
||||
{
|
||||
return m_node_array[nodeindex].m_right;
|
||||
}
|
||||
@@ -204,78 +201,78 @@ public:
|
||||
//!@}
|
||||
};
|
||||
|
||||
|
||||
//! Generic Box Tree Template
|
||||
/*!
|
||||
This class offers an structure for managing a box tree of primitives.
|
||||
Requires a Primitive prototype (like GIM_PRIMITIVE_MANAGER_PROTOTYPE ) and
|
||||
a Box tree structure ( like GIM_BOX_TREE).
|
||||
*/
|
||||
template<typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE, typename _GIM_BOX_TREE_PROTOTYPE>
|
||||
template <typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE, typename _GIM_BOX_TREE_PROTOTYPE>
|
||||
class GIM_BOX_TREE_TEMPLATE_SET
|
||||
{
|
||||
protected:
|
||||
_GIM_PRIMITIVE_MANAGER_PROTOTYPE m_primitive_manager;
|
||||
_GIM_BOX_TREE_PROTOTYPE m_box_tree;
|
||||
|
||||
protected:
|
||||
//stackless refit
|
||||
SIMD_FORCE_INLINE void refit()
|
||||
{
|
||||
GUINT nodecount = getNodeCount();
|
||||
while(nodecount--)
|
||||
while (nodecount--)
|
||||
{
|
||||
if(isLeafNode(nodecount))
|
||||
if (isLeafNode(nodecount))
|
||||
{
|
||||
GIM_AABB leafbox;
|
||||
m_primitive_manager.get_primitive_box(getNodeData(nodecount),leafbox);
|
||||
setNodeBound(nodecount,leafbox);
|
||||
m_primitive_manager.get_primitive_box(getNodeData(nodecount), leafbox);
|
||||
setNodeBound(nodecount, leafbox);
|
||||
}
|
||||
else
|
||||
{
|
||||
//get left bound
|
||||
GUINT childindex = getLeftNodeIndex(nodecount);
|
||||
GIM_AABB bound;
|
||||
getNodeBound(childindex,bound);
|
||||
getNodeBound(childindex, bound);
|
||||
//get right bound
|
||||
childindex = getRightNodeIndex(nodecount);
|
||||
GIM_AABB bound2;
|
||||
getNodeBound(childindex,bound2);
|
||||
getNodeBound(childindex, bound2);
|
||||
bound.merge(bound2);
|
||||
|
||||
setNodeBound(nodecount,bound);
|
||||
setNodeBound(nodecount, bound);
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
||||
public:
|
||||
GIM_BOX_TREE_TEMPLATE_SET()
|
||||
{
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE GIM_AABB getGlobalBox() const
|
||||
SIMD_FORCE_INLINE GIM_AABB getGlobalBox() const
|
||||
{
|
||||
GIM_AABB totalbox;
|
||||
getNodeBound(0, totalbox);
|
||||
return totalbox;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setPrimitiveManager(const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & primitive_manager)
|
||||
SIMD_FORCE_INLINE void setPrimitiveManager(const _GIM_PRIMITIVE_MANAGER_PROTOTYPE& primitive_manager)
|
||||
{
|
||||
m_primitive_manager = primitive_manager;
|
||||
}
|
||||
|
||||
const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager() const
|
||||
const _GIM_PRIMITIVE_MANAGER_PROTOTYPE& getPrimitiveManager() const
|
||||
{
|
||||
return m_primitive_manager;
|
||||
}
|
||||
|
||||
_GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager()
|
||||
_GIM_PRIMITIVE_MANAGER_PROTOTYPE& getPrimitiveManager()
|
||||
{
|
||||
return m_primitive_manager;
|
||||
}
|
||||
|
||||
//! node manager prototype functions
|
||||
///@{
|
||||
//! node manager prototype functions
|
||||
///@{
|
||||
|
||||
//! this attemps to refit the box set.
|
||||
SIMD_FORCE_INLINE void update()
|
||||
@@ -288,19 +285,19 @@ public:
|
||||
{
|
||||
//obtain primitive boxes
|
||||
gim_array<GIM_AABB_DATA> primitive_boxes;
|
||||
primitive_boxes.resize(m_primitive_manager.get_primitive_count(),false);
|
||||
primitive_boxes.resize(m_primitive_manager.get_primitive_count(), false);
|
||||
|
||||
for (GUINT i = 0;i<primitive_boxes.size() ;i++ )
|
||||
for (GUINT i = 0; i < primitive_boxes.size(); i++)
|
||||
{
|
||||
m_primitive_manager.get_primitive_box(i,primitive_boxes[i].m_bound);
|
||||
primitive_boxes[i].m_data = i;
|
||||
m_primitive_manager.get_primitive_box(i, primitive_boxes[i].m_bound);
|
||||
primitive_boxes[i].m_data = i;
|
||||
}
|
||||
|
||||
m_box_tree.build_tree(primitive_boxes);
|
||||
}
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
SIMD_FORCE_INLINE bool boxQuery(const GIM_AABB & box, gim_array<GUINT> & collided_results) const
|
||||
SIMD_FORCE_INLINE bool boxQuery(const GIM_AABB& box, gim_array<GUINT>& collided_results) const
|
||||
{
|
||||
GUINT curIndex = 0;
|
||||
GUINT numNodes = getNodeCount();
|
||||
@@ -308,7 +305,7 @@ public:
|
||||
while (curIndex < numNodes)
|
||||
{
|
||||
GIM_AABB bound;
|
||||
getNodeBound(curIndex,bound);
|
||||
getNodeBound(curIndex, bound);
|
||||
|
||||
//catch bugs in tree data
|
||||
|
||||
@@ -328,26 +325,26 @@ public:
|
||||
else
|
||||
{
|
||||
//skip node
|
||||
curIndex+= getScapeNodeIndex(curIndex);
|
||||
curIndex += getScapeNodeIndex(curIndex);
|
||||
}
|
||||
}
|
||||
if(collided_results.size()>0) return true;
|
||||
if (collided_results.size() > 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
SIMD_FORCE_INLINE bool boxQueryTrans(const GIM_AABB & box,
|
||||
const btTransform & transform, gim_array<GUINT> & collided_results) const
|
||||
SIMD_FORCE_INLINE bool boxQueryTrans(const GIM_AABB& box,
|
||||
const btTransform& transform, gim_array<GUINT>& collided_results) const
|
||||
{
|
||||
GIM_AABB transbox=box;
|
||||
GIM_AABB transbox = box;
|
||||
transbox.appy_transform(transform);
|
||||
return boxQuery(transbox,collided_results);
|
||||
return boxQuery(transbox, collided_results);
|
||||
}
|
||||
|
||||
//! returns the indices of the primitives in the m_primitive_manager
|
||||
SIMD_FORCE_INLINE bool rayQuery(
|
||||
const btVector3 & ray_dir,const btVector3 & ray_origin ,
|
||||
gim_array<GUINT> & collided_results) const
|
||||
const btVector3& ray_dir, const btVector3& ray_origin,
|
||||
gim_array<GUINT>& collided_results) const
|
||||
{
|
||||
GUINT curIndex = 0;
|
||||
GUINT numNodes = getNodeCount();
|
||||
@@ -355,16 +352,16 @@ public:
|
||||
while (curIndex < numNodes)
|
||||
{
|
||||
GIM_AABB bound;
|
||||
getNodeBound(curIndex,bound);
|
||||
getNodeBound(curIndex, bound);
|
||||
|
||||
//catch bugs in tree data
|
||||
|
||||
bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir);
|
||||
bool aabbOverlap = bound.collide_ray(ray_origin, ray_dir);
|
||||
bool isleafnode = isLeafNode(curIndex);
|
||||
|
||||
if (isleafnode && aabbOverlap)
|
||||
{
|
||||
collided_results.push_back(getNodeData( curIndex));
|
||||
collided_results.push_back(getNodeData(curIndex));
|
||||
}
|
||||
|
||||
if (aabbOverlap || isleafnode)
|
||||
@@ -375,10 +372,10 @@ public:
|
||||
else
|
||||
{
|
||||
//skip node
|
||||
curIndex+= getScapeNodeIndex(curIndex);
|
||||
curIndex += getScapeNodeIndex(curIndex);
|
||||
}
|
||||
}
|
||||
if(collided_results.size()>0) return true;
|
||||
if (collided_results.size() > 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -389,7 +386,7 @@ public:
|
||||
}
|
||||
|
||||
//! tells if this set is a trimesh
|
||||
SIMD_FORCE_INLINE bool isTrimesh() const
|
||||
SIMD_FORCE_INLINE bool isTrimesh() const
|
||||
{
|
||||
return m_primitive_manager.is_trimesh();
|
||||
}
|
||||
@@ -411,12 +408,12 @@ public:
|
||||
return m_box_tree.getNodeData(nodeindex);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB & bound) const
|
||||
SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB& bound) const
|
||||
{
|
||||
m_box_tree.getNodeBound(nodeindex, bound);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB & bound)
|
||||
SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB& bound)
|
||||
{
|
||||
m_box_tree.setNodeBound(nodeindex, bound);
|
||||
}
|
||||
@@ -436,36 +433,30 @@ public:
|
||||
return m_box_tree.getScapeNodeIndex(nodeindex);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void getNodeTriangle(GUINT nodeindex,GIM_TRIANGLE & triangle) const
|
||||
SIMD_FORCE_INLINE void getNodeTriangle(GUINT nodeindex, GIM_TRIANGLE& triangle) const
|
||||
{
|
||||
m_primitive_manager.get_primitive_triangle(getNodeData(nodeindex),triangle);
|
||||
m_primitive_manager.get_primitive_triangle(getNodeData(nodeindex), triangle);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//! Class for Box Tree Sets
|
||||
/*!
|
||||
this has the GIM_BOX_TREE implementation for bounding boxes.
|
||||
*/
|
||||
template<typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE>
|
||||
class GIM_BOX_TREE_SET: public GIM_BOX_TREE_TEMPLATE_SET< _GIM_PRIMITIVE_MANAGER_PROTOTYPE, GIM_BOX_TREE>
|
||||
template <typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE>
|
||||
class GIM_BOX_TREE_SET : public GIM_BOX_TREE_TEMPLATE_SET<_GIM_PRIMITIVE_MANAGER_PROTOTYPE, GIM_BOX_TREE>
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// GIM_BOX_SET collision methods
|
||||
template<typename BOX_SET_CLASS0,typename BOX_SET_CLASS1>
|
||||
template <typename BOX_SET_CLASS0, typename BOX_SET_CLASS1>
|
||||
class GIM_TREE_TREE_COLLIDER
|
||||
{
|
||||
public:
|
||||
gim_pair_set * m_collision_pairs;
|
||||
BOX_SET_CLASS0 * m_boxset0;
|
||||
BOX_SET_CLASS1 * m_boxset1;
|
||||
gim_pair_set* m_collision_pairs;
|
||||
BOX_SET_CLASS0* m_boxset0;
|
||||
BOX_SET_CLASS1* m_boxset1;
|
||||
GUINT current_node0;
|
||||
GUINT current_node1;
|
||||
bool node0_is_leaf;
|
||||
@@ -483,18 +474,18 @@ public:
|
||||
GIM_TRIANGLE m_tri1;
|
||||
btVector4 m_tri1_plane;
|
||||
|
||||
|
||||
public:
|
||||
GIM_TREE_TREE_COLLIDER()
|
||||
{
|
||||
current_node0 = G_UINT_INFINITY;
|
||||
current_node1 = G_UINT_INFINITY;
|
||||
}
|
||||
|
||||
protected:
|
||||
SIMD_FORCE_INLINE void retrieve_node0_triangle(GUINT node0)
|
||||
{
|
||||
if(node0_has_triangle) return;
|
||||
m_boxset0->getNodeTriangle(node0,m_tri0);
|
||||
if (node0_has_triangle) return;
|
||||
m_boxset0->getNodeTriangle(node0, m_tri0);
|
||||
//transform triangle
|
||||
m_tri0.m_vertices[0] = trans_cache_0to1(m_tri0.m_vertices[0]);
|
||||
m_tri0.m_vertices[1] = trans_cache_0to1(m_tri0.m_vertices[1]);
|
||||
@@ -506,8 +497,8 @@ protected:
|
||||
|
||||
SIMD_FORCE_INLINE void retrieve_node1_triangle(GUINT node1)
|
||||
{
|
||||
if(node1_has_triangle) return;
|
||||
m_boxset1->getNodeTriangle(node1,m_tri1);
|
||||
if (node1_has_triangle) return;
|
||||
m_boxset1->getNodeTriangle(node1, m_tri1);
|
||||
//transform triangle
|
||||
m_tri1.m_vertices[0] = trans_cache_1to0.transform(m_tri1.m_vertices[0]);
|
||||
m_tri1.m_vertices[1] = trans_cache_1to0.transform(m_tri1.m_vertices[1]);
|
||||
@@ -519,8 +510,8 @@ protected:
|
||||
|
||||
SIMD_FORCE_INLINE void retrieve_node0_info(GUINT node0)
|
||||
{
|
||||
if(node0 == current_node0) return;
|
||||
m_boxset0->getNodeBound(node0,m_box0);
|
||||
if (node0 == current_node0) return;
|
||||
m_boxset0->getNodeBound(node0, m_box0);
|
||||
node0_is_leaf = m_boxset0->isLeafNode(node0);
|
||||
node0_has_triangle = false;
|
||||
current_node0 = node0;
|
||||
@@ -528,21 +519,21 @@ protected:
|
||||
|
||||
SIMD_FORCE_INLINE void retrieve_node1_info(GUINT node1)
|
||||
{
|
||||
if(node1 == current_node1) return;
|
||||
m_boxset1->getNodeBound(node1,m_box1);
|
||||
if (node1 == current_node1) return;
|
||||
m_boxset1->getNodeBound(node1, m_box1);
|
||||
node1_is_leaf = m_boxset1->isLeafNode(node1);
|
||||
node1_has_triangle = false;
|
||||
current_node1 = node1;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool node_collision(GUINT node0 ,GUINT node1)
|
||||
SIMD_FORCE_INLINE bool node_collision(GUINT node0, GUINT node1)
|
||||
{
|
||||
retrieve_node0_info(node0);
|
||||
retrieve_node1_info(node1);
|
||||
bool result = m_box0.overlapping_trans_cache(m_box1,trans_cache_1to0,true);
|
||||
if(!result) return false;
|
||||
bool result = m_box0.overlapping_trans_cache(m_box1, trans_cache_1to0, true);
|
||||
if (!result) return false;
|
||||
|
||||
if(t0_is_trimesh && node0_is_leaf)
|
||||
if (t0_is_trimesh && node0_is_leaf)
|
||||
{
|
||||
//perform primitive vs box collision
|
||||
retrieve_node0_triangle(node0);
|
||||
@@ -550,14 +541,14 @@ protected:
|
||||
m_box1.increment_margin(m_tri0.m_margin);
|
||||
|
||||
result = m_box1.collide_triangle_exact(
|
||||
m_tri0.m_vertices[0],m_tri0.m_vertices[1],m_tri0.m_vertices[2],m_tri0_plane);
|
||||
m_tri0.m_vertices[0], m_tri0.m_vertices[1], m_tri0.m_vertices[2], m_tri0_plane);
|
||||
|
||||
m_box1.increment_margin(-m_tri0.m_margin);
|
||||
|
||||
if(!result) return false;
|
||||
if (!result) return false;
|
||||
return true;
|
||||
}
|
||||
else if(t1_is_trimesh && node1_is_leaf)
|
||||
else if (t1_is_trimesh && node1_is_leaf)
|
||||
{
|
||||
//perform primitive vs box collision
|
||||
retrieve_node1_triangle(node1);
|
||||
@@ -565,11 +556,11 @@ protected:
|
||||
m_box0.increment_margin(m_tri1.m_margin);
|
||||
|
||||
result = m_box0.collide_triangle_exact(
|
||||
m_tri1.m_vertices[0],m_tri1.m_vertices[1],m_tri1.m_vertices[2],m_tri1_plane);
|
||||
m_tri1.m_vertices[0], m_tri1.m_vertices[1], m_tri1.m_vertices[2], m_tri1_plane);
|
||||
|
||||
m_box0.increment_margin(-m_tri1.m_margin);
|
||||
|
||||
if(!result) return false;
|
||||
if (!result) return false;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
@@ -582,40 +573,39 @@ protected:
|
||||
stack_collisions.reserve(32);
|
||||
|
||||
//add the first pair
|
||||
stack_collisions.push_pair(0,0);
|
||||
stack_collisions.push_pair(0, 0);
|
||||
|
||||
|
||||
while(stack_collisions.size())
|
||||
while (stack_collisions.size())
|
||||
{
|
||||
//retrieve the last pair and pop
|
||||
GUINT node0 = stack_collisions.back().m_index1;
|
||||
GUINT node1 = stack_collisions.back().m_index2;
|
||||
stack_collisions.pop_back();
|
||||
if(node_collision(node0,node1)) // a collision is found
|
||||
if (node_collision(node0, node1)) // a collision is found
|
||||
{
|
||||
if(node0_is_leaf)
|
||||
if (node0_is_leaf)
|
||||
{
|
||||
if(node1_is_leaf)
|
||||
if (node1_is_leaf)
|
||||
{
|
||||
m_collision_pairs->push_pair(m_boxset0->getNodeData(node0),m_boxset1->getNodeData(node1));
|
||||
m_collision_pairs->push_pair(m_boxset0->getNodeData(node0), m_boxset1->getNodeData(node1));
|
||||
}
|
||||
else
|
||||
{
|
||||
//collide left
|
||||
stack_collisions.push_pair(node0,m_boxset1->getLeftNodeIndex(node1));
|
||||
stack_collisions.push_pair(node0, m_boxset1->getLeftNodeIndex(node1));
|
||||
|
||||
//collide right
|
||||
stack_collisions.push_pair(node0,m_boxset1->getRightNodeIndex(node1));
|
||||
stack_collisions.push_pair(node0, m_boxset1->getRightNodeIndex(node1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(node1_is_leaf)
|
||||
if (node1_is_leaf)
|
||||
{
|
||||
//collide left
|
||||
stack_collisions.push_pair(m_boxset0->getLeftNodeIndex(node0),node1);
|
||||
stack_collisions.push_pair(m_boxset0->getLeftNodeIndex(node0), node1);
|
||||
//collide right
|
||||
stack_collisions.push_pair(m_boxset0->getRightNodeIndex(node0),node1);
|
||||
stack_collisions.push_pair(m_boxset0->getRightNodeIndex(node0), node1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -624,36 +614,36 @@ protected:
|
||||
GUINT left1 = m_boxset1->getLeftNodeIndex(node1);
|
||||
GUINT right1 = m_boxset1->getRightNodeIndex(node1);
|
||||
//collide left
|
||||
stack_collisions.push_pair(left0,left1);
|
||||
stack_collisions.push_pair(left0, left1);
|
||||
//collide right
|
||||
stack_collisions.push_pair(left0,right1);
|
||||
stack_collisions.push_pair(left0, right1);
|
||||
//collide left
|
||||
stack_collisions.push_pair(right0,left1);
|
||||
stack_collisions.push_pair(right0, left1);
|
||||
//collide right
|
||||
stack_collisions.push_pair(right0,right1);
|
||||
stack_collisions.push_pair(right0, right1);
|
||||
|
||||
}// else if node1 is not a leaf
|
||||
}// else if node0 is not a leaf
|
||||
} // else if node1 is not a leaf
|
||||
} // else if node0 is not a leaf
|
||||
|
||||
}// if(node_collision(node0,node1))
|
||||
}//while(stack_collisions.size())
|
||||
} // if(node_collision(node0,node1))
|
||||
} //while(stack_collisions.size())
|
||||
}
|
||||
|
||||
public:
|
||||
void find_collision(BOX_SET_CLASS0 * boxset1, const btTransform & trans1,
|
||||
BOX_SET_CLASS1 * boxset2, const btTransform & trans2,
|
||||
gim_pair_set & collision_pairs, bool complete_primitive_tests = true)
|
||||
void find_collision(BOX_SET_CLASS0* boxset1, const btTransform& trans1,
|
||||
BOX_SET_CLASS1* boxset2, const btTransform& trans2,
|
||||
gim_pair_set& collision_pairs, bool complete_primitive_tests = true)
|
||||
{
|
||||
m_collision_pairs = &collision_pairs;
|
||||
m_boxset0 = boxset1;
|
||||
m_boxset1 = boxset2;
|
||||
|
||||
trans_cache_1to0.calc_from_homogenic(trans1,trans2);
|
||||
trans_cache_1to0.calc_from_homogenic(trans1, trans2);
|
||||
|
||||
trans_cache_0to1 = trans2.inverse();
|
||||
trans_cache_0to1 = trans2.inverse();
|
||||
trans_cache_0to1 *= trans1;
|
||||
|
||||
|
||||
if(complete_primitive_tests)
|
||||
if (complete_primitive_tests)
|
||||
{
|
||||
t0_is_trimesh = boxset1->getPrimitiveManager().is_trimesh();
|
||||
t1_is_trimesh = boxset2->getPrimitiveManager().is_trimesh();
|
||||
@@ -668,7 +658,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
|
||||
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
|
||||
@@ -33,91 +33,86 @@ email: projectileman@yahoo.com
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
//! 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)
|
||||
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>
|
||||
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)
|
||||
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)
|
||||
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);
|
||||
GREAL blendfactor = -dist0 / (dist1 - dist0);
|
||||
VEC_BLEND(clipped[clipped_count], point0, point1, blendfactor);
|
||||
clipped_count++;
|
||||
}
|
||||
if(!_classif)
|
||||
if (!_classif)
|
||||
{
|
||||
VEC_COPY(clipped[clipped_count],point1);
|
||||
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>
|
||||
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)
|
||||
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;
|
||||
GUINT clipped_count = 0;
|
||||
|
||||
|
||||
//clip first point
|
||||
GREAL firstdist = distance_func(plane,polygon_points[0]);;
|
||||
if(!(firstdist>G_EPSILON))
|
||||
//clip first point
|
||||
GREAL firstdist = distance_func(plane, polygon_points[0]);
|
||||
;
|
||||
if (!(firstdist > G_EPSILON))
|
||||
{
|
||||
VEC_COPY(clipped[clipped_count],polygon_points[0]);
|
||||
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]);
|
||||
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);
|
||||
polygon_points[_i - 1], polygon_points[_i],
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
|
||||
|
||||
olddist = dist;
|
||||
olddist = dist;
|
||||
}
|
||||
|
||||
//RETURN TO FIRST point
|
||||
//RETURN TO FIRST point
|
||||
|
||||
PLANE_CLIP_POLYGON_COLLECT(
|
||||
polygon_points[polygon_point_count-1],polygon_points[0],
|
||||
olddist,
|
||||
firstdist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
polygon_points[polygon_point_count - 1], polygon_points[0],
|
||||
olddist,
|
||||
firstdist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
|
||||
return clipped_count;
|
||||
}
|
||||
@@ -126,85 +121,79 @@ SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON_GENERIC(
|
||||
/*!
|
||||
*\return The count of the clipped counts
|
||||
*/
|
||||
template<typename CLASS_POINT,typename CLASS_PLANE, typename DISTANCE_PLANE_FUNC>
|
||||
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)
|
||||
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;
|
||||
GUINT clipped_count = 0;
|
||||
|
||||
//clip first point
|
||||
GREAL firstdist = distance_func(plane,point0);;
|
||||
if(!(firstdist>G_EPSILON))
|
||||
//clip first point
|
||||
GREAL firstdist = distance_func(plane, point0);
|
||||
;
|
||||
if (!(firstdist > G_EPSILON))
|
||||
{
|
||||
VEC_COPY(clipped[clipped_count],point0);
|
||||
VEC_COPY(clipped[clipped_count], point0);
|
||||
clipped_count++;
|
||||
}
|
||||
|
||||
// point 1
|
||||
GREAL olddist = firstdist;
|
||||
GREAL dist = distance_func(plane,point1);
|
||||
GREAL dist = distance_func(plane, point1);
|
||||
|
||||
PLANE_CLIP_POLYGON_COLLECT(
|
||||
point0,point1,
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
point0, point1,
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
|
||||
olddist = dist;
|
||||
|
||||
|
||||
// point 2
|
||||
dist = distance_func(plane,point2);
|
||||
dist = distance_func(plane, point2);
|
||||
|
||||
PLANE_CLIP_POLYGON_COLLECT(
|
||||
point1,point2,
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
point1, point2,
|
||||
olddist,
|
||||
dist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
olddist = dist;
|
||||
|
||||
|
||||
|
||||
//RETURN TO FIRST point
|
||||
PLANE_CLIP_POLYGON_COLLECT(
|
||||
point2,point0,
|
||||
olddist,
|
||||
firstdist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
point2, point0,
|
||||
olddist,
|
||||
firstdist,
|
||||
clipped,
|
||||
clipped_count);
|
||||
|
||||
return clipped_count;
|
||||
}
|
||||
|
||||
|
||||
template<typename CLASS_POINT,typename CLASS_PLANE>
|
||||
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)
|
||||
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());
|
||||
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>
|
||||
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)
|
||||
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());
|
||||
return PLANE_CLIP_TRIANGLE_GENERIC<CLASS_POINT, CLASS_PLANE>(plane, point0, point1, point2, clipped, DISTANCE_PLANE_3D_FUNC());
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // GIM_TRI_COLLISION_H_INCLUDED
|
||||
#endif // GIM_TRI_COLLISION_H_INCLUDED
|
||||
|
||||
@@ -33,91 +33,89 @@ email: projectileman@yahoo.com
|
||||
#define MAX_COINCIDENT 8
|
||||
|
||||
void gim_contact_array::merge_contacts(
|
||||
const gim_contact_array & contacts, bool normal_contact_average)
|
||||
const gim_contact_array& contacts, bool normal_contact_average)
|
||||
{
|
||||
clear();
|
||||
|
||||
if(contacts.size()==1)
|
||||
if (contacts.size() == 1)
|
||||
{
|
||||
push_back(contacts.back());
|
||||
return;
|
||||
}
|
||||
|
||||
gim_array<GIM_RSORT_TOKEN> keycontacts(contacts.size());
|
||||
keycontacts.resize(contacts.size(),false);
|
||||
keycontacts.resize(contacts.size(), false);
|
||||
|
||||
//fill key contacts
|
||||
|
||||
GUINT i;
|
||||
|
||||
for (i = 0;i<contacts.size() ;i++ )
|
||||
for (i = 0; i < contacts.size(); i++)
|
||||
{
|
||||
keycontacts[i].m_key = contacts[i].calc_key_contact();
|
||||
keycontacts[i].m_value = i;
|
||||
}
|
||||
|
||||
//sort keys
|
||||
gim_heap_sort(keycontacts.pointer(),keycontacts.size(),GIM_RSORT_TOKEN_COMPARATOR());
|
||||
gim_heap_sort(keycontacts.pointer(), keycontacts.size(), GIM_RSORT_TOKEN_COMPARATOR());
|
||||
|
||||
// Merge contacts
|
||||
|
||||
GUINT coincident_count=0;
|
||||
GUINT coincident_count = 0;
|
||||
btVector3 coincident_normals[MAX_COINCIDENT];
|
||||
|
||||
GUINT last_key = keycontacts[0].m_key;
|
||||
GUINT key = 0;
|
||||
|
||||
push_back(contacts[keycontacts[0].m_value]);
|
||||
GIM_CONTACT * pcontact = &back();
|
||||
GIM_CONTACT* pcontact = &back();
|
||||
|
||||
|
||||
|
||||
for( i=1;i<keycontacts.size();i++)
|
||||
for (i = 1; i < keycontacts.size(); i++)
|
||||
{
|
||||
key = keycontacts[i].m_key;
|
||||
const GIM_CONTACT * scontact = &contacts[keycontacts[i].m_value];
|
||||
key = keycontacts[i].m_key;
|
||||
const GIM_CONTACT* scontact = &contacts[keycontacts[i].m_value];
|
||||
|
||||
if(last_key == key)//same points
|
||||
if (last_key == key) //same points
|
||||
{
|
||||
//merge contact
|
||||
if(pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//)
|
||||
if (pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth) //)
|
||||
{
|
||||
*pcontact = *scontact;
|
||||
coincident_count = 0;
|
||||
coincident_count = 0;
|
||||
}
|
||||
else if(normal_contact_average)
|
||||
else if (normal_contact_average)
|
||||
{
|
||||
if(btFabs(pcontact->m_depth - scontact->m_depth)<CONTACT_DIFF_EPSILON)
|
||||
{
|
||||
if(coincident_count<MAX_COINCIDENT)
|
||||
{
|
||||
coincident_normals[coincident_count] = scontact->m_normal;
|
||||
coincident_count++;
|
||||
}
|
||||
}
|
||||
if (btFabs(pcontact->m_depth - scontact->m_depth) < CONTACT_DIFF_EPSILON)
|
||||
{
|
||||
if (coincident_count < MAX_COINCIDENT)
|
||||
{
|
||||
coincident_normals[coincident_count] = scontact->m_normal;
|
||||
coincident_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{//add new contact
|
||||
{ //add new contact
|
||||
|
||||
if(normal_contact_average && coincident_count>0)
|
||||
{
|
||||
pcontact->interpolate_normals(coincident_normals,coincident_count);
|
||||
coincident_count = 0;
|
||||
}
|
||||
if (normal_contact_average && coincident_count > 0)
|
||||
{
|
||||
pcontact->interpolate_normals(coincident_normals, coincident_count);
|
||||
coincident_count = 0;
|
||||
}
|
||||
|
||||
push_back(*scontact);
|
||||
pcontact = &back();
|
||||
}
|
||||
push_back(*scontact);
|
||||
pcontact = &back();
|
||||
}
|
||||
last_key = key;
|
||||
}
|
||||
}
|
||||
|
||||
void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts)
|
||||
void gim_contact_array::merge_contacts_unique(const gim_contact_array& contacts)
|
||||
{
|
||||
clear();
|
||||
|
||||
if(contacts.size()==1)
|
||||
if (contacts.size() == 1)
|
||||
{
|
||||
push_back(contacts.back());
|
||||
return;
|
||||
@@ -125,14 +123,14 @@ void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts
|
||||
|
||||
GIM_CONTACT average_contact = contacts.back();
|
||||
|
||||
for (GUINT i=1;i<contacts.size() ;i++ )
|
||||
for (GUINT i = 1; i < contacts.size(); i++)
|
||||
{
|
||||
average_contact.m_point += contacts[i].m_point;
|
||||
average_contact.m_normal += contacts[i].m_normal * contacts[i].m_depth;
|
||||
}
|
||||
|
||||
//divide
|
||||
GREAL divide_average = 1.0f/((GREAL)contacts.size());
|
||||
GREAL divide_average = 1.0f / ((GREAL)contacts.size());
|
||||
|
||||
average_contact.m_point *= divide_average;
|
||||
|
||||
@@ -141,6 +139,4 @@ void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts
|
||||
average_contact.m_depth = average_contact.m_normal.length();
|
||||
|
||||
average_contact.m_normal /= average_contact.m_depth;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ email: projectileman@yahoo.com
|
||||
#include "gim_radixsort.h"
|
||||
#include "gim_array.h"
|
||||
|
||||
|
||||
/**
|
||||
Configuration var for applying interpolation of contact normals
|
||||
*/
|
||||
@@ -58,90 +57,87 @@ Configuration var for applying interpolation of contact normals
|
||||
class GIM_CONTACT
|
||||
{
|
||||
public:
|
||||
btVector3 m_point;
|
||||
btVector3 m_normal;
|
||||
GREAL m_depth;//Positive value indicates interpenetration
|
||||
GREAL m_distance;//Padding not for use
|
||||
GUINT m_feature1;//Face number
|
||||
GUINT m_feature2;//Face number
|
||||
btVector3 m_point;
|
||||
btVector3 m_normal;
|
||||
GREAL m_depth; //Positive value indicates interpenetration
|
||||
GREAL m_distance; //Padding not for use
|
||||
GUINT m_feature1; //Face number
|
||||
GUINT m_feature2; //Face number
|
||||
public:
|
||||
GIM_CONTACT()
|
||||
{
|
||||
}
|
||||
GIM_CONTACT()
|
||||
{
|
||||
}
|
||||
|
||||
GIM_CONTACT(const GIM_CONTACT & contact):
|
||||
m_point(contact.m_point),
|
||||
m_normal(contact.m_normal),
|
||||
m_depth(contact.m_depth),
|
||||
m_feature1(contact.m_feature1),
|
||||
m_feature2(contact.m_feature2)
|
||||
{
|
||||
m_point = contact.m_point;
|
||||
m_normal = contact.m_normal;
|
||||
m_depth = contact.m_depth;
|
||||
m_feature1 = contact.m_feature1;
|
||||
m_feature2 = contact.m_feature2;
|
||||
}
|
||||
GIM_CONTACT(const GIM_CONTACT &contact) : m_point(contact.m_point),
|
||||
m_normal(contact.m_normal),
|
||||
m_depth(contact.m_depth),
|
||||
m_feature1(contact.m_feature1),
|
||||
m_feature2(contact.m_feature2)
|
||||
{
|
||||
m_point = contact.m_point;
|
||||
m_normal = contact.m_normal;
|
||||
m_depth = contact.m_depth;
|
||||
m_feature1 = contact.m_feature1;
|
||||
m_feature2 = contact.m_feature2;
|
||||
}
|
||||
|
||||
GIM_CONTACT(const btVector3 &point,const btVector3 & normal,
|
||||
GREAL depth, GUINT feature1, GUINT feature2):
|
||||
m_point(point),
|
||||
m_normal(normal),
|
||||
m_depth(depth),
|
||||
m_feature1(feature1),
|
||||
m_feature2(feature2)
|
||||
{
|
||||
}
|
||||
GIM_CONTACT(const btVector3 &point, const btVector3 &normal,
|
||||
GREAL depth, GUINT feature1, GUINT feature2) : m_point(point),
|
||||
m_normal(normal),
|
||||
m_depth(depth),
|
||||
m_feature1(feature1),
|
||||
m_feature2(feature2)
|
||||
{
|
||||
}
|
||||
|
||||
//! Calcs key for coord classification
|
||||
SIMD_FORCE_INLINE GUINT calc_key_contact() const
|
||||
{
|
||||
GINT _coords[] = {
|
||||
(GINT)(m_point[0]*1000.0f+1.0f),
|
||||
(GINT)(m_point[1]*1333.0f),
|
||||
(GINT)(m_point[2]*2133.0f+3.0f)};
|
||||
GUINT _hash=0;
|
||||
SIMD_FORCE_INLINE GUINT calc_key_contact() const
|
||||
{
|
||||
GINT _coords[] = {
|
||||
(GINT)(m_point[0] * 1000.0f + 1.0f),
|
||||
(GINT)(m_point[1] * 1333.0f),
|
||||
(GINT)(m_point[2] * 2133.0f + 3.0f)};
|
||||
GUINT _hash = 0;
|
||||
GUINT *_uitmp = (GUINT *)(&_coords[0]);
|
||||
_hash = *_uitmp;
|
||||
_uitmp++;
|
||||
_hash += (*_uitmp)<<4;
|
||||
_hash += (*_uitmp) << 4;
|
||||
_uitmp++;
|
||||
_hash += (*_uitmp)<<8;
|
||||
_hash += (*_uitmp) << 8;
|
||||
return _hash;
|
||||
}
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void interpolate_normals( btVector3 * normals,GUINT normal_count)
|
||||
{
|
||||
btVector3 vec_sum(m_normal);
|
||||
for(GUINT i=0;i<normal_count;i++)
|
||||
SIMD_FORCE_INLINE void interpolate_normals(btVector3 *normals, GUINT normal_count)
|
||||
{
|
||||
btVector3 vec_sum(m_normal);
|
||||
for (GUINT i = 0; i < normal_count; i++)
|
||||
{
|
||||
vec_sum += normals[i];
|
||||
}
|
||||
|
||||
GREAL vec_sum_len = vec_sum.length2();
|
||||
if(vec_sum_len <CONTACT_DIFF_EPSILON) return;
|
||||
if (vec_sum_len < CONTACT_DIFF_EPSILON) return;
|
||||
|
||||
GIM_INV_SQRT(vec_sum_len,vec_sum_len); // 1/sqrt(vec_sum_len)
|
||||
|
||||
m_normal = vec_sum*vec_sum_len;
|
||||
}
|
||||
GIM_INV_SQRT(vec_sum_len, vec_sum_len); // 1/sqrt(vec_sum_len)
|
||||
|
||||
m_normal = vec_sum * vec_sum_len;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class gim_contact_array:public gim_array<GIM_CONTACT>
|
||||
class gim_contact_array : public gim_array<GIM_CONTACT>
|
||||
{
|
||||
public:
|
||||
gim_contact_array():gim_array<GIM_CONTACT>(64)
|
||||
gim_contact_array() : gim_array<GIM_CONTACT>(64)
|
||||
{
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void push_contact(const btVector3 &point,const btVector3 & normal,
|
||||
GREAL depth, GUINT feature1, GUINT feature2)
|
||||
SIMD_FORCE_INLINE void push_contact(const btVector3 &point, const btVector3 &normal,
|
||||
GREAL depth, GUINT feature1, GUINT feature2)
|
||||
{
|
||||
push_back_mem();
|
||||
GIM_CONTACT & newele = back();
|
||||
GIM_CONTACT &newele = back();
|
||||
newele.m_point = point;
|
||||
newele.m_normal = normal;
|
||||
newele.m_depth = depth;
|
||||
@@ -150,13 +146,13 @@ public:
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void push_triangle_contacts(
|
||||
const GIM_TRIANGLE_CONTACT_DATA & tricontact,
|
||||
GUINT feature1,GUINT feature2)
|
||||
const GIM_TRIANGLE_CONTACT_DATA &tricontact,
|
||||
GUINT feature1, GUINT feature2)
|
||||
{
|
||||
for(GUINT i = 0;i<tricontact.m_point_count ;i++ )
|
||||
for (GUINT i = 0; i < tricontact.m_point_count; i++)
|
||||
{
|
||||
push_back_mem();
|
||||
GIM_CONTACT & newele = back();
|
||||
GIM_CONTACT &newele = back();
|
||||
newele.m_point = tricontact.m_points[i];
|
||||
newele.m_normal = tricontact.m_separating_normal;
|
||||
newele.m_depth = tricontact.m_penetration_depth;
|
||||
@@ -165,8 +161,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void merge_contacts(const gim_contact_array & contacts, bool normal_contact_average = true);
|
||||
void merge_contacts_unique(const gim_contact_array & contacts);
|
||||
void merge_contacts(const gim_contact_array &contacts, bool normal_contact_average = true);
|
||||
void merge_contacts_unique(const gim_contact_array &contacts);
|
||||
};
|
||||
|
||||
#endif // GIM_CONTACT_H_INCLUDED
|
||||
#endif // GIM_CONTACT_H_INCLUDED
|
||||
|
||||
@@ -33,11 +33,8 @@ email: projectileman@yahoo.com
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "gim_math.h"
|
||||
|
||||
|
||||
|
||||
//! Short Integer vector 2D
|
||||
typedef GSHORT vec2s[2];
|
||||
//! Integer vector 3D
|
||||
@@ -92,6 +89,4 @@ typedef GREAL quatf[4];
|
||||
|
||||
//typedef struct _aabb3f aabb3f;
|
||||
|
||||
|
||||
|
||||
#endif // GIM_GEOM_TYPES_H_INCLUDED
|
||||
#endif // GIM_GEOM_TYPES_H_INCLUDED
|
||||
|
||||
@@ -39,4 +39,4 @@ email: projectileman@yahoo.com
|
||||
#include "gim_box_collision.h"
|
||||
#include "gim_tri_collision.h"
|
||||
|
||||
#endif // GIM_VECTOR_H_INCLUDED
|
||||
#endif // GIM_VECTOR_H_INCLUDED
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -34,8 +34,6 @@ email: projectileman@yahoo.com
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
|
||||
|
||||
|
||||
#define GREAL btScalar
|
||||
#define GREAL2 double
|
||||
#define GINT int
|
||||
@@ -45,8 +43,6 @@ email: projectileman@yahoo.com
|
||||
#define GINT64 long long
|
||||
#define GUINT64 unsigned long long
|
||||
|
||||
|
||||
|
||||
#define G_PI 3.14159265358979f
|
||||
#define G_HALF_PI 1.5707963f
|
||||
//267948966
|
||||
@@ -54,16 +50,14 @@ email: projectileman@yahoo.com
|
||||
//71795864
|
||||
#define G_ROOT3 1.73205f
|
||||
#define G_ROOT2 1.41421f
|
||||
#define G_UINT_INFINITY 0xffffffff //!< A very very high value
|
||||
#define G_UINT_INFINITY 0xffffffff //!< A very very high value
|
||||
#define G_REAL_INFINITY FLT_MAX
|
||||
#define G_SIGN_BITMASK 0x80000000
|
||||
#define G_SIGN_BITMASK 0x80000000
|
||||
#define G_EPSILON SIMD_EPSILON
|
||||
|
||||
|
||||
|
||||
enum GIM_SCALAR_TYPES
|
||||
{
|
||||
G_STYPE_REAL =0,
|
||||
G_STYPE_REAL = 0,
|
||||
G_STYPE_REAL2,
|
||||
G_STYPE_SHORT,
|
||||
G_STYPE_USHORT,
|
||||
@@ -73,85 +67,82 @@ enum GIM_SCALAR_TYPES
|
||||
G_STYPE_UINT64
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f)
|
||||
#define G_RADTODEG(X) ((X)*180.0f/3.1415926f)
|
||||
#define G_DEGTORAD(X) ((X)*3.1415926f / 180.0f)
|
||||
#define G_RADTODEG(X) ((X)*180.0f / 3.1415926f)
|
||||
|
||||
//! Integer representation of a floating-point value.
|
||||
#define GIM_IR(x) ((GUINT&)(x))
|
||||
#define GIM_IR(x) ((GUINT&)(x))
|
||||
|
||||
//! Signed integer representation of a floating-point value.
|
||||
#define GIM_SIR(x) ((GINT&)(x))
|
||||
#define GIM_SIR(x) ((GINT&)(x))
|
||||
|
||||
//! Absolute integer representation of a floating-point value
|
||||
#define GIM_AIR(x) (GIM_IR(x)&0x7fffffff)
|
||||
#define GIM_AIR(x) (GIM_IR(x) & 0x7fffffff)
|
||||
|
||||
//! Floating-point representation of an integer value.
|
||||
#define GIM_FR(x) ((GREAL&)(x))
|
||||
#define GIM_FR(x) ((GREAL&)(x))
|
||||
|
||||
#define GIM_MAX(a,b) (a<b?b:a)
|
||||
#define GIM_MIN(a,b) (a>b?b:a)
|
||||
#define GIM_MAX(a, b) (a < b ? b : a)
|
||||
#define GIM_MIN(a, b) (a > b ? b : a)
|
||||
|
||||
#define GIM_MAX3(a,b,c) GIM_MAX(a,GIM_MAX(b,c))
|
||||
#define GIM_MIN3(a,b,c) GIM_MIN(a,GIM_MIN(b,c))
|
||||
#define GIM_MAX3(a, b, c) GIM_MAX(a, GIM_MAX(b, c))
|
||||
#define GIM_MIN3(a, b, c) GIM_MIN(a, GIM_MIN(b, c))
|
||||
|
||||
#define GIM_IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON)
|
||||
#define GIM_IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON)
|
||||
|
||||
#define GIM_IS_NEGATIVE(value) (value <= -G_EPSILON)
|
||||
|
||||
#define GIM_IS_POSISITVE(value) (value >= G_EPSILON)
|
||||
|
||||
#define GIM_NEAR_EQUAL(v1,v2) GIM_IS_ZERO((v1-v2))
|
||||
#define GIM_NEAR_EQUAL(v1, v2) GIM_IS_ZERO((v1 - v2))
|
||||
|
||||
///returns a clamped number
|
||||
#define GIM_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
|
||||
#define GIM_CLAMP(number, minval, maxval) (number < minval ? minval : (number > maxval ? maxval : number))
|
||||
|
||||
#define GIM_GREATER(x, y) btFabs(x) > (y)
|
||||
#define GIM_GREATER(x, y) btFabs(x) > (y)
|
||||
|
||||
///Swap numbers
|
||||
#define GIM_SWAP_NUMBERS(a,b){ \
|
||||
a = a+b; \
|
||||
b = a-b; \
|
||||
a = a-b; \
|
||||
}\
|
||||
#define GIM_SWAP_NUMBERS(a, b) \
|
||||
{ \
|
||||
a = a + b; \
|
||||
b = a - b; \
|
||||
a = a - b; \
|
||||
}
|
||||
|
||||
#define GIM_INV_SQRT(va,isva)\
|
||||
{\
|
||||
if(va<=0.0000001f)\
|
||||
{\
|
||||
isva = G_REAL_INFINITY;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
GREAL _x = va * 0.5f;\
|
||||
GUINT _y = 0x5f3759df - ( GIM_IR(va) >> 1);\
|
||||
isva = GIM_FR(_y);\
|
||||
isva = isva * ( 1.5f - ( _x * isva * isva ) );\
|
||||
}\
|
||||
}\
|
||||
#define GIM_INV_SQRT(va, isva) \
|
||||
{ \
|
||||
if (va <= 0.0000001f) \
|
||||
{ \
|
||||
isva = G_REAL_INFINITY; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
GREAL _x = va * 0.5f; \
|
||||
GUINT _y = 0x5f3759df - (GIM_IR(va) >> 1); \
|
||||
isva = GIM_FR(_y); \
|
||||
isva = isva * (1.5f - (_x * isva * isva)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GIM_SQRT(va,sva)\
|
||||
{\
|
||||
GIM_INV_SQRT(va,sva);\
|
||||
sva = 1.0f/sva;\
|
||||
}\
|
||||
#define GIM_SQRT(va, sva) \
|
||||
{ \
|
||||
GIM_INV_SQRT(va, sva); \
|
||||
sva = 1.0f / sva; \
|
||||
}
|
||||
|
||||
//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html
|
||||
inline GREAL gim_inv_sqrt(GREAL f)
|
||||
{
|
||||
GREAL r;
|
||||
GIM_INV_SQRT(f,r);
|
||||
return r;
|
||||
GREAL r;
|
||||
GIM_INV_SQRT(f, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline GREAL gim_sqrt(GREAL f)
|
||||
{
|
||||
GREAL r;
|
||||
GIM_SQRT(f,r);
|
||||
return r;
|
||||
GREAL r;
|
||||
GIM_SQRT(f, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // GIM_MATH_H_INCLUDED
|
||||
#endif // GIM_MATH_H_INCLUDED
|
||||
|
||||
@@ -27,7 +27,6 @@ email: projectileman@yahoo.com
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "gim_memory.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
@@ -40,52 +39,49 @@ static gim_alloca_function *g_allocafn = 0;
|
||||
static gim_realloc_function *g_reallocfn = 0;
|
||||
static gim_free_function *g_freefn = 0;
|
||||
|
||||
void gim_set_alloc_handler (gim_alloc_function *fn)
|
||||
void gim_set_alloc_handler(gim_alloc_function *fn)
|
||||
{
|
||||
g_allocfn = fn;
|
||||
g_allocfn = fn;
|
||||
}
|
||||
|
||||
void gim_set_alloca_handler (gim_alloca_function *fn)
|
||||
void gim_set_alloca_handler(gim_alloca_function *fn)
|
||||
{
|
||||
g_allocafn = fn;
|
||||
g_allocafn = fn;
|
||||
}
|
||||
|
||||
void gim_set_realloc_handler (gim_realloc_function *fn)
|
||||
void gim_set_realloc_handler(gim_realloc_function *fn)
|
||||
{
|
||||
g_reallocfn = fn;
|
||||
g_reallocfn = fn;
|
||||
}
|
||||
|
||||
void gim_set_free_handler (gim_free_function *fn)
|
||||
void gim_set_free_handler(gim_free_function *fn)
|
||||
{
|
||||
g_freefn = fn;
|
||||
g_freefn = fn;
|
||||
}
|
||||
|
||||
gim_alloc_function *gim_get_alloc_handler()
|
||||
{
|
||||
return g_allocfn;
|
||||
return g_allocfn;
|
||||
}
|
||||
|
||||
gim_alloca_function *gim_get_alloca_handler()
|
||||
{
|
||||
return g_allocafn;
|
||||
return g_allocafn;
|
||||
}
|
||||
|
||||
|
||||
gim_realloc_function *gim_get_realloc_handler ()
|
||||
gim_realloc_function *gim_get_realloc_handler()
|
||||
{
|
||||
return g_reallocfn;
|
||||
return g_reallocfn;
|
||||
}
|
||||
|
||||
|
||||
gim_free_function *gim_get_free_handler ()
|
||||
gim_free_function *gim_get_free_handler()
|
||||
{
|
||||
return g_freefn;
|
||||
return g_freefn;
|
||||
}
|
||||
|
||||
|
||||
void * gim_alloc(size_t size)
|
||||
void *gim_alloc(size_t size)
|
||||
{
|
||||
void * ptr;
|
||||
void *ptr;
|
||||
if (g_allocfn)
|
||||
{
|
||||
ptr = g_allocfn(size);
|
||||
@@ -93,27 +89,29 @@ void * gim_alloc(size_t size)
|
||||
else
|
||||
{
|
||||
#ifdef GIM_SIMD_MEMORY
|
||||
ptr = btAlignedAlloc(size,16);
|
||||
ptr = btAlignedAlloc(size, 16);
|
||||
#else
|
||||
ptr = malloc(size);
|
||||
#endif
|
||||
}
|
||||
return ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void * gim_alloca(size_t size)
|
||||
void *gim_alloca(size_t size)
|
||||
{
|
||||
if (g_allocafn) return g_allocafn(size); else return gim_alloc(size);
|
||||
if (g_allocafn)
|
||||
return g_allocafn(size);
|
||||
else
|
||||
return gim_alloc(size);
|
||||
}
|
||||
|
||||
|
||||
void * gim_realloc(void *ptr, size_t oldsize, size_t newsize)
|
||||
void *gim_realloc(void *ptr, size_t oldsize, size_t newsize)
|
||||
{
|
||||
void * newptr = gim_alloc(newsize);
|
||||
size_t copysize = oldsize<newsize?oldsize:newsize;
|
||||
gim_simd_memcpy(newptr,ptr,copysize);
|
||||
gim_free(ptr);
|
||||
return newptr;
|
||||
void *newptr = gim_alloc(newsize);
|
||||
size_t copysize = oldsize < newsize ? oldsize : newsize;
|
||||
gim_simd_memcpy(newptr, ptr, copysize);
|
||||
gim_free(ptr);
|
||||
return newptr;
|
||||
}
|
||||
|
||||
void gim_free(void *ptr)
|
||||
@@ -121,15 +119,14 @@ void gim_free(void *ptr)
|
||||
if (!ptr) return;
|
||||
if (g_freefn)
|
||||
{
|
||||
g_freefn(ptr);
|
||||
g_freefn(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GIM_SIMD_MEMORY
|
||||
#ifdef GIM_SIMD_MEMORY
|
||||
btAlignedFree(ptr);
|
||||
#else
|
||||
#else
|
||||
free(ptr);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,93 +32,84 @@ email: projectileman@yahoo.com
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "gim_math.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef PREFETCH
|
||||
#include <xmmintrin.h> // for prefetch
|
||||
#define pfval 64
|
||||
#define pfval2 128
|
||||
#include <xmmintrin.h> // for prefetch
|
||||
#define pfval 64
|
||||
#define pfval2 128
|
||||
//! Prefetch 64
|
||||
#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0)
|
||||
#define pf(_x, _i) _mm_prefetch((void *)(_x + _i + pfval), 0)
|
||||
//! Prefetch 128
|
||||
#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
|
||||
#define pf2(_x, _i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
|
||||
#else
|
||||
//! Prefetch 64
|
||||
#define pf(_x,_i)
|
||||
#define pf(_x, _i)
|
||||
//! Prefetch 128
|
||||
#define pf2(_x,_i)
|
||||
#define pf2(_x, _i)
|
||||
#endif
|
||||
|
||||
|
||||
///Functions for manip packed arrays of numbers
|
||||
#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\
|
||||
{\
|
||||
for (GUINT _i_=0;_i_<element_count ;++_i_)\
|
||||
{\
|
||||
dest_array[_i_] = source_array[_i_];\
|
||||
}\
|
||||
}\
|
||||
#define GIM_COPY_ARRAYS(dest_array, source_array, element_count) \
|
||||
{ \
|
||||
for (GUINT _i_ = 0; _i_ < element_count; ++_i_) \
|
||||
{ \
|
||||
dest_array[_i_] = source_array[_i_]; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GIM_COPY_ARRAYS_1(dest_array,source_array,element_count,copy_macro)\
|
||||
{\
|
||||
for (GUINT _i_=0;_i_<element_count ;++_i_)\
|
||||
{\
|
||||
copy_macro(dest_array[_i_],source_array[_i_]);\
|
||||
}\
|
||||
}\
|
||||
#define GIM_COPY_ARRAYS_1(dest_array, source_array, element_count, copy_macro) \
|
||||
{ \
|
||||
for (GUINT _i_ = 0; _i_ < element_count; ++_i_) \
|
||||
{ \
|
||||
copy_macro(dest_array[_i_], source_array[_i_]); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GIM_ZERO_ARRAY(array, element_count) \
|
||||
{ \
|
||||
for (GUINT _i_ = 0; _i_ < element_count; ++_i_) \
|
||||
{ \
|
||||
array[_i_] = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GIM_ZERO_ARRAY(array,element_count)\
|
||||
{\
|
||||
for (GUINT _i_=0;_i_<element_count ;++_i_)\
|
||||
{\
|
||||
array[_i_] = 0;\
|
||||
}\
|
||||
}\
|
||||
|
||||
#define GIM_CONSTANT_ARRAY(array,element_count,constant)\
|
||||
{\
|
||||
for (GUINT _i_=0;_i_<element_count ;++_i_)\
|
||||
{\
|
||||
array[_i_] = constant;\
|
||||
}\
|
||||
}\
|
||||
|
||||
#define GIM_CONSTANT_ARRAY(array, element_count, constant) \
|
||||
{ \
|
||||
for (GUINT _i_ = 0; _i_ < element_count; ++_i_) \
|
||||
{ \
|
||||
array[_i_] = constant; \
|
||||
} \
|
||||
}
|
||||
|
||||
///Function prototypes to allocate and free memory.
|
||||
typedef void * gim_alloc_function (size_t size);
|
||||
typedef void * gim_alloca_function (size_t size);//Allocs on the heap
|
||||
typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
|
||||
typedef void gim_free_function (void *ptr);
|
||||
|
||||
typedef void *gim_alloc_function(size_t size);
|
||||
typedef void *gim_alloca_function(size_t size); //Allocs on the heap
|
||||
typedef void *gim_realloc_function(void *ptr, size_t oldsize, size_t newsize);
|
||||
typedef void gim_free_function(void *ptr);
|
||||
|
||||
///Memory Function Handlers
|
||||
///set new memory management functions. if fn is 0, the default handlers are used.
|
||||
void gim_set_alloc_handler (gim_alloc_function *fn);
|
||||
void gim_set_alloca_handler (gim_alloca_function *fn);
|
||||
void gim_set_realloc_handler (gim_realloc_function *fn);
|
||||
void gim_set_free_handler (gim_free_function *fn);
|
||||
|
||||
void gim_set_alloc_handler(gim_alloc_function *fn);
|
||||
void gim_set_alloca_handler(gim_alloca_function *fn);
|
||||
void gim_set_realloc_handler(gim_realloc_function *fn);
|
||||
void gim_set_free_handler(gim_free_function *fn);
|
||||
|
||||
///get current memory management functions.
|
||||
gim_alloc_function *gim_get_alloc_handler (void);
|
||||
gim_alloc_function *gim_get_alloc_handler(void);
|
||||
gim_alloca_function *gim_get_alloca_handler(void);
|
||||
gim_realloc_function *gim_get_realloc_handler (void);
|
||||
gim_free_function *gim_get_free_handler (void);
|
||||
|
||||
gim_realloc_function *gim_get_realloc_handler(void);
|
||||
gim_free_function *gim_get_free_handler(void);
|
||||
|
||||
///Standar Memory functions
|
||||
void * gim_alloc(size_t size);
|
||||
void * gim_alloca(size_t size);
|
||||
void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
|
||||
void *gim_alloc(size_t size);
|
||||
void *gim_alloca(size_t size);
|
||||
void *gim_realloc(void *ptr, size_t oldsize, size_t newsize);
|
||||
void gim_free(void *ptr);
|
||||
|
||||
|
||||
|
||||
#if defined (_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
#define GIM_SIMD_MEMORY 1
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
#define GIM_SIMD_MEMORY 1
|
||||
#endif
|
||||
|
||||
//! SIMD POINTER INTEGER
|
||||
@@ -126,11 +117,10 @@ void gim_free(void *ptr);
|
||||
//! SIMD INTEGER SIZE
|
||||
#define SIMD_T_SIZE sizeof(SIMD_T)
|
||||
|
||||
|
||||
inline void gim_simd_memcpy(void * dst, const void * src, size_t copysize)
|
||||
inline void gim_simd_memcpy(void *dst, const void *src, size_t copysize)
|
||||
{
|
||||
#ifdef GIM_SIMD_MEMORY
|
||||
/*
|
||||
/*
|
||||
//'long long int' is incompatible with visual studio 6...
|
||||
//copy words
|
||||
SIMD_T * ui_src_ptr = (SIMD_T *)src;
|
||||
@@ -143,48 +133,45 @@ inline void gim_simd_memcpy(void * dst, const void * src, size_t copysize)
|
||||
if(copysize==0) return;
|
||||
*/
|
||||
|
||||
char * c_src_ptr = (char *)src;
|
||||
char * c_dst_ptr = (char *)dst;
|
||||
while(copysize>0)
|
||||
{
|
||||
*(c_dst_ptr++) = *(c_src_ptr++);
|
||||
copysize--;
|
||||
}
|
||||
return;
|
||||
char *c_src_ptr = (char *)src;
|
||||
char *c_dst_ptr = (char *)dst;
|
||||
while (copysize > 0)
|
||||
{
|
||||
*(c_dst_ptr++) = *(c_src_ptr++);
|
||||
copysize--;
|
||||
}
|
||||
return;
|
||||
#else
|
||||
memcpy(dst,src,copysize);
|
||||
memcpy(dst, src, copysize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void gim_swap_elements(T* _array,size_t _i,size_t _j)
|
||||
template <class T>
|
||||
inline void gim_swap_elements(T *_array, size_t _i, size_t _j)
|
||||
{
|
||||
T _e_tmp_ = _array[_i];
|
||||
_array[_i] = _array[_j];
|
||||
_array[_j] = _e_tmp_;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void gim_swap_elements_memcpy(T* _array,size_t _i,size_t _j)
|
||||
template <class T>
|
||||
inline void gim_swap_elements_memcpy(T *_array, size_t _i, size_t _j)
|
||||
{
|
||||
char _e_tmp_[sizeof(T)];
|
||||
gim_simd_memcpy(_e_tmp_,&_array[_i],sizeof(T));
|
||||
gim_simd_memcpy(&_array[_i],&_array[_j],sizeof(T));
|
||||
gim_simd_memcpy(&_array[_j],_e_tmp_,sizeof(T));
|
||||
gim_simd_memcpy(_e_tmp_, &_array[_i], sizeof(T));
|
||||
gim_simd_memcpy(&_array[_i], &_array[_j], sizeof(T));
|
||||
gim_simd_memcpy(&_array[_j], _e_tmp_, sizeof(T));
|
||||
}
|
||||
|
||||
template <int SIZE>
|
||||
inline void gim_swap_elements_ptr(char * _array,size_t _i,size_t _j)
|
||||
inline void gim_swap_elements_ptr(char *_array, size_t _i, size_t _j)
|
||||
{
|
||||
char _e_tmp_[SIZE];
|
||||
_i*=SIZE;
|
||||
_j*=SIZE;
|
||||
gim_simd_memcpy(_e_tmp_,_array+_i,SIZE);
|
||||
gim_simd_memcpy(_array+_i,_array+_j,SIZE);
|
||||
gim_simd_memcpy(_array+_j,_e_tmp_,SIZE);
|
||||
_i *= SIZE;
|
||||
_j *= SIZE;
|
||||
gim_simd_memcpy(_e_tmp_, _array + _i, SIZE);
|
||||
gim_simd_memcpy(_array + _i, _array + _j, SIZE);
|
||||
gim_simd_memcpy(_array + _j, _e_tmp_, SIZE);
|
||||
}
|
||||
|
||||
#endif // GIM_MEMORY_H_INCLUDED
|
||||
#endif // GIM_MEMORY_H_INCLUDED
|
||||
|
||||
@@ -40,24 +40,22 @@ email: projectileman@yahoo.com
|
||||
//! Prototype for comparators
|
||||
class less_comparator
|
||||
{
|
||||
public:
|
||||
|
||||
template<class T,class Z>
|
||||
inline int operator() ( const T& a, const Z& b )
|
||||
public:
|
||||
template <class T, class Z>
|
||||
inline int operator()(const T& a, const Z& b)
|
||||
{
|
||||
return ( a<b?-1:(a>b?1:0));
|
||||
return (a < b ? -1 : (a > b ? 1 : 0));
|
||||
}
|
||||
};
|
||||
|
||||
//! Prototype for comparators
|
||||
class integer_comparator
|
||||
{
|
||||
public:
|
||||
|
||||
template<class T>
|
||||
inline int operator() ( const T& a, const T& b )
|
||||
public:
|
||||
template <class T>
|
||||
inline int operator()(const T& a, const T& b)
|
||||
{
|
||||
return (int)(a-b);
|
||||
return (int)(a - b);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -65,20 +63,19 @@ class integer_comparator
|
||||
class uint_key_func
|
||||
{
|
||||
public:
|
||||
template<class T>
|
||||
inline GUINT operator()( const T& a)
|
||||
template <class T>
|
||||
inline GUINT operator()(const T& a)
|
||||
{
|
||||
return (GUINT)a;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//!Prototype for copying elements
|
||||
class copy_elements_func
|
||||
{
|
||||
public:
|
||||
template<class T>
|
||||
inline void operator()(T& a,T& b)
|
||||
template <class T>
|
||||
inline void operator()(T& a, T& b)
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
@@ -88,34 +85,33 @@ public:
|
||||
class memcopy_elements_func
|
||||
{
|
||||
public:
|
||||
template<class T>
|
||||
inline void operator()(T& a,T& b)
|
||||
template <class T>
|
||||
inline void operator()(T& a, T& b)
|
||||
{
|
||||
gim_simd_memcpy(&a,&b,sizeof(T));
|
||||
gim_simd_memcpy(&a, &b, sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! @{
|
||||
struct GIM_RSORT_TOKEN
|
||||
{
|
||||
GUINT m_key;
|
||||
GUINT m_value;
|
||||
GIM_RSORT_TOKEN()
|
||||
{
|
||||
}
|
||||
GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken)
|
||||
{
|
||||
m_key = rtoken.m_key;
|
||||
m_value = rtoken.m_value;
|
||||
}
|
||||
GUINT m_key;
|
||||
GUINT m_value;
|
||||
GIM_RSORT_TOKEN()
|
||||
{
|
||||
}
|
||||
GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken)
|
||||
{
|
||||
m_key = rtoken.m_key;
|
||||
m_value = rtoken.m_value;
|
||||
}
|
||||
|
||||
inline bool operator <(const GIM_RSORT_TOKEN& other) const
|
||||
inline bool operator<(const GIM_RSORT_TOKEN& other) const
|
||||
{
|
||||
return (m_key < other.m_key);
|
||||
}
|
||||
|
||||
inline bool operator >(const GIM_RSORT_TOKEN& other) const
|
||||
inline bool operator>(const GIM_RSORT_TOKEN& other) const
|
||||
{
|
||||
return (m_key > other.m_key);
|
||||
}
|
||||
@@ -124,33 +120,28 @@ struct GIM_RSORT_TOKEN
|
||||
//! Prototype for comparators
|
||||
class GIM_RSORT_TOKEN_COMPARATOR
|
||||
{
|
||||
public:
|
||||
|
||||
inline int operator()( const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b )
|
||||
public:
|
||||
inline int operator()(const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b)
|
||||
{
|
||||
return (int)((a.m_key) - (b.m_key));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define kHist 2048
|
||||
// ---- utils for accessing 11-bit quantities
|
||||
#define D11_0(x) (x & 0x7FF)
|
||||
#define D11_1(x) (x >> 11 & 0x7FF)
|
||||
#define D11_2(x) (x >> 22 )
|
||||
|
||||
|
||||
#define D11_0(x) (x & 0x7FF)
|
||||
#define D11_1(x) (x >> 11 & 0x7FF)
|
||||
#define D11_2(x) (x >> 22)
|
||||
|
||||
///Radix sort for unsigned integer keys
|
||||
inline void gim_radix_sort_rtokens(
|
||||
GIM_RSORT_TOKEN * array,
|
||||
GIM_RSORT_TOKEN * sorted, GUINT element_count)
|
||||
GIM_RSORT_TOKEN* array,
|
||||
GIM_RSORT_TOKEN* sorted, GUINT element_count)
|
||||
{
|
||||
GUINT i;
|
||||
GUINT b0[kHist * 3];
|
||||
GUINT *b1 = b0 + kHist;
|
||||
GUINT *b2 = b1 + kHist;
|
||||
GUINT* b1 = b0 + kHist;
|
||||
GUINT* b2 = b1 + kHist;
|
||||
for (i = 0; i < kHist * 3; ++i)
|
||||
{
|
||||
b0[i] = 0;
|
||||
@@ -159,10 +150,10 @@ inline void gim_radix_sort_rtokens(
|
||||
GUINT pos;
|
||||
for (i = 0; i < element_count; ++i)
|
||||
{
|
||||
fi = array[i].m_key;
|
||||
b0[D11_0(fi)] ++;
|
||||
b1[D11_1(fi)] ++;
|
||||
b2[D11_2(fi)] ++;
|
||||
fi = array[i].m_key;
|
||||
b0[D11_0(fi)]++;
|
||||
b1[D11_1(fi)]++;
|
||||
b2[D11_2(fi)]++;
|
||||
}
|
||||
{
|
||||
GUINT sum0 = 0, sum1 = 0, sum2 = 0;
|
||||
@@ -182,7 +173,7 @@ inline void gim_radix_sort_rtokens(
|
||||
}
|
||||
for (i = 0; i < element_count; ++i)
|
||||
{
|
||||
fi = array[i].m_key;
|
||||
fi = array[i].m_key;
|
||||
pos = D11_0(fi);
|
||||
pos = ++b0[pos];
|
||||
sorted[pos].m_key = array[i].m_key;
|
||||
@@ -190,7 +181,7 @@ inline void gim_radix_sort_rtokens(
|
||||
}
|
||||
for (i = 0; i < element_count; ++i)
|
||||
{
|
||||
fi = sorted[i].m_key;
|
||||
fi = sorted[i].m_key;
|
||||
pos = D11_1(fi);
|
||||
pos = ++b1[pos];
|
||||
array[pos].m_key = sorted[i].m_key;
|
||||
@@ -198,7 +189,7 @@ inline void gim_radix_sort_rtokens(
|
||||
}
|
||||
for (i = 0; i < element_count; ++i)
|
||||
{
|
||||
fi = array[i].m_key;
|
||||
fi = array[i].m_key;
|
||||
pos = D11_2(fi);
|
||||
pos = ++b2[pos];
|
||||
sorted[pos].m_key = array[i].m_key;
|
||||
@@ -206,9 +197,6 @@ inline void gim_radix_sort_rtokens(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// Get the sorted tokens from an array. For generic use. Tokens are IRR_RSORT_TOKEN
|
||||
/*!
|
||||
*\param array Array of elements to sort
|
||||
@@ -216,21 +204,21 @@ inline void gim_radix_sort_rtokens(
|
||||
*\param element_count element count
|
||||
*\param uintkey_macro Functor which retrieves the integer representation of an array element
|
||||
*/
|
||||
template<typename T, class GETKEY_CLASS>
|
||||
template <typename T, class GETKEY_CLASS>
|
||||
void gim_radix_sort_array_tokens(
|
||||
T* array ,
|
||||
GIM_RSORT_TOKEN * sorted_tokens,
|
||||
GUINT element_count,GETKEY_CLASS uintkey_macro)
|
||||
T* array,
|
||||
GIM_RSORT_TOKEN* sorted_tokens,
|
||||
GUINT element_count, GETKEY_CLASS uintkey_macro)
|
||||
{
|
||||
GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
|
||||
for (GUINT _i=0;_i<element_count;++_i)
|
||||
{
|
||||
_unsorted[_i].m_key = uintkey_macro(array[_i]);
|
||||
_unsorted[_i].m_value = _i;
|
||||
}
|
||||
gim_radix_sort_rtokens(_unsorted,sorted_tokens,element_count);
|
||||
gim_free(_unsorted);
|
||||
gim_free(_unsorted);
|
||||
GIM_RSORT_TOKEN* _unsorted = (GIM_RSORT_TOKEN*)gim_alloc(sizeof(GIM_RSORT_TOKEN) * element_count);
|
||||
for (GUINT _i = 0; _i < element_count; ++_i)
|
||||
{
|
||||
_unsorted[_i].m_key = uintkey_macro(array[_i]);
|
||||
_unsorted[_i].m_value = _i;
|
||||
}
|
||||
gim_radix_sort_rtokens(_unsorted, sorted_tokens, element_count);
|
||||
gim_free(_unsorted);
|
||||
gim_free(_unsorted);
|
||||
}
|
||||
|
||||
/// Sorts array in place. For generic use
|
||||
@@ -241,21 +229,21 @@ void gim_radix_sort_array_tokens(
|
||||
\param get_uintkey_macro Macro for extract the Integer value of the element. Similar to SIMPLE_GET_UINTKEY
|
||||
\param copy_elements_macro Macro for copy elements, similar to SIMPLE_COPY_ELEMENTS
|
||||
*/
|
||||
template<typename T, class GETKEY_CLASS, class COPY_CLASS>
|
||||
template <typename T, class GETKEY_CLASS, class COPY_CLASS>
|
||||
void gim_radix_sort(
|
||||
T * array, GUINT element_count,
|
||||
T* array, GUINT element_count,
|
||||
GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro)
|
||||
{
|
||||
GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
|
||||
gim_radix_sort_array_tokens(array,_sorted,element_count,get_uintkey_macro);
|
||||
T * _original_array = (T *) gim_alloc(sizeof(T)*element_count);
|
||||
gim_simd_memcpy(_original_array,array,sizeof(T)*element_count);
|
||||
for (GUINT _i=0;_i<element_count;++_i)
|
||||
{
|
||||
copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);
|
||||
}
|
||||
gim_free(_original_array);
|
||||
gim_free(_sorted);
|
||||
GIM_RSORT_TOKEN* _sorted = (GIM_RSORT_TOKEN*)gim_alloc(sizeof(GIM_RSORT_TOKEN) * element_count);
|
||||
gim_radix_sort_array_tokens(array, _sorted, element_count, get_uintkey_macro);
|
||||
T* _original_array = (T*)gim_alloc(sizeof(T) * element_count);
|
||||
gim_simd_memcpy(_original_array, array, sizeof(T) * element_count);
|
||||
for (GUINT _i = 0; _i < element_count; ++_i)
|
||||
{
|
||||
copy_elements_macro(array[_i], _original_array[_sorted[_i].m_value]);
|
||||
}
|
||||
gim_free(_original_array);
|
||||
gim_free(_sorted);
|
||||
}
|
||||
|
||||
//! Failsafe Iterative binary search,
|
||||
@@ -269,20 +257,20 @@ If the element is not found, it returns the nearest upper element position, may
|
||||
\param _found If true the value has found. Boolean
|
||||
\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value
|
||||
*/
|
||||
template<class T, typename KEYCLASS, typename COMP_CLASS>
|
||||
bool gim_binary_search_ex(
|
||||
const T* _array, GUINT _start_i,
|
||||
GUINT _end_i,GUINT & _result_index,
|
||||
const KEYCLASS & _search_key,
|
||||
COMP_CLASS _comp_macro)
|
||||
template <class T, typename KEYCLASS, typename COMP_CLASS>
|
||||
bool gim_binary_search_ex(
|
||||
const T* _array, GUINT _start_i,
|
||||
GUINT _end_i, GUINT& _result_index,
|
||||
const KEYCLASS& _search_key,
|
||||
COMP_CLASS _comp_macro)
|
||||
{
|
||||
GUINT _k;
|
||||
int _comp_result;
|
||||
GUINT _i = _start_i;
|
||||
GUINT _j = _end_i+1;
|
||||
GUINT _j = _end_i + 1;
|
||||
while (_i < _j)
|
||||
{
|
||||
_k = (_j+_i-1)/2;
|
||||
_k = (_j + _i - 1) / 2;
|
||||
_comp_result = _comp_macro(_array[_k], _search_key);
|
||||
if (_comp_result == 0)
|
||||
{
|
||||
@@ -291,7 +279,7 @@ bool gim_binary_search_ex(
|
||||
}
|
||||
else if (_comp_result < 0)
|
||||
{
|
||||
_i = _k+1;
|
||||
_i = _k + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -302,8 +290,6 @@ bool gim_binary_search_ex(
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Failsafe Iterative binary search,Template version
|
||||
/*!
|
||||
If the element is not found, it returns the nearest upper element position, may be the further position after the last element.
|
||||
@@ -314,26 +300,26 @@ If the element is not found, it returns the nearest upper element position, may
|
||||
\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value
|
||||
\return true if found, else false
|
||||
*/
|
||||
template<class T>
|
||||
template <class T>
|
||||
bool gim_binary_search(
|
||||
const T*_array,GUINT _start_i,
|
||||
GUINT _end_i,const T & _search_key,
|
||||
GUINT & _result_index)
|
||||
const T* _array, GUINT _start_i,
|
||||
GUINT _end_i, const T& _search_key,
|
||||
GUINT& _result_index)
|
||||
{
|
||||
GUINT _i = _start_i;
|
||||
GUINT _j = _end_i+1;
|
||||
GUINT _j = _end_i + 1;
|
||||
GUINT _k;
|
||||
while(_i < _j)
|
||||
while (_i < _j)
|
||||
{
|
||||
_k = (_j+_i-1)/2;
|
||||
if(_array[_k]==_search_key)
|
||||
_k = (_j + _i - 1) / 2;
|
||||
if (_array[_k] == _search_key)
|
||||
{
|
||||
_result_index = _k;
|
||||
return true;
|
||||
}
|
||||
else if (_array[_k]<_search_key)
|
||||
else if (_array[_k] < _search_key)
|
||||
{
|
||||
_i = _k+1;
|
||||
_i = _k + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -344,27 +330,25 @@ bool gim_binary_search(
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
|
||||
template <typename T, typename COMP_CLASS>
|
||||
void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc)
|
||||
void gim_down_heap(T* pArr, GUINT k, GUINT n, COMP_CLASS CompareFunc)
|
||||
{
|
||||
/* PRE: a[k+1..N] is a heap */
|
||||
/* POST: a[k..N] is a heap */
|
||||
|
||||
T temp = pArr[k - 1];
|
||||
/* k has child(s) */
|
||||
while (k <= n/2)
|
||||
while (k <= n / 2)
|
||||
{
|
||||
int child = 2*k;
|
||||
int child = 2 * k;
|
||||
|
||||
if ((child < (int)n) && CompareFunc(pArr[child - 1] , pArr[child])<0)
|
||||
if ((child < (int)n) && CompareFunc(pArr[child - 1], pArr[child]) < 0)
|
||||
{
|
||||
child++;
|
||||
}
|
||||
/* pick larger child */
|
||||
if (CompareFunc(temp , pArr[child - 1])<0)
|
||||
if (CompareFunc(temp, pArr[child - 1]) < 0)
|
||||
{
|
||||
/* move child up */
|
||||
pArr[k - 1] = pArr[child - 1];
|
||||
@@ -378,29 +362,25 @@ void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc)
|
||||
pArr[k - 1] = temp;
|
||||
} /*downHeap*/
|
||||
|
||||
|
||||
template <typename T, typename COMP_CLASS>
|
||||
void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc)
|
||||
void gim_heap_sort(T* pArr, GUINT element_count, COMP_CLASS CompareFunc)
|
||||
{
|
||||
/* sort a[0..N-1], N.B. 0 to N-1 */
|
||||
GUINT k;
|
||||
GUINT n = element_count;
|
||||
for (k = n/2; k > 0; k--)
|
||||
for (k = n / 2; k > 0; k--)
|
||||
{
|
||||
gim_down_heap(pArr, k, n, CompareFunc);
|
||||
}
|
||||
|
||||
/* a[1..N] is now a heap */
|
||||
while ( n>=2 )
|
||||
while (n >= 2)
|
||||
{
|
||||
gim_swap_elements(pArr,0,n-1); /* largest of a[0..n-1] */
|
||||
gim_swap_elements(pArr, 0, n - 1); /* largest of a[0..n-1] */
|
||||
--n;
|
||||
/* restore a[1..i-1] heap */
|
||||
gim_down_heap(pArr, 1, n, CompareFunc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // GIM_RADIXSORT_H_INCLUDED
|
||||
#endif // GIM_RADIXSORT_H_INCLUDED
|
||||
|
||||
@@ -33,15 +33,13 @@ email: projectileman@yahoo.com
|
||||
|
||||
#include "gim_tri_collision.h"
|
||||
|
||||
|
||||
#define TRI_LOCAL_EPSILON 0.000001f
|
||||
#define MIN_EDGE_EDGE_DIS 0.00001f
|
||||
|
||||
|
||||
class GIM_TRIANGLE_CALCULATION_CACHE
|
||||
{
|
||||
public:
|
||||
GREAL margin;
|
||||
GREAL margin;
|
||||
btVector3 tu_vertices[3];
|
||||
btVector3 tv_vertices[3];
|
||||
btVector4 tu_plane;
|
||||
@@ -55,46 +53,47 @@ public:
|
||||
GREAL du0du2;
|
||||
GREAL dv[4];
|
||||
GREAL dv0dv1;
|
||||
GREAL dv0dv2;
|
||||
GREAL dv0dv2;
|
||||
btVector3 temp_points[MAX_TRI_CLIPPING];
|
||||
btVector3 temp_points1[MAX_TRI_CLIPPING];
|
||||
btVector3 contact_points[MAX_TRI_CLIPPING];
|
||||
|
||||
|
||||
|
||||
//! if returns false, the faces are paralele
|
||||
SIMD_FORCE_INLINE bool compute_intervals(
|
||||
const GREAL &D0,
|
||||
const GREAL &D1,
|
||||
const GREAL &D2,
|
||||
const GREAL &D0D1,
|
||||
const GREAL &D0D2,
|
||||
GREAL & scale_edge0,
|
||||
GREAL & scale_edge1,
|
||||
GUINT &edge_index0,
|
||||
GUINT &edge_index1)
|
||||
const GREAL &D0,
|
||||
const GREAL &D1,
|
||||
const GREAL &D2,
|
||||
const GREAL &D0D1,
|
||||
const GREAL &D0D2,
|
||||
GREAL &scale_edge0,
|
||||
GREAL &scale_edge1,
|
||||
GUINT &edge_index0,
|
||||
GUINT &edge_index1)
|
||||
{
|
||||
if(D0D1>0.0f)
|
||||
if (D0D1 > 0.0f)
|
||||
{
|
||||
/* here we know that D0D2<=0.0 */
|
||||
/* that is D0, D1 are on the same side, D2 on the other or on the plane */
|
||||
scale_edge0 = -D2/(D0-D2);
|
||||
scale_edge1 = -D1/(D2-D1);
|
||||
edge_index0 = 2;edge_index1 = 1;
|
||||
scale_edge0 = -D2 / (D0 - D2);
|
||||
scale_edge1 = -D1 / (D2 - D1);
|
||||
edge_index0 = 2;
|
||||
edge_index1 = 1;
|
||||
}
|
||||
else if(D0D2>0.0f)
|
||||
else if (D0D2 > 0.0f)
|
||||
{
|
||||
/* here we know that d0d1<=0.0 */
|
||||
scale_edge0 = -D0/(D1-D0);
|
||||
scale_edge1 = -D1/(D2-D1);
|
||||
edge_index0 = 0;edge_index1 = 1;
|
||||
scale_edge0 = -D0 / (D1 - D0);
|
||||
scale_edge1 = -D1 / (D2 - D1);
|
||||
edge_index0 = 0;
|
||||
edge_index1 = 1;
|
||||
}
|
||||
else if(D1*D2>0.0f || D0!=0.0f)
|
||||
else if (D1 * D2 > 0.0f || D0 != 0.0f)
|
||||
{
|
||||
/* here we know that d0d1<=0.0 or that D0!=0.0 */
|
||||
scale_edge0 = -D0/(D1-D0);
|
||||
scale_edge1 = -D2/(D0-D2);
|
||||
edge_index0 = 0 ;edge_index1 = 2;
|
||||
scale_edge0 = -D0 / (D1 - D0);
|
||||
scale_edge1 = -D2 / (D0 - D2);
|
||||
edge_index0 = 0;
|
||||
edge_index1 = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -103,46 +102,44 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! clip triangle
|
||||
/*!
|
||||
*/
|
||||
SIMD_FORCE_INLINE GUINT clip_triangle(
|
||||
const btVector4 & tri_plane,
|
||||
const btVector3 * tripoints,
|
||||
const btVector3 * srcpoints,
|
||||
btVector3 * clip_points)
|
||||
const btVector4 &tri_plane,
|
||||
const btVector3 *tripoints,
|
||||
const btVector3 *srcpoints,
|
||||
btVector3 *clip_points)
|
||||
{
|
||||
// edge 0
|
||||
|
||||
btVector4 edgeplane;
|
||||
|
||||
EDGE_PLANE(tripoints[0],tripoints[1],tri_plane,edgeplane);
|
||||
EDGE_PLANE(tripoints[0], tripoints[1], tri_plane, edgeplane);
|
||||
|
||||
GUINT clipped_count = PLANE_CLIP_TRIANGLE3D(
|
||||
edgeplane,srcpoints[0],srcpoints[1],srcpoints[2],temp_points);
|
||||
edgeplane, srcpoints[0], srcpoints[1], srcpoints[2], temp_points);
|
||||
|
||||
if(clipped_count == 0) return 0;
|
||||
if (clipped_count == 0) return 0;
|
||||
|
||||
// edge 1
|
||||
|
||||
EDGE_PLANE(tripoints[1],tripoints[2],tri_plane,edgeplane);
|
||||
EDGE_PLANE(tripoints[1], tripoints[2], tri_plane, edgeplane);
|
||||
|
||||
clipped_count = PLANE_CLIP_POLYGON3D(
|
||||
edgeplane,temp_points,clipped_count,temp_points1);
|
||||
edgeplane, temp_points, clipped_count, temp_points1);
|
||||
|
||||
if(clipped_count == 0) return 0;
|
||||
if (clipped_count == 0) return 0;
|
||||
|
||||
// edge 2
|
||||
|
||||
EDGE_PLANE(tripoints[2],tripoints[0],tri_plane,edgeplane);
|
||||
EDGE_PLANE(tripoints[2], tripoints[0], tri_plane, edgeplane);
|
||||
|
||||
clipped_count = PLANE_CLIP_POLYGON3D(
|
||||
edgeplane,temp_points1,clipped_count,clip_points);
|
||||
edgeplane, temp_points1, clipped_count, clip_points);
|
||||
|
||||
return clipped_count;
|
||||
|
||||
|
||||
/*GUINT i0 = (tri_plane.closestAxis()+1)%3;
|
||||
GUINT i1 = (i0+1)%3;
|
||||
// edge 0
|
||||
@@ -172,13 +169,13 @@ public:
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void sort_isect(
|
||||
GREAL & isect0,GREAL & isect1,GUINT &e0,GUINT &e1,btVector3 & vec0,btVector3 & vec1)
|
||||
GREAL &isect0, GREAL &isect1, GUINT &e0, GUINT &e1, btVector3 &vec0, btVector3 &vec1)
|
||||
{
|
||||
if(isect1<isect0)
|
||||
if (isect1 < isect0)
|
||||
{
|
||||
//swap
|
||||
GIM_SWAP_NUMBERS(isect0,isect1);
|
||||
GIM_SWAP_NUMBERS(e0,e1);
|
||||
GIM_SWAP_NUMBERS(isect0, isect1);
|
||||
GIM_SWAP_NUMBERS(e0, e1);
|
||||
btVector3 tmp = vec0;
|
||||
vec0 = vec1;
|
||||
vec1 = tmp;
|
||||
@@ -202,53 +199,52 @@ public:
|
||||
// Compute direction of intersection line
|
||||
edge_edge_dir = tu_plane.cross(tv_plane);
|
||||
GREAL Dlen;
|
||||
VEC_LENGTH(edge_edge_dir,Dlen);
|
||||
VEC_LENGTH(edge_edge_dir, Dlen);
|
||||
|
||||
if(Dlen<0.0001)
|
||||
if (Dlen < 0.0001)
|
||||
{
|
||||
return 0; //faces near paralele
|
||||
return 0; //faces near paralele
|
||||
}
|
||||
|
||||
edge_edge_dir*= 1/Dlen;//normalize
|
||||
|
||||
edge_edge_dir *= 1 / Dlen; //normalize
|
||||
|
||||
// Compute interval for triangle 1
|
||||
GUINT tu_e0,tu_e1;//edge indices
|
||||
GREAL tu_scale_e0,tu_scale_e1;//edge scale
|
||||
if(!compute_intervals(du[0],du[1],du[2],
|
||||
du0du1,du0du2,tu_scale_e0,tu_scale_e1,tu_e0,tu_e1)) return 0;
|
||||
GUINT tu_e0, tu_e1; //edge indices
|
||||
GREAL tu_scale_e0, tu_scale_e1; //edge scale
|
||||
if (!compute_intervals(du[0], du[1], du[2],
|
||||
du0du1, du0du2, tu_scale_e0, tu_scale_e1, tu_e0, tu_e1)) return 0;
|
||||
|
||||
// Compute interval for triangle 2
|
||||
GUINT tv_e0,tv_e1;//edge indices
|
||||
GREAL tv_scale_e0,tv_scale_e1;//edge scale
|
||||
GUINT tv_e0, tv_e1; //edge indices
|
||||
GREAL tv_scale_e0, tv_scale_e1; //edge scale
|
||||
|
||||
if(!compute_intervals(dv[0],dv[1],dv[2],
|
||||
dv0dv1,dv0dv2,tv_scale_e0,tv_scale_e1,tv_e0,tv_e1)) return 0;
|
||||
if (!compute_intervals(dv[0], dv[1], dv[2],
|
||||
dv0dv1, dv0dv2, tv_scale_e0, tv_scale_e1, tv_e0, tv_e1)) return 0;
|
||||
|
||||
//proyected vertices
|
||||
btVector3 up_e0 = tu_vertices[tu_e0].lerp(tu_vertices[(tu_e0+1)%3],tu_scale_e0);
|
||||
btVector3 up_e1 = tu_vertices[tu_e1].lerp(tu_vertices[(tu_e1+1)%3],tu_scale_e1);
|
||||
btVector3 up_e0 = tu_vertices[tu_e0].lerp(tu_vertices[(tu_e0 + 1) % 3], tu_scale_e0);
|
||||
btVector3 up_e1 = tu_vertices[tu_e1].lerp(tu_vertices[(tu_e1 + 1) % 3], tu_scale_e1);
|
||||
|
||||
btVector3 vp_e0 = tv_vertices[tv_e0].lerp(tv_vertices[(tv_e0+1)%3],tv_scale_e0);
|
||||
btVector3 vp_e1 = tv_vertices[tv_e1].lerp(tv_vertices[(tv_e1+1)%3],tv_scale_e1);
|
||||
btVector3 vp_e0 = tv_vertices[tv_e0].lerp(tv_vertices[(tv_e0 + 1) % 3], tv_scale_e0);
|
||||
btVector3 vp_e1 = tv_vertices[tv_e1].lerp(tv_vertices[(tv_e1 + 1) % 3], tv_scale_e1);
|
||||
|
||||
//proyected intervals
|
||||
GREAL isect_u[] = {up_e0.dot(edge_edge_dir),up_e1.dot(edge_edge_dir)};
|
||||
GREAL isect_v[] = {vp_e0.dot(edge_edge_dir),vp_e1.dot(edge_edge_dir)};
|
||||
GREAL isect_u[] = {up_e0.dot(edge_edge_dir), up_e1.dot(edge_edge_dir)};
|
||||
GREAL isect_v[] = {vp_e0.dot(edge_edge_dir), vp_e1.dot(edge_edge_dir)};
|
||||
|
||||
sort_isect(isect_u[0],isect_u[1],tu_e0,tu_e1,up_e0,up_e1);
|
||||
sort_isect(isect_v[0],isect_v[1],tv_e0,tv_e1,vp_e0,vp_e1);
|
||||
sort_isect(isect_u[0], isect_u[1], tu_e0, tu_e1, up_e0, up_e1);
|
||||
sort_isect(isect_v[0], isect_v[1], tv_e0, tv_e1, vp_e0, vp_e1);
|
||||
|
||||
const GREAL midpoint_u = 0.5f*(isect_u[0]+isect_u[1]); // midpoint
|
||||
const GREAL midpoint_v = 0.5f*(isect_v[0]+isect_v[1]); // midpoint
|
||||
const GREAL midpoint_u = 0.5f * (isect_u[0] + isect_u[1]); // midpoint
|
||||
const GREAL midpoint_v = 0.5f * (isect_v[0] + isect_v[1]); // midpoint
|
||||
|
||||
if(midpoint_u<midpoint_v)
|
||||
if (midpoint_u < midpoint_v)
|
||||
{
|
||||
if(isect_u[1]>=isect_v[1]) // face U casts face V
|
||||
if (isect_u[1] >= isect_v[1]) // face U casts face V
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if(isect_v[0]<=isect_u[0]) // face V casts face U
|
||||
else if (isect_v[0] <= isect_u[0]) // face V casts face U
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
@@ -257,32 +253,31 @@ public:
|
||||
closest_point_v = vp_e0;
|
||||
// calc edges and separation
|
||||
|
||||
if(isect_u[1]+ MIN_EDGE_EDGE_DIS<isect_v[0]) //calc distance between two lines instead
|
||||
if (isect_u[1] + MIN_EDGE_EDGE_DIS < isect_v[0]) //calc distance between two lines instead
|
||||
{
|
||||
SEGMENT_COLLISION(
|
||||
tu_vertices[tu_e1],tu_vertices[(tu_e1+1)%3],
|
||||
tv_vertices[tv_e0],tv_vertices[(tv_e0+1)%3],
|
||||
tu_vertices[tu_e1], tu_vertices[(tu_e1 + 1) % 3],
|
||||
tv_vertices[tv_e0], tv_vertices[(tv_e0 + 1) % 3],
|
||||
closest_point_u,
|
||||
closest_point_v);
|
||||
|
||||
edge_edge_dir = closest_point_u-closest_point_v;
|
||||
VEC_LENGTH(edge_edge_dir,distances[2]);
|
||||
edge_edge_dir *= 1.0f/distances[2];// normalize
|
||||
edge_edge_dir = closest_point_u - closest_point_v;
|
||||
VEC_LENGTH(edge_edge_dir, distances[2]);
|
||||
edge_edge_dir *= 1.0f / distances[2]; // normalize
|
||||
}
|
||||
else
|
||||
{
|
||||
distances[2] = isect_v[0]-isect_u[1];//distance negative
|
||||
//edge_edge_dir *= -1.0f; //normal pointing from V to U
|
||||
distances[2] = isect_v[0] - isect_u[1]; //distance negative
|
||||
//edge_edge_dir *= -1.0f; //normal pointing from V to U
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isect_v[1]>=isect_u[1]) // face V casts face U
|
||||
if (isect_v[1] >= isect_u[1]) // face V casts face U
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else if(isect_u[0]<=isect_v[0]) // face U casts face V
|
||||
else if (isect_u[0] <= isect_v[0]) // face U casts face V
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -291,41 +286,39 @@ public:
|
||||
closest_point_v = vp_e1;
|
||||
// calc edges and separation
|
||||
|
||||
if(isect_v[1]+MIN_EDGE_EDGE_DIS<isect_u[0]) //calc distance between two lines instead
|
||||
if (isect_v[1] + MIN_EDGE_EDGE_DIS < isect_u[0]) //calc distance between two lines instead
|
||||
{
|
||||
SEGMENT_COLLISION(
|
||||
tu_vertices[tu_e0],tu_vertices[(tu_e0+1)%3],
|
||||
tv_vertices[tv_e1],tv_vertices[(tv_e1+1)%3],
|
||||
tu_vertices[tu_e0], tu_vertices[(tu_e0 + 1) % 3],
|
||||
tv_vertices[tv_e1], tv_vertices[(tv_e1 + 1) % 3],
|
||||
closest_point_u,
|
||||
closest_point_v);
|
||||
|
||||
edge_edge_dir = closest_point_u-closest_point_v;
|
||||
VEC_LENGTH(edge_edge_dir,distances[2]);
|
||||
edge_edge_dir *= 1.0f/distances[2];// normalize
|
||||
edge_edge_dir = closest_point_u - closest_point_v;
|
||||
VEC_LENGTH(edge_edge_dir, distances[2]);
|
||||
edge_edge_dir *= 1.0f / distances[2]; // normalize
|
||||
}
|
||||
else
|
||||
{
|
||||
distances[2] = isect_u[0]-isect_v[1];//distance negative
|
||||
//edge_edge_dir *= -1.0f; //normal pointing from V to U
|
||||
distances[2] = isect_u[0] - isect_v[1]; //distance negative
|
||||
//edge_edge_dir *= -1.0f; //normal pointing from V to U
|
||||
}
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
//! collides by two sides
|
||||
SIMD_FORCE_INLINE bool triangle_collision(
|
||||
const btVector3 & u0,
|
||||
const btVector3 & u1,
|
||||
const btVector3 & u2,
|
||||
GREAL margin_u,
|
||||
const btVector3 & v0,
|
||||
const btVector3 & v1,
|
||||
const btVector3 & v2,
|
||||
GREAL margin_v,
|
||||
GIM_TRIANGLE_CONTACT_DATA & contacts)
|
||||
const btVector3 &u0,
|
||||
const btVector3 &u1,
|
||||
const btVector3 &u2,
|
||||
GREAL margin_u,
|
||||
const btVector3 &v0,
|
||||
const btVector3 &v1,
|
||||
const btVector3 &v2,
|
||||
GREAL margin_v,
|
||||
GIM_TRIANGLE_CONTACT_DATA &contacts)
|
||||
{
|
||||
|
||||
margin = margin_u + margin_v;
|
||||
|
||||
tu_vertices[0] = u0;
|
||||
@@ -339,103 +332,99 @@ public:
|
||||
//create planes
|
||||
// plane v vs U points
|
||||
|
||||
TRIANGLE_PLANE(tv_vertices[0],tv_vertices[1],tv_vertices[2],tv_plane);
|
||||
|
||||
du[0] = DISTANCE_PLANE_POINT(tv_plane,tu_vertices[0]);
|
||||
du[1] = DISTANCE_PLANE_POINT(tv_plane,tu_vertices[1]);
|
||||
du[2] = DISTANCE_PLANE_POINT(tv_plane,tu_vertices[2]);
|
||||
TRIANGLE_PLANE(tv_vertices[0], tv_vertices[1], tv_vertices[2], tv_plane);
|
||||
|
||||
du[0] = DISTANCE_PLANE_POINT(tv_plane, tu_vertices[0]);
|
||||
du[1] = DISTANCE_PLANE_POINT(tv_plane, tu_vertices[1]);
|
||||
du[2] = DISTANCE_PLANE_POINT(tv_plane, tu_vertices[2]);
|
||||
|
||||
du0du1 = du[0] * du[1];
|
||||
du0du2 = du[0] * du[2];
|
||||
|
||||
|
||||
if(du0du1>0.0f && du0du2>0.0f) // same sign on all of them + not equal 0 ?
|
||||
if (du0du1 > 0.0f && du0du2 > 0.0f) // same sign on all of them + not equal 0 ?
|
||||
{
|
||||
if(du[0]<0) //we need test behind the triangle plane
|
||||
if (du[0] < 0) //we need test behind the triangle plane
|
||||
{
|
||||
distances[0] = GIM_MAX3(du[0],du[1],du[2]);
|
||||
distances[0] = GIM_MAX3(du[0], du[1], du[2]);
|
||||
distances[0] = -distances[0];
|
||||
if(distances[0]>margin) return false; //never intersect
|
||||
if (distances[0] > margin) return false; //never intersect
|
||||
|
||||
//reorder triangle v
|
||||
VEC_SWAP(tv_vertices[0],tv_vertices[1]);
|
||||
VEC_SCALE_4(tv_plane,-1.0f,tv_plane);
|
||||
VEC_SWAP(tv_vertices[0], tv_vertices[1]);
|
||||
VEC_SCALE_4(tv_plane, -1.0f, tv_plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
distances[0] = GIM_MIN3(du[0],du[1],du[2]);
|
||||
if(distances[0]>margin) return false; //never intersect
|
||||
distances[0] = GIM_MIN3(du[0], du[1], du[2]);
|
||||
if (distances[0] > margin) return false; //never intersect
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Look if we need to invert the triangle
|
||||
distances[0] = (du[0]+du[1]+du[2])/3.0f; //centroid
|
||||
distances[0] = (du[0] + du[1] + du[2]) / 3.0f; //centroid
|
||||
|
||||
if(distances[0]<0.0f)
|
||||
if (distances[0] < 0.0f)
|
||||
{
|
||||
//reorder triangle v
|
||||
VEC_SWAP(tv_vertices[0],tv_vertices[1]);
|
||||
VEC_SCALE_4(tv_plane,-1.0f,tv_plane);
|
||||
VEC_SWAP(tv_vertices[0], tv_vertices[1]);
|
||||
VEC_SCALE_4(tv_plane, -1.0f, tv_plane);
|
||||
|
||||
distances[0] = GIM_MAX3(du[0],du[1],du[2]);
|
||||
distances[0] = GIM_MAX3(du[0], du[1], du[2]);
|
||||
distances[0] = -distances[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
distances[0] = GIM_MIN3(du[0],du[1],du[2]);
|
||||
distances[0] = GIM_MIN3(du[0], du[1], du[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// plane U vs V points
|
||||
|
||||
TRIANGLE_PLANE(tu_vertices[0],tu_vertices[1],tu_vertices[2],tu_plane);
|
||||
TRIANGLE_PLANE(tu_vertices[0], tu_vertices[1], tu_vertices[2], tu_plane);
|
||||
|
||||
dv[0] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[0]);
|
||||
dv[1] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[1]);
|
||||
dv[2] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[2]);
|
||||
dv[0] = DISTANCE_PLANE_POINT(tu_plane, tv_vertices[0]);
|
||||
dv[1] = DISTANCE_PLANE_POINT(tu_plane, tv_vertices[1]);
|
||||
dv[2] = DISTANCE_PLANE_POINT(tu_plane, tv_vertices[2]);
|
||||
|
||||
dv0dv1 = dv[0] * dv[1];
|
||||
dv0dv2 = dv[0] * dv[2];
|
||||
|
||||
|
||||
if(dv0dv1>0.0f && dv0dv2>0.0f) // same sign on all of them + not equal 0 ?
|
||||
if (dv0dv1 > 0.0f && dv0dv2 > 0.0f) // same sign on all of them + not equal 0 ?
|
||||
{
|
||||
if(dv[0]<0) //we need test behind the triangle plane
|
||||
if (dv[0] < 0) //we need test behind the triangle plane
|
||||
{
|
||||
distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]);
|
||||
distances[1] = GIM_MAX3(dv[0], dv[1], dv[2]);
|
||||
distances[1] = -distances[1];
|
||||
if(distances[1]>margin) return false; //never intersect
|
||||
if (distances[1] > margin) return false; //never intersect
|
||||
|
||||
//reorder triangle u
|
||||
VEC_SWAP(tu_vertices[0],tu_vertices[1]);
|
||||
VEC_SCALE_4(tu_plane,-1.0f,tu_plane);
|
||||
VEC_SWAP(tu_vertices[0], tu_vertices[1]);
|
||||
VEC_SCALE_4(tu_plane, -1.0f, tu_plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]);
|
||||
if(distances[1]>margin) return false; //never intersect
|
||||
distances[1] = GIM_MIN3(dv[0], dv[1], dv[2]);
|
||||
if (distances[1] > margin) return false; //never intersect
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Look if we need to invert the triangle
|
||||
distances[1] = (dv[0]+dv[1]+dv[2])/3.0f; //centroid
|
||||
distances[1] = (dv[0] + dv[1] + dv[2]) / 3.0f; //centroid
|
||||
|
||||
if(distances[1]<0.0f)
|
||||
if (distances[1] < 0.0f)
|
||||
{
|
||||
//reorder triangle v
|
||||
VEC_SWAP(tu_vertices[0],tu_vertices[1]);
|
||||
VEC_SCALE_4(tu_plane,-1.0f,tu_plane);
|
||||
VEC_SWAP(tu_vertices[0], tu_vertices[1]);
|
||||
VEC_SCALE_4(tu_plane, -1.0f, tu_plane);
|
||||
|
||||
distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]);
|
||||
distances[1] = GIM_MAX3(dv[0], dv[1], dv[2]);
|
||||
distances[1] = -distances[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]);
|
||||
distances[1] = GIM_MIN3(dv[0], dv[1], dv[2]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,47 +437,44 @@ public:
|
||||
}
|
||||
else
|
||||
{*/
|
||||
bl = 0;
|
||||
if(distances[0]<distances[1]) bl = 1;
|
||||
bl = 0;
|
||||
if (distances[0] < distances[1]) bl = 1;
|
||||
//}
|
||||
|
||||
if(bl==2) //edge edge separation
|
||||
if (bl == 2) //edge edge separation
|
||||
{
|
||||
if(distances[2]>margin) return false;
|
||||
if (distances[2] > margin) return false;
|
||||
|
||||
contacts.m_penetration_depth = -distances[2] + margin;
|
||||
contacts.m_points[0] = closest_point_v;
|
||||
contacts.m_point_count = 1;
|
||||
VEC_COPY(contacts.m_separating_normal,edge_edge_dir);
|
||||
VEC_COPY(contacts.m_separating_normal, edge_edge_dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//clip face against other
|
||||
|
||||
|
||||
GUINT point_count;
|
||||
//TODO
|
||||
if(bl == 0) //clip U points against V
|
||||
if (bl == 0) //clip U points against V
|
||||
{
|
||||
point_count = clip_triangle(tv_plane,tv_vertices,tu_vertices,contact_points);
|
||||
if(point_count == 0) return false;
|
||||
contacts.merge_points(tv_plane,margin,contact_points,point_count);
|
||||
point_count = clip_triangle(tv_plane, tv_vertices, tu_vertices, contact_points);
|
||||
if (point_count == 0) return false;
|
||||
contacts.merge_points(tv_plane, margin, contact_points, point_count);
|
||||
}
|
||||
else //clip V points against U
|
||||
else //clip V points against U
|
||||
{
|
||||
point_count = clip_triangle(tu_plane,tu_vertices,tv_vertices,contact_points);
|
||||
if(point_count == 0) return false;
|
||||
contacts.merge_points(tu_plane,margin,contact_points,point_count);
|
||||
point_count = clip_triangle(tu_plane, tu_vertices, tv_vertices, contact_points);
|
||||
if (point_count == 0) return false;
|
||||
contacts.merge_points(tu_plane, margin, contact_points, point_count);
|
||||
contacts.m_separating_normal *= -1.f;
|
||||
}
|
||||
if(contacts.m_point_count == 0) return false;
|
||||
if (contacts.m_point_count == 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*class GIM_TRIANGLE_CALCULATION_CACHE
|
||||
{
|
||||
public:
|
||||
@@ -621,20 +607,13 @@ public:
|
||||
|
||||
};*/
|
||||
|
||||
|
||||
|
||||
bool GIM_TRIANGLE::collide_triangle_hard_test(
|
||||
const GIM_TRIANGLE & other,
|
||||
GIM_TRIANGLE_CONTACT_DATA & contact_data) const
|
||||
const GIM_TRIANGLE &other,
|
||||
GIM_TRIANGLE_CONTACT_DATA &contact_data) const
|
||||
{
|
||||
GIM_TRIANGLE_CALCULATION_CACHE calc_cache;
|
||||
GIM_TRIANGLE_CALCULATION_CACHE calc_cache;
|
||||
return calc_cache.triangle_collision(
|
||||
m_vertices[0],m_vertices[1],m_vertices[2],m_margin,
|
||||
other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],other.m_margin,
|
||||
contact_data);
|
||||
|
||||
m_vertices[0], m_vertices[1], m_vertices[2], m_margin,
|
||||
other.m_vertices[0], other.m_vertices[1], other.m_vertices[2], other.m_margin,
|
||||
contact_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -36,8 +36,6 @@ email: projectileman@yahoo.com
|
||||
#include "gim_box_collision.h"
|
||||
#include "gim_clip_polygon.h"
|
||||
|
||||
|
||||
|
||||
#ifndef MAX_TRI_CLIPPING
|
||||
#define MAX_TRI_CLIPPING 16
|
||||
#endif
|
||||
@@ -45,18 +43,18 @@ email: projectileman@yahoo.com
|
||||
//! Structure for collision
|
||||
struct GIM_TRIANGLE_CONTACT_DATA
|
||||
{
|
||||
GREAL m_penetration_depth;
|
||||
GUINT m_point_count;
|
||||
btVector4 m_separating_normal;
|
||||
btVector3 m_points[MAX_TRI_CLIPPING];
|
||||
GREAL m_penetration_depth;
|
||||
GUINT m_point_count;
|
||||
btVector4 m_separating_normal;
|
||||
btVector3 m_points[MAX_TRI_CLIPPING];
|
||||
|
||||
SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT_DATA& other)
|
||||
SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT_DATA &other)
|
||||
{
|
||||
m_penetration_depth = other.m_penetration_depth;
|
||||
m_separating_normal = other.m_separating_normal;
|
||||
m_point_count = other.m_point_count;
|
||||
GUINT i = m_point_count;
|
||||
while(i--)
|
||||
while (i--)
|
||||
{
|
||||
m_points[i] = other.m_points[i];
|
||||
}
|
||||
@@ -66,39 +64,36 @@ struct GIM_TRIANGLE_CONTACT_DATA
|
||||
{
|
||||
}
|
||||
|
||||
GIM_TRIANGLE_CONTACT_DATA(const GIM_TRIANGLE_CONTACT_DATA& other)
|
||||
GIM_TRIANGLE_CONTACT_DATA(const GIM_TRIANGLE_CONTACT_DATA &other)
|
||||
{
|
||||
copy_from(other);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//! classify points that are closer
|
||||
template<typename DISTANCE_FUNC,typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE void mergepoints_generic(const CLASS_PLANE & plane,
|
||||
GREAL margin, const btVector3 * points, GUINT point_count, DISTANCE_FUNC distance_func)
|
||||
{
|
||||
m_point_count = 0;
|
||||
m_penetration_depth= -1000.0f;
|
||||
//! classify points that are closer
|
||||
template <typename DISTANCE_FUNC, typename CLASS_PLANE>
|
||||
SIMD_FORCE_INLINE void mergepoints_generic(const CLASS_PLANE &plane,
|
||||
GREAL margin, const btVector3 *points, GUINT point_count, DISTANCE_FUNC distance_func)
|
||||
{
|
||||
m_point_count = 0;
|
||||
m_penetration_depth = -1000.0f;
|
||||
|
||||
GUINT point_indices[MAX_TRI_CLIPPING];
|
||||
|
||||
GUINT _k;
|
||||
|
||||
for(_k=0;_k<point_count;_k++)
|
||||
for (_k = 0; _k < point_count; _k++)
|
||||
{
|
||||
GREAL _dist = -distance_func(plane,points[_k]) + margin;
|
||||
GREAL _dist = -distance_func(plane, points[_k]) + margin;
|
||||
|
||||
if(_dist>=0.0f)
|
||||
if (_dist >= 0.0f)
|
||||
{
|
||||
if(_dist>m_penetration_depth)
|
||||
if (_dist > m_penetration_depth)
|
||||
{
|
||||
m_penetration_depth = _dist;
|
||||
point_indices[0] = _k;
|
||||
m_point_count=1;
|
||||
m_point_count = 1;
|
||||
}
|
||||
else if((_dist+G_EPSILON)>=m_penetration_depth)
|
||||
else if ((_dist + G_EPSILON) >= m_penetration_depth)
|
||||
{
|
||||
point_indices[m_point_count] = _k;
|
||||
m_point_count++;
|
||||
@@ -106,88 +101,87 @@ struct GIM_TRIANGLE_CONTACT_DATA
|
||||
}
|
||||
}
|
||||
|
||||
for( _k=0;_k<m_point_count;_k++)
|
||||
for (_k = 0; _k < m_point_count; _k++)
|
||||
{
|
||||
m_points[_k] = points[point_indices[_k]];
|
||||
}
|
||||
}
|
||||
|
||||
//! classify points that are closer
|
||||
SIMD_FORCE_INLINE void merge_points(const btVector4 & plane, GREAL margin,
|
||||
const btVector3 * points, GUINT point_count)
|
||||
SIMD_FORCE_INLINE void merge_points(const btVector4 &plane, GREAL margin,
|
||||
const btVector3 *points, GUINT point_count)
|
||||
{
|
||||
m_separating_normal = plane;
|
||||
mergepoints_generic(plane, margin, points, point_count, DISTANCE_PLANE_3D_FUNC());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! Class for colliding triangles
|
||||
class GIM_TRIANGLE
|
||||
{
|
||||
public:
|
||||
btScalar m_margin;
|
||||
btVector3 m_vertices[3];
|
||||
btVector3 m_vertices[3];
|
||||
|
||||
GIM_TRIANGLE():m_margin(0.1f)
|
||||
{
|
||||
}
|
||||
GIM_TRIANGLE() : m_margin(0.1f)
|
||||
{
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE GIM_AABB get_box() const
|
||||
{
|
||||
return GIM_AABB(m_vertices[0],m_vertices[1],m_vertices[2],m_margin);
|
||||
}
|
||||
SIMD_FORCE_INLINE GIM_AABB get_box() const
|
||||
{
|
||||
return GIM_AABB(m_vertices[0], m_vertices[1], m_vertices[2], m_margin);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void get_normal(btVector3 &normal) const
|
||||
{
|
||||
TRIANGLE_NORMAL(m_vertices[0],m_vertices[1],m_vertices[2],normal);
|
||||
}
|
||||
SIMD_FORCE_INLINE void get_normal(btVector3 &normal) const
|
||||
{
|
||||
TRIANGLE_NORMAL(m_vertices[0], m_vertices[1], m_vertices[2], normal);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void get_plane(btVector4 &plane) const
|
||||
{
|
||||
TRIANGLE_PLANE(m_vertices[0],m_vertices[1],m_vertices[2],plane);;
|
||||
}
|
||||
SIMD_FORCE_INLINE void get_plane(btVector4 &plane) const
|
||||
{
|
||||
TRIANGLE_PLANE(m_vertices[0], m_vertices[1], m_vertices[2], plane);
|
||||
;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void apply_transform(const btTransform & trans)
|
||||
{
|
||||
m_vertices[0] = trans(m_vertices[0]);
|
||||
m_vertices[1] = trans(m_vertices[1]);
|
||||
m_vertices[2] = trans(m_vertices[2]);
|
||||
}
|
||||
SIMD_FORCE_INLINE void apply_transform(const btTransform &trans)
|
||||
{
|
||||
m_vertices[0] = trans(m_vertices[0]);
|
||||
m_vertices[1] = trans(m_vertices[1]);
|
||||
m_vertices[2] = trans(m_vertices[2]);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void get_edge_plane(GUINT edge_index,const btVector3 &triangle_normal,btVector4 &plane) const
|
||||
{
|
||||
const btVector3 & e0 = m_vertices[edge_index];
|
||||
const btVector3 & e1 = m_vertices[(edge_index+1)%3];
|
||||
EDGE_PLANE(e0,e1,triangle_normal,plane);
|
||||
}
|
||||
SIMD_FORCE_INLINE void get_edge_plane(GUINT edge_index, const btVector3 &triangle_normal, btVector4 &plane) const
|
||||
{
|
||||
const btVector3 &e0 = m_vertices[edge_index];
|
||||
const btVector3 &e1 = m_vertices[(edge_index + 1) % 3];
|
||||
EDGE_PLANE(e0, e1, triangle_normal, plane);
|
||||
}
|
||||
|
||||
//! Gets the relative transformation of this triangle
|
||||
/*!
|
||||
//! Gets the relative transformation of this triangle
|
||||
/*!
|
||||
The transformation is oriented to the triangle normal , and aligned to the 1st edge of this triangle. The position corresponds to vertice 0:
|
||||
- triangle normal corresponds to Z axis.
|
||||
- 1st normalized edge corresponds to X axis,
|
||||
|
||||
*/
|
||||
SIMD_FORCE_INLINE void get_triangle_transform(btTransform & triangle_transform) const
|
||||
{
|
||||
btMatrix3x3 & matrix = triangle_transform.getBasis();
|
||||
SIMD_FORCE_INLINE void get_triangle_transform(btTransform &triangle_transform) const
|
||||
{
|
||||
btMatrix3x3 &matrix = triangle_transform.getBasis();
|
||||
|
||||
btVector3 zaxis;
|
||||
get_normal(zaxis);
|
||||
MAT_SET_Z(matrix,zaxis);
|
||||
btVector3 zaxis;
|
||||
get_normal(zaxis);
|
||||
MAT_SET_Z(matrix, zaxis);
|
||||
|
||||
btVector3 xaxis = m_vertices[1] - m_vertices[0];
|
||||
VEC_NORMALIZE(xaxis);
|
||||
MAT_SET_X(matrix,xaxis);
|
||||
btVector3 xaxis = m_vertices[1] - m_vertices[0];
|
||||
VEC_NORMALIZE(xaxis);
|
||||
MAT_SET_X(matrix, xaxis);
|
||||
|
||||
//y axis
|
||||
xaxis = zaxis.cross(xaxis);
|
||||
MAT_SET_Y(matrix,xaxis);
|
||||
|
||||
triangle_transform.setOrigin(m_vertices[0]);
|
||||
}
|
||||
//y axis
|
||||
xaxis = zaxis.cross(xaxis);
|
||||
MAT_SET_Y(matrix, xaxis);
|
||||
|
||||
triangle_transform.setOrigin(m_vertices[0]);
|
||||
}
|
||||
|
||||
//! Test triangles by finding separating axis
|
||||
/*!
|
||||
@@ -195,8 +189,8 @@ public:
|
||||
\param contact_data Structure for holding contact points, normal and penetration depth; The normal is pointing toward this triangle from the other triangle
|
||||
*/
|
||||
bool collide_triangle_hard_test(
|
||||
const GIM_TRIANGLE & other,
|
||||
GIM_TRIANGLE_CONTACT_DATA & contact_data) const;
|
||||
const GIM_TRIANGLE &other,
|
||||
GIM_TRIANGLE_CONTACT_DATA &contact_data) const;
|
||||
|
||||
//! Test boxes before doing hard test
|
||||
/*!
|
||||
@@ -205,16 +199,16 @@ public:
|
||||
\
|
||||
*/
|
||||
SIMD_FORCE_INLINE bool collide_triangle(
|
||||
const GIM_TRIANGLE & other,
|
||||
GIM_TRIANGLE_CONTACT_DATA & contact_data) const
|
||||
const GIM_TRIANGLE &other,
|
||||
GIM_TRIANGLE_CONTACT_DATA &contact_data) const
|
||||
{
|
||||
//test box collisioin
|
||||
GIM_AABB boxu(m_vertices[0],m_vertices[1],m_vertices[2],m_margin);
|
||||
GIM_AABB boxv(other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],other.m_margin);
|
||||
if(!boxu.has_collision(boxv)) return false;
|
||||
GIM_AABB boxu(m_vertices[0], m_vertices[1], m_vertices[2], m_margin);
|
||||
GIM_AABB boxv(other.m_vertices[0], other.m_vertices[1], other.m_vertices[2], other.m_margin);
|
||||
if (!boxu.has_collision(boxv)) return false;
|
||||
|
||||
//do hard test
|
||||
return collide_triangle_hard_test(other,contact_data);
|
||||
return collide_triangle_hard_test(other, contact_data);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -246,43 +240,43 @@ if 0.0<= u+v <=1.0 then they are inside of triangle
|
||||
\return false if the point is outside of triangle.This function doesn't take the margin
|
||||
*/
|
||||
SIMD_FORCE_INLINE bool get_uv_parameters(
|
||||
const btVector3 & point,
|
||||
const btVector3 & tri_plane,
|
||||
GREAL & u, GREAL & v) const
|
||||
const btVector3 &point,
|
||||
const btVector3 &tri_plane,
|
||||
GREAL &u, GREAL &v) const
|
||||
{
|
||||
btVector3 _axe1 = m_vertices[1]-m_vertices[0];
|
||||
btVector3 _axe2 = m_vertices[2]-m_vertices[0];
|
||||
btVector3 _axe1 = m_vertices[1] - m_vertices[0];
|
||||
btVector3 _axe2 = m_vertices[2] - m_vertices[0];
|
||||
btVector3 _vecproj = point - m_vertices[0];
|
||||
GUINT _i1 = (tri_plane.closestAxis()+1)%3;
|
||||
GUINT _i2 = (_i1+1)%3;
|
||||
if(btFabs(_axe2[_i2])<G_EPSILON)
|
||||
GUINT _i1 = (tri_plane.closestAxis() + 1) % 3;
|
||||
GUINT _i2 = (_i1 + 1) % 3;
|
||||
if (btFabs(_axe2[_i2]) < G_EPSILON)
|
||||
{
|
||||
u = (_vecproj[_i2]*_axe2[_i1] - _vecproj[_i1]*_axe2[_i2]) /(_axe1[_i2]*_axe2[_i1] - _axe1[_i1]*_axe2[_i2]);
|
||||
v = (_vecproj[_i1] - u*_axe1[_i1])/_axe2[_i1];
|
||||
u = (_vecproj[_i2] * _axe2[_i1] - _vecproj[_i1] * _axe2[_i2]) / (_axe1[_i2] * _axe2[_i1] - _axe1[_i1] * _axe2[_i2]);
|
||||
v = (_vecproj[_i1] - u * _axe1[_i1]) / _axe2[_i1];
|
||||
}
|
||||
else
|
||||
{
|
||||
u = (_vecproj[_i1]*_axe2[_i2] - _vecproj[_i2]*_axe2[_i1]) /(_axe1[_i1]*_axe2[_i2] - _axe1[_i2]*_axe2[_i1]);
|
||||
v = (_vecproj[_i2] - u*_axe1[_i2])/_axe2[_i2];
|
||||
u = (_vecproj[_i1] * _axe2[_i2] - _vecproj[_i2] * _axe2[_i1]) / (_axe1[_i1] * _axe2[_i2] - _axe1[_i2] * _axe2[_i1]);
|
||||
v = (_vecproj[_i2] - u * _axe1[_i2]) / _axe2[_i2];
|
||||
}
|
||||
|
||||
if(u<-G_EPSILON)
|
||||
if (u < -G_EPSILON)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(v<-G_EPSILON)
|
||||
else if (v < -G_EPSILON)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
btScalar sumuv;
|
||||
sumuv = u+v;
|
||||
if(sumuv<-G_EPSILON)
|
||||
sumuv = u + v;
|
||||
if (sumuv < -G_EPSILON)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(sumuv-1.0f>G_EPSILON)
|
||||
else if (sumuv - 1.0f > G_EPSILON)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -294,50 +288,49 @@ if 0.0<= u+v <=1.0 then they are inside of triangle
|
||||
/*!
|
||||
Test if point is in triangle, with m_margin tolerance
|
||||
*/
|
||||
SIMD_FORCE_INLINE bool is_point_inside(const btVector3 & point, const btVector3 & tri_normal) const
|
||||
SIMD_FORCE_INLINE bool is_point_inside(const btVector3 &point, const btVector3 &tri_normal) const
|
||||
{
|
||||
//Test with edge 0
|
||||
btVector4 edge_plane;
|
||||
this->get_edge_plane(0,tri_normal,edge_plane);
|
||||
GREAL dist = DISTANCE_PLANE_POINT(edge_plane,point);
|
||||
if(dist-m_margin>0.0f) return false; // outside plane
|
||||
this->get_edge_plane(0, tri_normal, edge_plane);
|
||||
GREAL dist = DISTANCE_PLANE_POINT(edge_plane, point);
|
||||
if (dist - m_margin > 0.0f) return false; // outside plane
|
||||
|
||||
this->get_edge_plane(1,tri_normal,edge_plane);
|
||||
dist = DISTANCE_PLANE_POINT(edge_plane,point);
|
||||
if(dist-m_margin>0.0f) return false; // outside plane
|
||||
this->get_edge_plane(1, tri_normal, edge_plane);
|
||||
dist = DISTANCE_PLANE_POINT(edge_plane, point);
|
||||
if (dist - m_margin > 0.0f) return false; // outside plane
|
||||
|
||||
this->get_edge_plane(2,tri_normal,edge_plane);
|
||||
dist = DISTANCE_PLANE_POINT(edge_plane,point);
|
||||
if(dist-m_margin>0.0f) return false; // outside plane
|
||||
this->get_edge_plane(2, tri_normal, edge_plane);
|
||||
dist = DISTANCE_PLANE_POINT(edge_plane, point);
|
||||
if (dist - m_margin > 0.0f) return false; // outside plane
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! Bidireccional ray collision
|
||||
SIMD_FORCE_INLINE bool ray_collision(
|
||||
const btVector3 & vPoint,
|
||||
const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal,
|
||||
GREAL & tparam, GREAL tmax = G_REAL_INFINITY)
|
||||
const btVector3 &vPoint,
|
||||
const btVector3 &vDir, btVector3 &pout, btVector3 &triangle_normal,
|
||||
GREAL &tparam, GREAL tmax = G_REAL_INFINITY)
|
||||
{
|
||||
btVector4 faceplane;
|
||||
{
|
||||
btVector3 dif1 = m_vertices[1] - m_vertices[0];
|
||||
btVector3 dif2 = m_vertices[2] - m_vertices[0];
|
||||
VEC_CROSS(faceplane,dif1,dif2);
|
||||
faceplane[3] = m_vertices[0].dot(faceplane);
|
||||
VEC_CROSS(faceplane, dif1, dif2);
|
||||
faceplane[3] = m_vertices[0].dot(faceplane);
|
||||
}
|
||||
|
||||
GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam, btScalar(0), tmax);
|
||||
if(res == 0) return false;
|
||||
if(! is_point_inside(pout,faceplane)) return false;
|
||||
GUINT res = LINE_PLANE_COLLISION(faceplane, vDir, vPoint, pout, tparam, btScalar(0), tmax);
|
||||
if (res == 0) return false;
|
||||
if (!is_point_inside(pout, faceplane)) return false;
|
||||
|
||||
if(res==2) //invert normal
|
||||
if (res == 2) //invert normal
|
||||
{
|
||||
triangle_normal.setValue(-faceplane[0],-faceplane[1],-faceplane[2]);
|
||||
triangle_normal.setValue(-faceplane[0], -faceplane[1], -faceplane[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]);
|
||||
triangle_normal.setValue(faceplane[0], faceplane[1], faceplane[2]);
|
||||
}
|
||||
|
||||
VEC_NORMALIZE(triangle_normal);
|
||||
@@ -345,36 +338,31 @@ if 0.0<= u+v <=1.0 then they are inside of triangle
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! one direccion ray collision
|
||||
SIMD_FORCE_INLINE bool ray_collision_front_side(
|
||||
const btVector3 & vPoint,
|
||||
const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal,
|
||||
GREAL & tparam, GREAL tmax = G_REAL_INFINITY)
|
||||
const btVector3 &vPoint,
|
||||
const btVector3 &vDir, btVector3 &pout, btVector3 &triangle_normal,
|
||||
GREAL &tparam, GREAL tmax = G_REAL_INFINITY)
|
||||
{
|
||||
btVector4 faceplane;
|
||||
{
|
||||
btVector3 dif1 = m_vertices[1] - m_vertices[0];
|
||||
btVector3 dif2 = m_vertices[2] - m_vertices[0];
|
||||
VEC_CROSS(faceplane,dif1,dif2);
|
||||
faceplane[3] = m_vertices[0].dot(faceplane);
|
||||
VEC_CROSS(faceplane, dif1, dif2);
|
||||
faceplane[3] = m_vertices[0].dot(faceplane);
|
||||
}
|
||||
|
||||
GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam, btScalar(0), tmax);
|
||||
if(res != 1) return false;
|
||||
GUINT res = LINE_PLANE_COLLISION(faceplane, vDir, vPoint, pout, tparam, btScalar(0), tmax);
|
||||
if (res != 1) return false;
|
||||
|
||||
if(!is_point_inside(pout,faceplane)) return false;
|
||||
if (!is_point_inside(pout, faceplane)) return false;
|
||||
|
||||
triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]);
|
||||
triangle_normal.setValue(faceplane[0], faceplane[1], faceplane[2]);
|
||||
|
||||
VEC_NORMALIZE(triangle_normal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // GIM_TRI_COLLISION_H_INCLUDED
|
||||
#endif // GIM_TRI_COLLISION_H_INCLUDED
|
||||
|
||||
Reference in New Issue
Block a user