gimpact 0.2 prep
This commit is contained in:
@@ -1,400 +0,0 @@
|
||||
#ifndef GIM_BOX_COLLISION_H_INCLUDED
|
||||
#define GIM_BOX_COLLISION_H_INCLUDED
|
||||
|
||||
/*! \file gim_box_collision.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*! \defgroup BOUND_AABB_OPERATIONS
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//!Initializes an AABB
|
||||
#define INVALIDATE_AABB(aabb) {\
|
||||
(aabb).minX = G_REAL_INFINITY;\
|
||||
(aabb).maxX = -G_REAL_INFINITY;\
|
||||
(aabb).minY = G_REAL_INFINITY;\
|
||||
(aabb).maxY = -G_REAL_INFINITY;\
|
||||
(aabb).minZ = G_REAL_INFINITY;\
|
||||
(aabb).maxZ = -G_REAL_INFINITY;\
|
||||
}\
|
||||
|
||||
#define AABB_GET_MIN(aabb,vmin) {\
|
||||
vmin[0] = (aabb).minX;\
|
||||
vmin[1] = (aabb).minY;\
|
||||
vmin[2] = (aabb).minZ;\
|
||||
}\
|
||||
|
||||
#define AABB_GET_MAX(aabb,vmax) {\
|
||||
vmax[0] = (aabb).maxX;\
|
||||
vmax[1] = (aabb).maxY;\
|
||||
vmax[2] = (aabb).maxZ;\
|
||||
}\
|
||||
|
||||
//!Copy boxes
|
||||
#define AABB_COPY(dest_aabb,src_aabb)\
|
||||
{\
|
||||
(dest_aabb).minX = (src_aabb).minX;\
|
||||
(dest_aabb).maxX = (src_aabb).maxX;\
|
||||
(dest_aabb).minY = (src_aabb).minY;\
|
||||
(dest_aabb).maxY = (src_aabb).maxY;\
|
||||
(dest_aabb).minZ = (src_aabb).minZ;\
|
||||
(dest_aabb).maxZ = (src_aabb).maxZ;\
|
||||
}\
|
||||
|
||||
//! Computes an Axis aligned box from a triangle
|
||||
#define COMPUTEAABB_FOR_TRIANGLE(aabb,V1,V2,V3) {\
|
||||
(aabb).minX = GIM_MIN3(V1[0],V2[0],V3[0]);\
|
||||
(aabb).maxX = GIM_MAX3(V1[0],V2[0],V3[0]);\
|
||||
(aabb).minY = GIM_MIN3(V1[1],V2[1],V3[1]);\
|
||||
(aabb).maxY = GIM_MAX3(V1[1],V2[1],V3[1]);\
|
||||
(aabb).minZ = GIM_MIN3(V1[2],V2[2],V3[2]);\
|
||||
(aabb).maxZ = GIM_MAX3(V1[2],V2[2],V3[2]);\
|
||||
}\
|
||||
|
||||
//! Apply a transform to an AABB
|
||||
#define AABB_TRANSFORM(dest_box,source_box,mat4trans)\
|
||||
{\
|
||||
vec3f _vx,_vy,_vz;\
|
||||
float _vtemp[] = {(source_box.maxX-source_box.minX),(source_box.maxY-source_box.minY),(source_box.maxZ-source_box.minZ)};\
|
||||
MAT_GET_COL(mat4trans,_vx,0);\
|
||||
VEC_SCALE(_vx,_vtemp[0],_vx); \
|
||||
MAT_GET_COL(mat4trans,_vy,1);\
|
||||
VEC_SCALE(_vy,_vtemp[1],_vy); \
|
||||
MAT_GET_COL(mat4trans,_vz,2);\
|
||||
VEC_SCALE(_vz,_vtemp[2],_vz);\
|
||||
float _vtrans[] = {source_box.minX,source_box.minY,source_box.minZ}; \
|
||||
MAT_DOT_VEC_3X4(_vtemp,mat4trans,_vtrans);\
|
||||
dest_box.minX = dest_box.maxX = _vtemp[0];\
|
||||
dest_box.minY = dest_box.maxY = _vtemp[1];\
|
||||
dest_box.minZ = dest_box.maxZ = _vtemp[2]; \
|
||||
if(_vx[0]<0.0f) dest_box.minX += _vx[0]; else dest_box.maxX += _vx[0];\
|
||||
if(_vx[1]<0.0f) dest_box.minY += _vx[1]; else dest_box.maxY += _vx[1];\
|
||||
if(_vx[2]<0.0f) dest_box.minZ += _vx[2]; else dest_box.maxZ += _vx[2];\
|
||||
if(_vy[0]<0.0f) dest_box.minX += _vy[0]; else dest_box.maxX += _vy[0];\
|
||||
if(_vy[1]<0.0f) dest_box.minY += _vy[1]; else dest_box.maxY += _vy[1];\
|
||||
if(_vy[2]<0.0f) dest_box.minZ += _vy[2]; else dest_box.maxZ += _vy[2];\
|
||||
if(_vz[0]<0.0f) dest_box.minX += _vz[0]; else dest_box.maxX += _vz[0];\
|
||||
if(_vz[1]<0.0f) dest_box.minY += _vz[1]; else dest_box.maxY += _vz[1];\
|
||||
if(_vz[2]<0.0f) dest_box.minZ += _vz[2]; else dest_box.maxZ += _vz[2];\
|
||||
}\
|
||||
|
||||
|
||||
//! Merge two boxes to destaabb
|
||||
#define MERGEBOXES(destaabb,aabb) {\
|
||||
(destaabb).minX = GIM_MIN((aabb).minX,(destaabb).minX);\
|
||||
(destaabb).minY = GIM_MIN((aabb).minY,(destaabb).minY);\
|
||||
(destaabb).minZ = GIM_MIN((aabb).minZ,(destaabb).minZ);\
|
||||
(destaabb).maxX = GIM_MAX((aabb).maxX,(destaabb).maxX);\
|
||||
(destaabb).maxY = GIM_MAX((aabb).maxY,(destaabb).maxY);\
|
||||
(destaabb).maxZ = GIM_MAX((aabb).maxZ,(destaabb).maxZ);\
|
||||
}\
|
||||
|
||||
//! Extends the box
|
||||
#define AABB_POINT_EXTEND(destaabb,p) {\
|
||||
(destaabb).minX = GIM_MIN(p[0],(destaabb).minX);\
|
||||
(destaabb).maxX = GIM_MAX(p[0],(destaabb).maxX);\
|
||||
(destaabb).minY = GIM_MIN(p[1],(destaabb).minY);\
|
||||
(destaabb).maxY = GIM_MAX(p[1],(destaabb).maxY);\
|
||||
(destaabb).minZ = GIM_MIN(p[2],(destaabb).minZ);\
|
||||
(destaabb).maxZ = GIM_MAX(p[2],(destaabb).maxZ);\
|
||||
}\
|
||||
|
||||
//! Gets the center and the dimension of the AABB
|
||||
#define AABB_GET_CENTER_EXTEND(aabb,center,extend)\
|
||||
{\
|
||||
extend[0] = (aabb.maxX - aabb.minX)*0.5f;\
|
||||
extend[1] = (aabb.maxY - aabb.minY)*0.5f;\
|
||||
extend[2] = (aabb.maxZ - aabb.minZ)*0.5f;\
|
||||
center[0] = aabb.minX + extend[0];\
|
||||
center[1] = aabb.minY + extend[1];\
|
||||
center[2] = aabb.minZ + extend[2];\
|
||||
}\
|
||||
|
||||
//! Finds the intersection box of two boxes
|
||||
#define BOXINTERSECTION(aabb1, aabb2, iaabb) {\
|
||||
(iaabb).minX = GIM_MAX((aabb1).minX,(aabb2).minX);\
|
||||
(iaabb).minY = GIM_MAX((aabb1).minY,(aabb2).minY);\
|
||||
(iaabb).minZ = GIM_MAX((aabb1).minZ,(aabb2).minZ);\
|
||||
(iaabb).maxX = GIM_MIN((aabb1).maxX,(aabb2).maxX);\
|
||||
(iaabb).maxY = GIM_MIN((aabb1).maxY,(aabb2).maxY);\
|
||||
(iaabb).maxZ = GIM_MIN((aabb1).maxZ,(aabb2).maxZ);\
|
||||
}\
|
||||
|
||||
//! Determines if two aligned boxes do intersect
|
||||
#define AABBCOLLISION(intersected,aabb1,aabb2) {\
|
||||
intersected = 1;\
|
||||
if ((aabb1).minX > (aabb2).maxX ||\
|
||||
(aabb1).maxX < (aabb2).minX ||\
|
||||
(aabb1).minY > (aabb2).maxY ||\
|
||||
(aabb1).maxY < (aabb2).minY ||\
|
||||
(aabb1).minZ > (aabb2).maxZ ||\
|
||||
(aabb1).maxZ < (aabb2).minZ )\
|
||||
{\
|
||||
intersected = 0;\
|
||||
}\
|
||||
}\
|
||||
|
||||
#define AXIS_INTERSECT(min,max, a, d,tfirst, tlast,is_intersected) {\
|
||||
if(GIM_IS_ZERO(d))\
|
||||
{\
|
||||
is_intersected = !(a < min || a > max);\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
GREAL a0, a1;\
|
||||
a0 = (min - a) / (d);\
|
||||
a1 = (max - a) / (d);\
|
||||
if(a0 > a1) GIM_SWAP_NUMBERS(a0, a1);\
|
||||
tfirst = GIM_MAX(a0, tfirst);\
|
||||
tlast = GIM_MIN(a1, tlast);\
|
||||
if (tlast < tfirst)\
|
||||
{\
|
||||
is_intersected = 0;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
is_intersected = 1;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
|
||||
/*! \brief Finds the Ray intersection parameter.
|
||||
|
||||
\param aabb Aligned box
|
||||
\param vorigin A vec3f with the origin of the ray
|
||||
\param vdir A vec3f with the direction of the ray
|
||||
\param tparam Output parameter
|
||||
\param tmax Max lenght of the ray
|
||||
\param is_intersected 1 if the ray collides the box, else false
|
||||
|
||||
*/
|
||||
#define BOX_INTERSECTS_RAY(aabb, vorigin, vdir, tparam, tmax,is_intersected) { \
|
||||
GREAL _tfirst = 0.0f, _tlast = tmax;\
|
||||
AXIS_INTERSECT(aabb.minX,aabb.maxX,vorigin[0], vdir[0], _tfirst, _tlast,is_intersected);\
|
||||
if(is_intersected)\
|
||||
{\
|
||||
AXIS_INTERSECT(aabb.minY,aabb.maxY,vorigin[1], vdir[1], _tfirst, _tlast,is_intersected);\
|
||||
}\
|
||||
if(is_intersected)\
|
||||
{\
|
||||
AXIS_INTERSECT(aabb.minZ,aabb.maxZ,vorigin[2], vdir[2], _tfirst, _tlast,is_intersected);\
|
||||
}\
|
||||
tparam = _tfirst;\
|
||||
}\
|
||||
|
||||
/*! \brief Finds the Ray intersection parameter.
|
||||
|
||||
\param aabb Aligned box
|
||||
\param vorigin A vec3f with the origin of the ray
|
||||
\param vdir A vec3f with the direction of the ray
|
||||
*/
|
||||
inline int BOX_INTERSECTS_RAY_FAST(aabb3f & aabb, vec3f vorigin,vec3f vdir)
|
||||
{
|
||||
vec3f extents,center;
|
||||
AABB_GET_CENTER_EXTEND(aabb,center,extents);
|
||||
|
||||
GREAL Dx = vorigin[0] - center[0];
|
||||
if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return 0;
|
||||
GREAL Dy = vorigin[1] - center[1];
|
||||
if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return 0;
|
||||
GREAL Dz = vorigin[2] - center[2];
|
||||
if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return 0;
|
||||
GREAL f;
|
||||
f = vdir[1] * Dz - vdir[2] * Dy;
|
||||
if(fabsf(f) > extents[1]*fabsf(vdir[2]) + extents[2]*fabsf(vdir[1])) return 0;
|
||||
f = vdir[2] * Dx - vdir[0] * Dz;
|
||||
if(fabsf(f) > extents[0]*fabsf(vdir[2]) + extents[2]*fabsf(vdir[0]))return 0;
|
||||
f = vdir[0] * Dy - vdir[1] * Dx;
|
||||
if(fabsf(f) > extents[0]*fabsf(vdir[1]) + extents[1]*fabsf(vdir[0]))return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define AABB_PROJECTION_INTERVAL(aabb,direction, vmin, vmax)\
|
||||
{\
|
||||
GREAL _center[] = {(aabb.minX + aabb.maxX)*0.5f, (aabb.minY + aabb.maxY)*0.5f, (aabb.minZ + aabb.maxZ)*0.5f};\
|
||||
\
|
||||
GREAL _extend[] = {aabb.maxX-_center[0],aabb.maxY-_center[1],aabb.maxZ-_center[2]};\
|
||||
GREAL _fOrigin = VEC_DOT(direction,_center);\
|
||||
GREAL _fMaximumExtent = _extend[0]*fabsf(direction[0]) + \
|
||||
_extend[1]*fabsf(direction[1]) + \
|
||||
_extend[2]*fabsf(direction[2]); \
|
||||
\
|
||||
vmin = _fOrigin - _fMaximumExtent; \
|
||||
vmax = _fOrigin + _fMaximumExtent; \
|
||||
}\
|
||||
|
||||
#define BOX_PLANE_EPSILON 0.000001f
|
||||
|
||||
/*!
|
||||
classify values:
|
||||
<ol>
|
||||
<li> 0 : In back of plane
|
||||
<li> 1 : Spanning
|
||||
<li> 2 : In front of
|
||||
</ol>
|
||||
*/
|
||||
#define PLANE_CLASSIFY_BOX(plane,aabb,classify)\
|
||||
{\
|
||||
GREAL _fmin,_fmax; \
|
||||
AABB_PROJECTION_INTERVAL(aabb,plane, _fmin, _fmax); \
|
||||
if(plane[3] > _fmax + BOX_PLANE_EPSILON ) \
|
||||
{ \
|
||||
classify = 0;/*In back of*/ \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if(plane[3]+BOX_PLANE_EPSILON >=_fmin) \
|
||||
{ \
|
||||
classify = 1;/*Spanning*/ \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
classify = 2;/*In front of*/ \
|
||||
} \
|
||||
} \
|
||||
}\
|
||||
|
||||
//! Class for transforming a model1 to the space of model0
|
||||
class GIM_BOX_BOX_TRANSFORM_CACHE
|
||||
{
|
||||
public:
|
||||
vec3f m_T1to0;//!< Transforms translation of model1 to model 0
|
||||
mat3f m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1
|
||||
mat3f m_AR;//!< Absolute value of m_R1to0
|
||||
|
||||
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)
|
||||
int i,j;
|
||||
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
for(j=0;j<3;j++ )
|
||||
{
|
||||
m_AR[i][j] = 1e-6f + fabsf(m_R1to0[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline int gim_box_box_overlap_trans_conservative(aabb3f * box0,aabb3f * box1,mat4f trans1_to_0)
|
||||
{
|
||||
aabb3f pbox1;
|
||||
AABB_TRANSFORM(pbox1,(*box1),trans1_to_0);
|
||||
int intersected;
|
||||
AABBCOLLISION(intersected,pbox1,(*box0));
|
||||
return intersected;
|
||||
}
|
||||
|
||||
inline int gim_box_box_overlap_cache(aabb3f * box0,aabb3f * box1,GIM_BOX_BOX_TRANSFORM_CACHE * boxcache, bool fulltest)
|
||||
{
|
||||
//Taken from OPCODE
|
||||
vec3f ea,eb;//extends
|
||||
vec3f ca,cb;//extends
|
||||
AABB_GET_CENTER_EXTEND((*box0),ca,ea);
|
||||
AABB_GET_CENTER_EXTEND((*box1),cb,eb);
|
||||
|
||||
|
||||
vec3f T;
|
||||
|
||||
GREAL t,t2;
|
||||
int i;
|
||||
|
||||
// Class I : A's basis vectors
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
T[i] = MAT_DOT_ROW(boxcache->m_R1to0,cb,i) + boxcache->m_T1to0[i] - ca[i];
|
||||
t = MAT_DOT_ROW(boxcache->m_AR,eb,i) + ea[i];
|
||||
if(GIM_GREATER(T[i], t)) return 0;
|
||||
}
|
||||
// Class II : B's basis vectors
|
||||
for(i=0;i<3;i++)
|
||||
{
|
||||
t = MAT_DOT_COL(boxcache->m_R1to0,T,i);
|
||||
t2 = MAT_DOT_COL(boxcache->m_AR,ea,i) + eb[i];
|
||||
if(GIM_GREATER(t,t2)) return 0;
|
||||
}
|
||||
// Class III : 9 cross products
|
||||
if(fulltest)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
q = j==2?1:2;
|
||||
r = j==0?1:0;
|
||||
t = T[n]*boxcache->m_R1to0[m][j] - T[m]*boxcache->m_R1to0[n][j];
|
||||
t2 = ea[o]*boxcache->m_AR[p][j] + ea[p]*boxcache->m_AR[o][j] +
|
||||
eb[r]*boxcache->m_AR[i][q] + eb[q]*boxcache->m_AR[i][r];
|
||||
if(GIM_GREATER(t,t2)) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/// conservative test for overlap between triangle and aabb
|
||||
inline int gim_box_collide_triangle(vec3f p1, vec3f p2, vec3f p3,aabb3f & box)
|
||||
{
|
||||
if(GIM_MIN3(p1[0],p2[0],p3[0])> box.maxX) return 0;
|
||||
if(GIM_MAX3(p1[0],p2[0],p3[0])< box.minX) return 0;
|
||||
|
||||
if(GIM_MIN3(p1[2],p2[2],p3[2])> box.maxZ) return 0;
|
||||
if(GIM_MAX3(p1[2],p2[2],p3[2])< box.minZ) return 0;
|
||||
|
||||
if(GIM_MIN3(p1[1],p2[1],p3[1])> box.maxY) return 0;
|
||||
if(GIM_MAX3(p1[1],p2[1],p3[1])< box.minY) return 0;
|
||||
|
||||
vec4f plane;
|
||||
TRIANGLE_PLANE_FAST(p1,p2,p3,plane);
|
||||
char classify;
|
||||
PLANE_CLASSIFY_BOX(plane,box,classify);
|
||||
|
||||
if(classify != 1) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
#endif // GIM_BOX_COLLISION_H_INCLUDED
|
||||
@@ -1,484 +0,0 @@
|
||||
#ifndef GIM_BOXPRUNING_H_INCLUDED
|
||||
#define GIM_BOXPRUNING_H_INCLUDED
|
||||
|
||||
/*! \file gim_boxpruning.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "GIMPACT/gim_radixsort.h"
|
||||
#include "GIMPACT/gim_geometry.h"
|
||||
|
||||
/*! \defgroup BOX_PRUNNING
|
||||
|
||||
\brief
|
||||
Tools for find overlapping objects on a scenary. These functions sort boxes for faster collisioin queries, using radix sort or quick sort as convenience. See \ref SORTING .
|
||||
<ul>
|
||||
<li> For using these collision routines, you must create a \ref GIM_AABB_SET by using this function : \ref gim_aabbset_alloc.
|
||||
<li> The GIM_AABB_SET objects must be updated on their boxes on each query, and they must be update by calling \ref gim_aabbset_update
|
||||
<li> Before calling collision functions, you must create a pair set with \ref GIM_CREATE_PAIR_SET
|
||||
<li> For finding collision pairs on a scene (common space for objects), call \ref gim_aabbset_self_intersections
|
||||
<li> For finding collision pairs between two box sets , call \ref gim_aabbset_box_collision
|
||||
<li> After using collision routines, you must destroy the pairset with \ref GIM_DESTROY_PAIR_SET
|
||||
<li> When the box set is no longer used, you must destroy it by calling \ref gim_aabbset_destroy
|
||||
</ul>
|
||||
*/
|
||||
//! @{
|
||||
//! Overlapping pair
|
||||
struct GIM_PAIR
|
||||
{
|
||||
GUINT m_index1;
|
||||
GUINT m_index2;
|
||||
};
|
||||
//typedef struct _GIM_PAIR GIM_PAIR;
|
||||
|
||||
//! Box container
|
||||
struct GIM_AABB_SET
|
||||
{
|
||||
GUINT m_count;
|
||||
aabb3f m_global_bound;//!< Global calculated bound of all boxes
|
||||
aabb3f * m_boxes;
|
||||
GUINT * m_maxcoords;//!<Upper corners of the boxes, in integer representation
|
||||
GIM_RSORT_TOKEN * m_sorted_mincoords;//!< sorted min coords (lower corners), with their coord value as the m_key and m_value as the box index
|
||||
char m_shared;//!< if m_shared == 0 then the memory is allocated and the set must be destroyed, else the pointers are shared and the set should't be destroyed
|
||||
};
|
||||
//typedef struct _GIM_AABB_SET GIM_AABB_SET;
|
||||
|
||||
//! Function for creating an overlapping pair set
|
||||
#define GIM_CREATE_PAIR_SET(dynarray) GIM_DYNARRAY_CREATE(GIM_PAIR,dynarray,G_ARRAY_GROW_SIZE)
|
||||
//! Function for destroying an overlapping pair set
|
||||
#define GIM_DESTROY_PAIR_SET(dynarray) GIM_DYNARRAY_DESTROY(dynarray)
|
||||
|
||||
//! Allocate memory for all aabb set.
|
||||
void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT count);
|
||||
|
||||
//! Destroys the aabb set.
|
||||
void gim_aabbset_destroy(GIM_AABB_SET * aabbset);
|
||||
|
||||
//! Calcs the global bound only
|
||||
/*!
|
||||
\pre aabbset must be allocated. And the boxes must be already set.
|
||||
*/
|
||||
void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset);
|
||||
|
||||
//! Sorts the boxes for box prunning.
|
||||
/*!
|
||||
1) find the integer representation of the aabb coords
|
||||
2) Sorts the min coords
|
||||
3) Calcs the global bound
|
||||
\pre aabbset must be allocated. And the boxes must be already set.
|
||||
\param aabbset
|
||||
\param calc_global_bound If 1 , calcs the global bound
|
||||
\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
|
||||
*/
|
||||
void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound);
|
||||
|
||||
//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
|
||||
/*!
|
||||
\pre aabbset must be allocated and sorted, the boxes must be already set.
|
||||
\param aabbset Must be sorted. Global bound isn't required
|
||||
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
|
||||
|
||||
//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
|
||||
/*!
|
||||
\pre aabbset must be allocated, the boxes must be already set.
|
||||
\param aabbset Global bound isn't required. Doen't need to be sorted.
|
||||
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
|
||||
|
||||
//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
|
||||
/*!
|
||||
\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
|
||||
\param aabbset1 Must be sorted, Global bound is required.
|
||||
\param aabbset2 Must be sorted, Global bound is required.
|
||||
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
|
||||
|
||||
//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
|
||||
/*!
|
||||
\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
|
||||
\param aabbset1 Must be sorted, Global bound is required.
|
||||
\param aabbset2 Must be sorted, Global bound is required.
|
||||
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
|
||||
|
||||
|
||||
/*
|
||||
Brute-Force Vs Sorted pruning
|
||||
Different approaches must be applied when colliding sets with different number of
|
||||
elements. When sets have less of 100 boxes, is often better to apply force brute
|
||||
approach instead of sorted methods, because at lowlevel bruteforce routines gives
|
||||
better perormance and consumes less resources, due of their simplicity.
|
||||
But when sets are larger, the complexiity of bruteforce increases exponencially.
|
||||
In the case of large sets, sorted approach is applied. So GIMPACT has the following
|
||||
strategies:
|
||||
|
||||
On Sorting sets:
|
||||
!) When sets have more of 140 boxes, the boxes are sorted by its coded min coord
|
||||
and the global box is calculated. But when sets are smaller (less of 140 boxes),
|
||||
Is convenient to apply brute force approach.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
//! Constant for apply approaches between brute force and sorted pruning on bipartite queries
|
||||
#define GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES 600
|
||||
//! Constant for apply approaches between brute force and sorted pruning for box collision
|
||||
#define GIM_MIN_SORTED_PRUNING_BOXES 140
|
||||
|
||||
|
||||
//Use these functions for general initialization
|
||||
|
||||
//! Initalizes the set. Sort Boxes if needed.
|
||||
/*!
|
||||
\pre aabbset must be allocated. And the boxes must be already set.
|
||||
\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
|
||||
else it Sorts the entire set( Only applicable for large sets)
|
||||
*/
|
||||
void gim_aabbset_update(GIM_AABB_SET * aabbset);
|
||||
|
||||
///Use these functions for general collision
|
||||
|
||||
//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
|
||||
/*!
|
||||
This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted. This is an example of how to use this function:
|
||||
\code
|
||||
//Create contact list
|
||||
GDYNAMIC_ARRAY collision_pairs;
|
||||
GIM_CREATE_PAIR_SET(collision_pairs);
|
||||
//Do collision
|
||||
gim_aabbset_self_intersections(&aabbset,&collision_pairs);
|
||||
if(collision_pairs.m_size==0)
|
||||
{
|
||||
GIM_DYNARRAY_DESTROY(collision_pairs);//
|
||||
return; //no collisioin
|
||||
}
|
||||
|
||||
//pair pointer
|
||||
GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
|
||||
GUINT i, ti1,ti2;
|
||||
for (i=0;i<collision_pairs.m_size; i++)
|
||||
{
|
||||
ti1 = pairs[i].m_index1;
|
||||
ti2 = pairs[i].m_index2;
|
||||
//Do something with the pairs
|
||||
....
|
||||
....
|
||||
...
|
||||
|
||||
}
|
||||
//Terminate
|
||||
GIM_DYNARRAY_DESTROY(dummycontacts);
|
||||
GIM_DYNARRAY_DESTROY(collision_pairs);
|
||||
\endcode
|
||||
\param aabbset Set of boxes. Sorting isn't required.
|
||||
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
|
||||
\pre aabbset must be allocated and initialized.
|
||||
\post If aabbset->m_count >= GIM_MIN_SORTED_PRUNING_BOXES, then it calls to gim_aabbset_sort and then to gim_aabbset_self_intersections_sorted. Global box won't be calculated.
|
||||
*/
|
||||
void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
|
||||
|
||||
//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
|
||||
/*!
|
||||
\pre aabbset1 and aabbset2 must be allocated and updated. See gim_aabbset_update.
|
||||
\param aabbset1 Must be updated.
|
||||
\param aabbset2 Must be updated.
|
||||
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
|
||||
|
||||
///Function for create Box collision result set
|
||||
|
||||
#define GIM_CREATE_BOXQUERY_LIST(dynarray) GIM_DYNARRAY_CREATE(GUINT,dynarray,G_ARRAY_GROW_SIZE)
|
||||
|
||||
//! Finds intersections between a box and a set. Return the colliding boxes of the set
|
||||
/*!
|
||||
\pre aabbset must be allocated and initialized.
|
||||
\param test_aabb Box for collision query
|
||||
\param aabbset Set of boxes .Global bound is required.
|
||||
\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
|
||||
|
||||
//! Finds intersections between a box and a set. Return the colliding boxes of the set
|
||||
/*!
|
||||
\pre aabbset must be allocated and initialized.
|
||||
\param vorigin Origin point of ray.
|
||||
\param vdir Direction vector of ray.
|
||||
\param tmax Max distance param for ray.
|
||||
\param aabbset Set of boxes .Global bound is required.
|
||||
\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
|
||||
|
||||
|
||||
/*
|
||||
For sorting, each box corner must be discretized to a 32 bit integer.
|
||||
For this, we take the x and z coordinates from the box corner (a vector vec3f)
|
||||
Then convert the (x,z) pair to an integer. For convenience, we choose an error
|
||||
constant for converting the coordinates (0.05).
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
For fitting the coordinate to an integer, we need to constraint the range of its values. So each coord component (x, z) must lie between 0 and 65536.
|
||||
20 give us a 0.05 floating point error
|
||||
*/
|
||||
#define ERROR_AABB 20.0f
|
||||
|
||||
/**
|
||||
An error of 0.05 allows to make coordinates up to 1638.0f and no less of -1638.0f.
|
||||
So the maximum size of a room should be about 3276x3276 . Its dimensions must lie between [-1638,1638.0f]
|
||||
*/
|
||||
#define MAX_AABB_SIZE 1638.0f
|
||||
|
||||
/**
|
||||
If 1, then the system manages objects that are far away beyond the limits of the world [-1638,1638.0f]
|
||||
*/
|
||||
#define CLAMP_FURTHER_OBJECTS 0
|
||||
|
||||
//! Converts a vector coordinate to an integer for box sorting. Secure clamped
|
||||
/*!
|
||||
\param vx X component
|
||||
\param vz Z component
|
||||
\param uint_key a GUINT
|
||||
*/
|
||||
#define GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key)\
|
||||
{\
|
||||
GREAL _cx = GIM_CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
|
||||
GREAL _cz = GIM_CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
|
||||
GUINT _z = ((GUINT)(_cz*ERROR_AABB))+32768;\
|
||||
uint_key = ((GUINT)(_cx*ERROR_AABB))+32768;\
|
||||
uint_key = (uint_key<<16) + _z;\
|
||||
}\
|
||||
|
||||
//! Converts a vector coordinate to an integer for box sorting. Secure clamped, rounded
|
||||
/*!
|
||||
\param vx X component
|
||||
\param vz Z component
|
||||
\param uint_key a GUINT
|
||||
*/
|
||||
#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key)\
|
||||
{\
|
||||
GREAL _cx = GIM_CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
|
||||
GREAL _cz = GIM_CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
|
||||
GUINT _z = ((GUINT)ceilf(_cz*ERROR_AABB))+32768;\
|
||||
uint_key = ((GUINT)ceilf(_cx*ERROR_AABB))+32768;\
|
||||
uint_key = (uint_key<<16) + _z;\
|
||||
}\
|
||||
|
||||
|
||||
#if (CLAMP_FURTHER_OBJECTS == 1)
|
||||
|
||||
#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key) GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key)
|
||||
|
||||
#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key) GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key)
|
||||
|
||||
#else
|
||||
|
||||
//! Converts a vector coordinate to an integer for box sorting
|
||||
/*!
|
||||
\param vx X component
|
||||
\param vz Z component
|
||||
\param uint_key a GUINT
|
||||
*/
|
||||
#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key)\
|
||||
{\
|
||||
GUINT _z = ((GUINT)(vz*ERROR_AABB))+32768;\
|
||||
uint_key = ((GUINT)(vx*ERROR_AABB))+32768;\
|
||||
uint_key = (uint_key<<16) + _z;\
|
||||
}\
|
||||
|
||||
//! Converts a vector coordinate to an integer for box sorting,rounding to the upper int
|
||||
/*!
|
||||
\param vx X component
|
||||
\param vz Z component
|
||||
\param uint_key a GUINT
|
||||
*/
|
||||
#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key)\
|
||||
{\
|
||||
GUINT _z = ((GUINT)ceilf(vz*ERROR_AABB))+32768;\
|
||||
uint_key = ((GUINT)ceilf(vx*ERROR_AABB))+32768;\
|
||||
uint_key = (uint_key<<16) + _z;\
|
||||
}\
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
/*! \defgroup HIERARCHY_BOX_PRUNNING
|
||||
|
||||
\brief
|
||||
Tools for find overlapping objects on a scenary, by using Bounding Volume Trees.
|
||||
*/
|
||||
//! @{
|
||||
|
||||
struct GIM_AABB_DATA
|
||||
{
|
||||
aabb3f m_aabb;//!< Bounding volume
|
||||
GUINT m_data;
|
||||
};
|
||||
|
||||
#define AABB_DATA_COPY(dest_data,src_data)\
|
||||
{\
|
||||
AABB_COPY(dest_data.m_aabb,src_data.m_aabb);\
|
||||
dest_data.m_data = src_data.m_data;\
|
||||
}\
|
||||
|
||||
//! Node Structure for trees
|
||||
struct GIM_AABB_TREE_NODE
|
||||
{
|
||||
GIM_AABB_TREE_NODE * m_left;//!< Left subtree
|
||||
GIM_AABB_TREE_NODE * m_right;//!< Right subtree
|
||||
GUINT m_escapeIndex;//!< Scape index for traversing
|
||||
GIM_AABB_DATA m_data;
|
||||
|
||||
GIM_AABB_TREE_NODE()
|
||||
{
|
||||
m_left = 0;
|
||||
m_right = 0;
|
||||
m_escapeIndex = 0;
|
||||
}
|
||||
|
||||
bool is_leaf_node()
|
||||
{
|
||||
return (!m_left && !m_right);
|
||||
}
|
||||
};
|
||||
|
||||
//! AABB tree
|
||||
struct GIM_AABB_TREE
|
||||
{
|
||||
GIM_AABB_TREE_NODE * m_node_array;
|
||||
GUINT m_num_nodes;
|
||||
GUINT m_nodes_array_size;
|
||||
GIM_AABB_TREE_NODE * m_root_node;
|
||||
|
||||
void clear_nodes()
|
||||
{
|
||||
if(m_node_array != 0) gim_free(m_node_array,0);
|
||||
m_num_nodes = 0;
|
||||
m_root_node = 0;
|
||||
m_nodes_array_size = 0;
|
||||
}
|
||||
|
||||
GIM_AABB_TREE()
|
||||
{
|
||||
m_node_array = 0;
|
||||
m_num_nodes = 0;
|
||||
m_root_node = 0;
|
||||
m_nodes_array_size = 0;
|
||||
}
|
||||
|
||||
~GIM_AABB_TREE()
|
||||
{
|
||||
clear_nodes();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! Creates and intializes a GIM_AABB_TREE from an array of boxes
|
||||
/*!
|
||||
\param newtree Tree for be build
|
||||
\param boxarray A GIM_AABB_DATA array for sorting, must be allocated by user.
|
||||
\param boxcount box count.
|
||||
*/
|
||||
void gim_aabbtree_create(GIM_AABB_TREE * newtree, GIM_AABB_DATA * boxarray, GUINT boxcount);
|
||||
|
||||
//! Destroy an GIM_AABB_TREE.
|
||||
void gim_aabbtree_destroy(GIM_AABB_TREE * tree);
|
||||
|
||||
//! Finds intersections between a box and a tree. Return the indices from the colliding nodes of the tree
|
||||
/*!
|
||||
\pre aabbtree must be initialized.
|
||||
\param test_aabb Box for collision query
|
||||
\param aabbtree Tree of boxes.
|
||||
\param collided Array of GUINT elements which corresponds to the index of the collided node in the m_nodes_array menber. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbtree_box_collision_get_nodes(aabb3f *test_aabb, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided);
|
||||
|
||||
|
||||
//! Finds intersections between a box and a tree. Return the data index from the colliding leaf boxes of the tree
|
||||
/*!
|
||||
\pre aabbtree must be initialized.
|
||||
\param test_aabb Box for collision query
|
||||
\param aabbtree Tree of boxes.
|
||||
\param collided Array of GUINT elements which corresponds to the data index in the leafs. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbtree_box_collision(aabb3f *test_aabb, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided);
|
||||
|
||||
//! Finds intersections between a box and a tree. Return the colliding boxes of the set
|
||||
/*!
|
||||
\param vorigin Origin point of ray.
|
||||
\param vdir Direction vector of ray.
|
||||
\param tmax Max distance param for ray.
|
||||
\param aabbtree Set of boxes.
|
||||
\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbtree_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided);
|
||||
|
||||
|
||||
|
||||
//! Collides two transformed box trees. Returns a list of the data (m_data) from the overlapping pairs of box leafs, each leaf data belongs to a different tree.
|
||||
/*!
|
||||
\param aabbtree1 Must be updated.
|
||||
\param aabbtree2 Must be updated.
|
||||
\param trans1inverse Inverse Transformation of aabbtree1.
|
||||
\param trans2 Transformation of aabbtree2.
|
||||
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbtree_bipartite_intersections_trans(GIM_AABB_TREE * aabbtree1, GIM_AABB_TREE * aabbtree2,
|
||||
mat4f trans1,mat4f trans1inverse,
|
||||
mat4f trans2,mat4f trans2inverse,
|
||||
GDYNAMIC_ARRAY * collision_pairs);
|
||||
|
||||
|
||||
//! Collides an aabbset and aabbtree. Returns a pair list of overlapping pairs. The first element of the pair belongs to aabbset and the second belongs to aabbtree.
|
||||
/*!
|
||||
\param aabbset Must be updated.
|
||||
\param aabbtree Must be initialized.
|
||||
\param trans_aabbtree Transformation of the aabbtree.
|
||||
\param inv_trans_aabbtree Inverse Transformation of the aabbtree.
|
||||
\param collision_pairs Array of GIM_PAIR elements. The first element of the pair belongs to aabbset and the second belongs to aabbtree having the m_data value from leaf. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_aabbset_aabbtree_intersections_trans(GIM_AABB_SET * aabbset, GIM_AABB_TREE * aabbtree, mat4f trans_aabbtree, mat4f inv_trans_aabbtree, GDYNAMIC_ARRAY * collision_pairs);
|
||||
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
#endif // GIM_BOXPRUNING_H_INCLUDED
|
||||
@@ -1,121 +0,0 @@
|
||||
#ifndef GIM_CONTACT_H_INCLUDED
|
||||
#define GIM_CONTACT_H_INCLUDED
|
||||
|
||||
/*! \file gim_contact.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
#include "GIMPACT/gim_geometry.h"
|
||||
#include "GIMPACT/gim_radixsort.h"
|
||||
|
||||
/*! \defgroup CONTACTS
|
||||
\brief
|
||||
Functions for managing and sorting contacts resulting from a collision query.
|
||||
<ul>
|
||||
<li> Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
|
||||
<li> After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
|
||||
<li> Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
|
||||
</ul>
|
||||
|
||||
*/
|
||||
//! @{
|
||||
|
||||
/**
|
||||
Configuration var for applying interpolation of contact normals
|
||||
*/
|
||||
#define NORMAL_CONTACT_AVERAGE 1
|
||||
|
||||
/// Structure for collision results
|
||||
struct GIM_CONTACT
|
||||
{
|
||||
vec3f m_point;
|
||||
vec3f m_normal;
|
||||
GREAL m_depth;//Positive value indicates interpenetration
|
||||
void * m_handle1;
|
||||
void * m_handle2;
|
||||
GUINT m_feature1;//Face number
|
||||
GUINT m_feature2;//Face number
|
||||
};
|
||||
//typedef struct _GIM_CONTACT GIM_CONTACT;
|
||||
|
||||
#define CONTACT_DIFF_EPSILON 0.00001f
|
||||
|
||||
#define GIM_CALC_KEY_CONTACT(pos,hash)\
|
||||
{\
|
||||
GINT _coords[] = {(GINT)(pos[0]*1000.0f+1.0f),(GINT)(pos[1]*1333.0f),(GINT)(pos[2]*2133.0f+3.0f)};\
|
||||
GUINT _hash=0;\
|
||||
GUINT *_uitmp = (GUINT *)(&_coords[0]);\
|
||||
_hash = *_uitmp;\
|
||||
_uitmp++;\
|
||||
_hash += (*_uitmp)<<4;\
|
||||
_uitmp++;\
|
||||
_hash += (*_uitmp)<<8;\
|
||||
hash = _hash;\
|
||||
}\
|
||||
|
||||
///Creates a contact list for queries
|
||||
#define GIM_CREATE_CONTACT_LIST(contact_array) GIM_DYNARRAY_CREATE(GIM_CONTACT,contact_array,64)
|
||||
|
||||
#define GIM_PUSH_CONTACT(contact_array, point, normal, deep,handle1, handle2, feat1, feat2)\
|
||||
{\
|
||||
GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,contact_array);\
|
||||
GIM_CONTACT * _last = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,contact_array);\
|
||||
VEC_COPY(_last->m_point,point);\
|
||||
VEC_COPY(_last->m_normal,normal);\
|
||||
_last->m_depth = deep;\
|
||||
_last->m_handle1 = handle1;\
|
||||
_last->m_handle2 = handle2;\
|
||||
_last->m_feature1 = feat1;\
|
||||
_last->m_feature2 = feat2;\
|
||||
}\
|
||||
|
||||
///Receive pointer to contacts
|
||||
#define GIM_COPY_CONTACTS(dest_contact, source_contact)\
|
||||
{\
|
||||
VEC_COPY(dest_contact->m_point,source_contact->m_point);\
|
||||
VEC_COPY(dest_contact->m_normal,source_contact->m_normal);\
|
||||
dest_contact->m_depth = source_contact->m_depth;\
|
||||
dest_contact->m_handle1 = source_contact->m_handle1;\
|
||||
dest_contact->m_handle2 = source_contact->m_handle2;\
|
||||
dest_contact->m_feature1 = source_contact->m_feature1;\
|
||||
dest_contact->m_feature2 = source_contact->m_feature2;\
|
||||
}\
|
||||
|
||||
//! Merges duplicate contacts with minimum depth criterion
|
||||
void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
|
||||
GDYNAMIC_ARRAY * dest_contacts);
|
||||
|
||||
|
||||
//! Merges to an unique contact
|
||||
void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
|
||||
GDYNAMIC_ARRAY * dest_contacts);
|
||||
|
||||
//! @}
|
||||
#endif // GIM_CONTACT_H_INCLUDED
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,168 +0,0 @@
|
||||
#ifndef GIM_MATH_H_INCLUDED
|
||||
#define GIM_MATH_H_INCLUDED
|
||||
|
||||
/*! \file gim_math.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
/*! \defgroup BASIC_TYPES
|
||||
Basic types and constants
|
||||
Conventions:
|
||||
Types starting with G
|
||||
Constants starting with G_
|
||||
*/
|
||||
//! @{
|
||||
/*! Types */
|
||||
#define GREAL float
|
||||
#define GREAL2 double
|
||||
#define GINT long
|
||||
#define GUINT unsigned long
|
||||
#define GSHORT short
|
||||
#define GUSHORT unsigned short
|
||||
/*! Constants for integers*/
|
||||
#define GUINT_BIT_COUNT 32
|
||||
#define GUINT_EXPONENT 5
|
||||
|
||||
#define G_FASTMATH 1
|
||||
#define G_PI 3.14159265358979f
|
||||
#define G_HALF_PI 1.5707963f
|
||||
//267948966
|
||||
#define G_TWO_PI 6.28318530f
|
||||
//71795864
|
||||
#define G_ROOT3 1.73205f
|
||||
#define G_ROOT2 1.41421f
|
||||
#define G_UINT_INFINITY 65534
|
||||
#define G_REAL_INFINITY FLT_MAX
|
||||
#define G_SIGN_BITMASK 0x80000000
|
||||
#define G_USE_EPSILON_TEST
|
||||
#define G_EPSILON 0.0000001f
|
||||
//! @}
|
||||
|
||||
|
||||
/*! \defgroup SCALAR_TYPES
|
||||
\brief
|
||||
Precision type constants
|
||||
*/
|
||||
//! @{
|
||||
#define G_STYPE_REAL 0
|
||||
#define G_STYPE_REAL2 1
|
||||
#define G_STYPE_SHORT 2
|
||||
#define G_STYPE_USHORT 3
|
||||
#define G_STYPE_INT 4
|
||||
#define G_STYPE_UINT 5
|
||||
//! @}
|
||||
|
||||
/*! \defgroup MATH_FUNCTIONS
|
||||
mathematical functions
|
||||
*/
|
||||
//! @{
|
||||
#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))
|
||||
|
||||
//! Signed integer representation of a floating-point value.
|
||||
#define GIM_SIR(x) ((GINT&)(x))
|
||||
|
||||
//! Absolute integer representation of a floating-point value
|
||||
#define GIM_AIR(x) (GIM_IR(x)&0x7fffffff)
|
||||
|
||||
//! Floating-point representation of an integer value.
|
||||
#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_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_NEGATIVE(value) (value <= -G_EPSILON)
|
||||
|
||||
#define GIM_IS_POSISITVE(value) (value >= G_EPSILON)
|
||||
|
||||
///returns a clamped number
|
||||
#define GIM_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
|
||||
|
||||
#define GIM_GREATER(x, y) fabsf(x) > (y)
|
||||
|
||||
///Swap numbers
|
||||
#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_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
|
||||
GREAL gim_inv_sqrt(GREAL f);
|
||||
|
||||
//! Computes sqrtf(x) faster.
|
||||
/*!
|
||||
\sa gim_inv_sqrt
|
||||
*/
|
||||
GREAL gim_sqrt(GREAL f);
|
||||
|
||||
//!Initializes mathematical functions
|
||||
void gim_init_math();
|
||||
|
||||
//! Generates an unit random
|
||||
GREAL gim_unit_random();
|
||||
//! @}
|
||||
|
||||
#endif // GIM_MATH_H_INCLUDED
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,302 +0,0 @@
|
||||
#ifndef GIM_RADIXSORT_H_INCLUDED
|
||||
#define GIM_RADIXSORT_H_INCLUDED
|
||||
/*! \file gim_radixsort.h
|
||||
\author Francisco Le<4C>n N<>jera.
|
||||
Based on the work of Michael Herf : "fast floating-point radix sort"
|
||||
Avaliable on http://www.stereopsis.com/radix.html
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "GIMPACT/gim_memory.h"
|
||||
|
||||
/*! \defgroup SORTING
|
||||
\brief
|
||||
Macros for sorting.
|
||||
*/
|
||||
//! @{
|
||||
struct GIM_RSORT_TOKEN
|
||||
{
|
||||
GUINT m_key;
|
||||
GUINT m_value;
|
||||
};
|
||||
//typedef struct _GIM_RSORT_TOKEN GIM_RSORT_TOKEN;
|
||||
|
||||
//comparator for sorting
|
||||
#define RSORT_TOKEN_COMPARATOR(x, y) ((int)((x.m_key) - (y.m_key)))
|
||||
|
||||
// ---- 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 )
|
||||
|
||||
|
||||
//COMMON FUNCTIONS FOR ACCESSING THE KEY OF AN ELEMENT
|
||||
|
||||
|
||||
//For the type of your array, you need to declare a macro for obtaining the key, like these:
|
||||
#define SIMPLE_GET_FLOAT32KEY(e,key) {key =(GREAL)(e);}
|
||||
|
||||
#define SIMPLE_GET_INTKEY(e,key) {key =(GINT)(e);}
|
||||
|
||||
#define SIMPLE_GET_UINTKEY(e,key) {key =(GUINT)(e);}
|
||||
|
||||
//For the type of your array, you need to declare a macro for copy elements, like this:
|
||||
|
||||
#define SIMPLE_COPY_ELEMENTS(dest,src) {dest = src;}
|
||||
|
||||
#define kHist 2048
|
||||
|
||||
///Radix sort for unsigned integer keys
|
||||
|
||||
#define GIM_RADIX_SORT_RTOKENS(array,sorted,element_count)\
|
||||
{\
|
||||
GUINT i;\
|
||||
GUINT b0[kHist * 3];\
|
||||
GUINT *b1 = b0 + kHist;\
|
||||
GUINT *b2 = b1 + kHist;\
|
||||
for (i = 0; i < kHist * 3; i++)\
|
||||
{\
|
||||
b0[i] = 0;\
|
||||
}\
|
||||
GUINT fi;\
|
||||
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)] ++;\
|
||||
}\
|
||||
{\
|
||||
GUINT sum0 = 0, sum1 = 0, sum2 = 0;\
|
||||
GUINT tsum;\
|
||||
for (i = 0; i < kHist; i++)\
|
||||
{\
|
||||
tsum = b0[i] + sum0;\
|
||||
b0[i] = sum0 - 1;\
|
||||
sum0 = tsum;\
|
||||
tsum = b1[i] + sum1;\
|
||||
b1[i] = sum1 - 1;\
|
||||
sum1 = tsum;\
|
||||
tsum = b2[i] + sum2;\
|
||||
b2[i] = sum2 - 1;\
|
||||
sum2 = tsum;\
|
||||
}\
|
||||
}\
|
||||
for (i = 0; i < element_count; i++)\
|
||||
{\
|
||||
fi = array[i].m_key;\
|
||||
pos = D11_0(fi);\
|
||||
pos = ++b0[pos];\
|
||||
sorted[pos].m_key = array[i].m_key;\
|
||||
sorted[pos].m_value = array[i].m_value;\
|
||||
}\
|
||||
for (i = 0; i < element_count; i++)\
|
||||
{\
|
||||
fi = sorted[i].m_key;\
|
||||
pos = D11_1(fi);\
|
||||
pos = ++b1[pos];\
|
||||
array[pos].m_key = sorted[i].m_key;\
|
||||
array[pos].m_value = sorted[i].m_value;\
|
||||
}\
|
||||
for (i = 0; i < element_count; i++)\
|
||||
{\
|
||||
fi = array[i].m_key;\
|
||||
pos = D11_2(fi);\
|
||||
pos = ++b2[pos];\
|
||||
sorted[pos].m_key = array[i].m_key;\
|
||||
sorted[pos].m_value = array[i].m_value;\
|
||||
}\
|
||||
}\
|
||||
|
||||
/// Get the sorted tokens from an array. For generic use. Tokens are GIM_RSORT_TOKEN
|
||||
#define GIM_RADIX_SORT_ARRAY_TOKENS(array, sorted_tokens, element_count, get_uintkey_macro)\
|
||||
{\
|
||||
GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
|
||||
GUINT _i;\
|
||||
for (_i=0;_i<element_count;_i++)\
|
||||
{\
|
||||
get_uintkey_macro(array[_i],_unsorted[_i].m_key);\
|
||||
_unsorted[_i].m_value = _i;\
|
||||
}\
|
||||
GIM_RADIX_SORT_RTOKENS(_unsorted,sorted_tokens,element_count);\
|
||||
gim_free(_unsorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
|
||||
}\
|
||||
|
||||
/// Sorts array in place. For generic use
|
||||
#define GIM_RADIX_SORT(type,array,element_count,get_uintkey_macro,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);\
|
||||
type * _original_array = (type *) gim_alloc(sizeof(type)*element_count); \
|
||||
memcpy(_original_array,array,sizeof(type)*element_count);\
|
||||
GUINT _i;\
|
||||
for (_i=0;_i<element_count;_i++)\
|
||||
{\
|
||||
copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);\
|
||||
}\
|
||||
gim_free(_original_array,sizeof(type)*element_count);\
|
||||
gim_free(_sorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
|
||||
}\
|
||||
|
||||
/// Sorts array in place using quick sort
|
||||
#define GIM_QUICK_SORT_ARRAY(type, array, array_count, comp_macro, exchange_macro) \
|
||||
{\
|
||||
GINT _i_, _j_, _p_, _stack_index_, _start_, _end_;\
|
||||
GINT _start_stack_[64]; \
|
||||
GINT _end_stack_[64];\
|
||||
_start_stack_[0] = 0;\
|
||||
_end_stack_[0] = (array_count);\
|
||||
_stack_index_ = 1;\
|
||||
while (_stack_index_ > 0)\
|
||||
{\
|
||||
_stack_index_ --;\
|
||||
_start_ = _start_stack_[_stack_index_];\
|
||||
_end_ = _end_stack_[_stack_index_];\
|
||||
while (_end_ - _start_ > 2)\
|
||||
{\
|
||||
_p_ = _start_;\
|
||||
_i_ = _start_ + 1;\
|
||||
_j_ = _end_ - 1;\
|
||||
while (_i_<_j_) \
|
||||
{\
|
||||
for(; _i_<=_j_ && comp_macro(((array)[_i_]),((array)[_p_]))<=0; _i_++) ;\
|
||||
if (_i_ > _j_) \
|
||||
{\
|
||||
exchange_macro(type, array, _j_, _p_);\
|
||||
_i_ = _j_;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
for(; _i_<=_j_ && comp_macro(((array)[_j_]),((array)[_p_]))>=0; _j_--) ;\
|
||||
if (_i_ > _j_) \
|
||||
{\
|
||||
exchange_macro(type, array, _j_, _p_);\
|
||||
_i_ = _j_;\
|
||||
}\
|
||||
else if (_i_ < _j_)\
|
||||
{\
|
||||
exchange_macro(type, array, _i_, _j_);\
|
||||
if (_i_+2 < _j_) {_i_++; _j_--;}\
|
||||
else if (_i_+1 < _j_) _i_++;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
if (_i_-_start_ > 1 && _end_-_j_ > 1) \
|
||||
{\
|
||||
if (_i_-_start_ < _end_-_j_-1) \
|
||||
{\
|
||||
_start_stack_[_stack_index_] = _j_+1;\
|
||||
_end_stack_[_stack_index_] = _end_;\
|
||||
_stack_index_ ++;\
|
||||
_end_ = _i_;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
_start_stack_[_stack_index_] = _start_;\
|
||||
_end_stack_[_stack_index_] = _i_;\
|
||||
_stack_index_ ++;\
|
||||
_start_ = _j_+1;\
|
||||
}\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
if (_i_-_start_ > 1)\
|
||||
{\
|
||||
_end_ = _i_;\
|
||||
}\
|
||||
else \
|
||||
{\
|
||||
_start_ = _j_+1;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
if (_end_ - _start_ == 2) \
|
||||
{\
|
||||
if (comp_macro(((array)[_start_]),((array)[_end_-1])) > 0) \
|
||||
{\
|
||||
exchange_macro(type, array, _start_, _end_-1);\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
|
||||
#define GIM_DEF_EXCHANGE_MACRO(type, _array, _i, _j)\
|
||||
{\
|
||||
type _e_tmp_ =(_array)[(_i)];\
|
||||
(_array)[(_i)]=(_array)[(_j)];\
|
||||
(_array)[(_j)]= _e_tmp_;\
|
||||
}\
|
||||
|
||||
#define GIM_COMP_MACRO(x, y) ((GINT)((x) - (y)))
|
||||
|
||||
//! Iterative binary search
|
||||
/*!
|
||||
\param _array
|
||||
\param _start_i the beginning of the array
|
||||
\param _end_i the ending index of the array
|
||||
\param _search_key Value to find
|
||||
\param _comp_macro macro for comparing elements
|
||||
\param _found If 1 the value has found
|
||||
\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value
|
||||
*/
|
||||
#define GIM_BINARY_SEARCH(_array, _start_i, _end_i, _search_key, _comp_macro, _found, _result_index)\
|
||||
{\
|
||||
GUINT _k, _comp_result, _i, _j;\
|
||||
_i = _start_i; \
|
||||
_j = _end_i+1;\
|
||||
_found = 0;\
|
||||
while ((_i < _j) &&( _found==0)) \
|
||||
{\
|
||||
_k = (_j+_i-1)/2;\
|
||||
_comp_result = _comp_macro(_array[_k], _search_key);\
|
||||
if (_comp_result == 0) \
|
||||
{\
|
||||
_result_index = _k; \
|
||||
_found = 1;\
|
||||
}\
|
||||
else if (_comp_result < 0) \
|
||||
{\
|
||||
_i = _k+1;\
|
||||
} \
|
||||
else\
|
||||
{\
|
||||
_j = _k;\
|
||||
}\
|
||||
}\
|
||||
if (_found == 0) \
|
||||
{\
|
||||
_result_index = _j;\
|
||||
}\
|
||||
}\
|
||||
|
||||
|
||||
//! @}
|
||||
#endif // GIM_RADIXSORT_H_INCLUDED
|
||||
@@ -1,113 +0,0 @@
|
||||
#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
|
||||
#define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
|
||||
|
||||
/*! \file gim_tri_capsule_collision.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "GIMPACT/gim_memory.h"
|
||||
|
||||
/*! \addtogroup GEOMETRIC_OPERATIONS
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//! Capsule struct
|
||||
struct GIM_CAPSULE_DATA
|
||||
{
|
||||
GREAL m_radius;
|
||||
vec3f m_point1;
|
||||
vec3f m_point2;
|
||||
};
|
||||
//typedef struct _GIM_CAPSULE_DATA GIM_CAPSULE_DATA;
|
||||
|
||||
#define CALC_CAPSULE_AABB(capsule,aabb)\
|
||||
{\
|
||||
if(capsule.m_point1[0]<capsule.m_point2[0])\
|
||||
{\
|
||||
aabb.minX = capsule.m_point1[0] - capsule.m_radius;\
|
||||
aabb.maxX = capsule.m_point2[0] + capsule.m_radius;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
aabb.minX = capsule.m_point2[0] - capsule.m_radius;\
|
||||
aabb.maxX = capsule.m_point1[0] + capsule.m_radius;\
|
||||
}\
|
||||
if(capsule.m_point1[1]<capsule.m_point2[1])\
|
||||
{\
|
||||
aabb.minY = capsule.m_point1[1] - capsule.m_radius;\
|
||||
aabb.maxY = capsule.m_point2[1] + capsule.m_radius;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
aabb.minY = capsule.m_point2[1] - capsule.m_radius;\
|
||||
aabb.maxY = capsule.m_point1[1] + capsule.m_radius;\
|
||||
}\
|
||||
if(capsule.m_point1[2]<capsule.m_point2[2])\
|
||||
{\
|
||||
aabb.minZ = capsule.m_point1[2] - capsule.m_radius;\
|
||||
aabb.maxZ = capsule.m_point2[2] + capsule.m_radius;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
aabb.minZ = capsule.m_point2[2] - capsule.m_radius;\
|
||||
aabb.maxZ = capsule.m_point1[2] + capsule.m_radius;\
|
||||
}\
|
||||
}\
|
||||
|
||||
//! Utility function for find the closest point between a segment and a triangle
|
||||
/*!
|
||||
|
||||
\param triangle
|
||||
\param s1
|
||||
\param s2
|
||||
\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
|
||||
|
||||
\post The contacts array is not set to 0. It adds aditional contacts
|
||||
*/
|
||||
void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//! Utility function for find the closest point between a capsule and a triangle
|
||||
/*!
|
||||
|
||||
\param triangle
|
||||
\param capsule
|
||||
\param contacts Contains the closest points on the capsule, and the normal points to triangle
|
||||
\return 1 if the triangle collides the capsule
|
||||
\post The contacts array is not set to 0. It adds aditional contacts
|
||||
*/
|
||||
int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
|
||||
//! @}
|
||||
|
||||
#endif // GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
|
||||
@@ -1,256 +0,0 @@
|
||||
#ifndef GIM_TRI_COLLISION_H_INCLUDED
|
||||
#define GIM_TRI_COLLISION_H_INCLUDED
|
||||
|
||||
/*! \file gim_tri_collision.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*! \addtogroup GEOMETRIC_OPERATIONS
|
||||
*/
|
||||
//! @{
|
||||
|
||||
|
||||
#define MAX_TRI_CLIPPING 8
|
||||
|
||||
//! Clips a polygon by a plane
|
||||
#define PLANE_CLIP_POLYGON(plane,polygon_points,polygon_point_count,clipped,clipped_count,max_clipped) \
|
||||
{ \
|
||||
clipped_count = 0; \
|
||||
GUINT _i, _vi, _prevclassif=32000, _classif; \
|
||||
GREAL _d; \
|
||||
for(_i=0;_i<=polygon_point_count;_i++) \
|
||||
{ \
|
||||
_vi = _i%polygon_point_count; \
|
||||
_d = DISTANCE_PLANE_POINT(plane,polygon_points[_vi]); \
|
||||
_classif = _d>G_EPSILON ?1:0; \
|
||||
if(_classif == 0) \
|
||||
{ \
|
||||
if(_prevclassif==1) \
|
||||
{\
|
||||
if(clipped_count<max_clipped) \
|
||||
{\
|
||||
PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
|
||||
clipped_count++; \
|
||||
} \
|
||||
} \
|
||||
if(clipped_count<max_clipped&&_i<polygon_point_count) \
|
||||
{ \
|
||||
VEC_COPY(clipped[clipped_count],polygon_points[_vi]); \
|
||||
clipped_count++; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if(_prevclassif==0) \
|
||||
{ \
|
||||
if(clipped_count<max_clipped) \
|
||||
{ \
|
||||
PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
|
||||
clipped_count++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
_prevclassif = _classif; \
|
||||
} \
|
||||
}\
|
||||
|
||||
|
||||
struct GIM_TRIPLANES_CACHE
|
||||
{
|
||||
/*!
|
||||
Planes are:
|
||||
0 : Face normal plane (0,3)
|
||||
1 : Edge 1 plane (4,7)
|
||||
2 : Edge 2 plane (8,11)
|
||||
3 : Edge 3 plane (12,15)
|
||||
*/
|
||||
vec4f m_planes[4];
|
||||
};
|
||||
//typedef struct _GIM_TRIPLANES_CACHE GIM_TRIPLANES_CACHE;
|
||||
|
||||
|
||||
struct GIM_TRIANGLE_DATA
|
||||
{
|
||||
vec3f m_vertices[3];
|
||||
GIM_TRIPLANES_CACHE m_planes;
|
||||
int m_has_planes;
|
||||
};
|
||||
//typedef struct _GIM_TRIANGLE_DATA GIM_TRIANGLE_DATA;
|
||||
|
||||
//! tri_data is a GIM_TRIANGLE_DATA
|
||||
#define GIM_CALC_TRIANGLE_DATA_PLANES(tri_data)\
|
||||
{\
|
||||
TRIANGLE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],(tri_data).m_vertices[2],(tri_data).m_planes.m_planes[0]);\
|
||||
EDGE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],((tri_data).m_planes.m_planes[0]),((tri_data).m_planes.m_planes[1]));\
|
||||
EDGE_PLANE((tri_data).m_vertices[1],(tri_data).m_vertices[2],((tri_data).m_planes.m_planes[0]),((tri_data).m_planes.m_planes[2]));\
|
||||
EDGE_PLANE((tri_data).m_vertices[2],(tri_data).m_vertices[0],((tri_data).m_planes.m_planes[0]), ((tri_data).m_planes.m_planes[3]));\
|
||||
}\
|
||||
|
||||
//Structure for collision
|
||||
|
||||
struct GIM_TRIANGLE_CONTACT_DATA
|
||||
{
|
||||
GREAL m_penetration_depth;
|
||||
GUINT m_point_count;
|
||||
vec3f m_separating_normal;
|
||||
vec3f m_points[MAX_TRI_CLIPPING];
|
||||
};
|
||||
//typedef struct _GIM_TRIANGLE_CONTACT_DATA GIM_TRIANGLE_CONTACT_DATA;
|
||||
|
||||
struct GIM_TRIANGLE_RAY_CONTACT_DATA
|
||||
{
|
||||
GREAL u;
|
||||
GREAL v;
|
||||
GREAL tparam;
|
||||
GUINT m_face_id;
|
||||
vec3f m_point;
|
||||
vec3f m_normal;
|
||||
};
|
||||
//typedef struct _GIM_TRIANGLE_RAY_CONTACT_DATA GIM_TRIANGLE_RAY_CONTACT_DATA;
|
||||
|
||||
//! Fast Triangle Triangle overlapping test
|
||||
int gim_triangle_triangle_overlap(
|
||||
GIM_TRIANGLE_DATA *tri1,
|
||||
GIM_TRIANGLE_DATA *tri2);
|
||||
|
||||
|
||||
//! Fast but inacurate conservative Triangle Triangle overlapping test
|
||||
int gim_triangle_triangle_overlap_fast(
|
||||
GIM_TRIANGLE_DATA *tri1,
|
||||
GIM_TRIANGLE_DATA *tri2);
|
||||
|
||||
|
||||
//! Finds the contact points from a collision of two triangles
|
||||
/*!
|
||||
Returns the contact points, the penetration depth and the separating normal of the collision
|
||||
between two triangles. The normal is pointing toward triangle 1 from triangle 2
|
||||
*/
|
||||
int gim_triangle_triangle_collision(
|
||||
GIM_TRIANGLE_DATA *tri1,
|
||||
GIM_TRIANGLE_DATA *tri2,
|
||||
GIM_TRIANGLE_CONTACT_DATA * contact_data);
|
||||
|
||||
//Ray triangle
|
||||
|
||||
|
||||
/*!
|
||||
Solve the System for u,v parameters:
|
||||
|
||||
u*axe1[i1] + v*axe2[i1] = vecproj[i1]
|
||||
u*axe1[i2] + v*axe2[i2] = vecproj[i2]
|
||||
|
||||
sustitute:
|
||||
v = (vecproj[i2] - u*axe1[i2])/axe2[i2]
|
||||
|
||||
then the first equation in terms of 'u':
|
||||
|
||||
--> u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1]
|
||||
|
||||
--> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1]
|
||||
|
||||
--> u*(axe1[i1] - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2]
|
||||
|
||||
--> u*((axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2]
|
||||
|
||||
--> u*(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]
|
||||
|
||||
--> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])
|
||||
|
||||
if 0.0<= u+v <=1.0 then they are inside of triangle
|
||||
|
||||
*/
|
||||
#define TRIANGLE_GET_UVPARAMETERS(point,vec1,vec2,vec3,tri_plane,u,v,outside)\
|
||||
{\
|
||||
vec3f _axe1, _axe2, _vecproj;\
|
||||
VEC_DIFF(_axe1,vec2,vec1);\
|
||||
VEC_DIFF(_axe2,vec3,vec1);\
|
||||
VEC_DIFF(_vecproj,point,vec1);\
|
||||
GUINT _i1,_i2;\
|
||||
PLANE_MINOR_AXES(tri_plane, _i1, _i2);\
|
||||
if(fabsf(_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];\
|
||||
}\
|
||||
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];\
|
||||
}\
|
||||
if(u<-G_EPSILON)\
|
||||
{\
|
||||
outside = 1;\
|
||||
}\
|
||||
else if(v<-G_EPSILON)\
|
||||
{\
|
||||
outside = 1;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
float sumuv;\
|
||||
sumuv = u+v;\
|
||||
if(sumuv<-G_EPSILON)\
|
||||
{\
|
||||
outside = 1;\
|
||||
}\
|
||||
else if(sumuv-1.0f>G_EPSILON)\
|
||||
{\
|
||||
outside = 1;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
outside = 0;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
|
||||
//! Finds the collision of a ray and a triangle.
|
||||
#define RAY_TRIANGLE_INTERSECTION(vOrigin,vDir,vec1,vec2,vec3,tri_plane,pout,u,v,tparam,tmax,does_intersect)\
|
||||
{\
|
||||
RAY_PLANE_COLLISION(tri_plane,vDir,vOrigin,pout,tparam,does_intersect);\
|
||||
if(does_intersect != 0)\
|
||||
{\
|
||||
if(tparam<-G_EPSILON||tparam>tmax+G_EPSILON)\
|
||||
{\
|
||||
does_intersect = 0;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
TRIANGLE_GET_UVPARAMETERS(pout,vec1,vec2,vec3,tri_plane,u,v,does_intersect);\
|
||||
does_intersect = !does_intersect;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
#endif // GIM_TRI_COLLISION_H_INCLUDED
|
||||
@@ -1,53 +0,0 @@
|
||||
#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED
|
||||
#define GIM_TRI_SPHERE_COLLISION_H_INCLUDED
|
||||
|
||||
/*! \file gim_tri_sphere_collision.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*! \addtogroup GEOMETRIC_OPERATIONS
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//! Finds the contact points from a collision of a triangle and a sphere
|
||||
/*!
|
||||
\param tri
|
||||
\param center
|
||||
\param radius
|
||||
\param contact_data Contains the closest points on the Sphere, and the normal is pointing to triangle
|
||||
*/
|
||||
int gim_triangle_sphere_collision(
|
||||
GIM_TRIANGLE_DATA *tri,
|
||||
vec3f center, GREAL radius,
|
||||
GIM_TRIANGLE_CONTACT_DATA * contact_data);
|
||||
|
||||
//! @}
|
||||
#endif // GIM_TRI_SPHERE_COLLISION_H_INCLUDED
|
||||
@@ -1,657 +0,0 @@
|
||||
#ifndef GIM_TRIMESH_H_INCLUDED
|
||||
#define GIM_TRIMESH_H_INCLUDED
|
||||
/*! \file gim_trimesh.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "GIMPACT/gim_trimesh_data.h"
|
||||
#include "GIMPACT/gim_vertex_buffer_util.h"
|
||||
#include "GIMPACT/gim_contact.h"
|
||||
|
||||
|
||||
/*! \addtogroup TRIMESH
|
||||
\brief
|
||||
A Trimesh is the basic geometric structure for representing solid objects.
|
||||
<p><strong>CREATING TRIMESHES</strong></p>
|
||||
<ul>
|
||||
<li> For creating trimeshes, you must initialize Buffer managers by calling \ref gimpact_init
|
||||
<li> Then you must define the vertex and index sources by creating them with \ref BUFFER_ARRAYS routines, and then call \ref gim_trimesh_create_from_arrays.
|
||||
<li> An alternative way for creaing trimesh objects is calling \ref gim_trimesh_create_from_data.
|
||||
<li> For access to the trimesh data (vertices, triangle indices), you must call \ref gim_trimesh_locks_work_data , and \ref gim_trimesh_unlocks_work_data for finish the access.
|
||||
<li> Each time when the trimesh data is modified, you must call \ref gim_trimesh_update after.
|
||||
<li> When a trimesh is no longer needed, you must call \ref gim_trimesh_destroy.
|
||||
</ul>
|
||||
|
||||
<p>This is an example of how to create a deformable trimesh that shares vertices with the user application:</p>
|
||||
\code
|
||||
//Declaration of vertices
|
||||
vec3f trimeshvertices[200];
|
||||
//Declaration of indices
|
||||
GUINT trimeshindices[100];
|
||||
|
||||
... Initializing vertices and triangle indices at beginning
|
||||
|
||||
//Then create trimesh
|
||||
GIM_TRIMESH mytrimesh;
|
||||
|
||||
//Calling trimesh create function
|
||||
|
||||
gim_trimesh_create_from_data(
|
||||
&mytrimesh,
|
||||
trimeshvertices,200,
|
||||
0 ,//copy_vertices is 0
|
||||
trimeshindices,
|
||||
100,
|
||||
0, //copy_indices is 0
|
||||
0 //transformed_reply is 0
|
||||
);
|
||||
\endcode
|
||||
<p>Note that parameter transformed_reply is 0, that means that m_transformed_vertex_buffer is a reference to m_source_vertex on the trimesh, and transformations are not avaliable. Use that configuration if you have to simulate a deformable trimesh like cloth or elastic bodies.</p>
|
||||
<p>When the trimesh is no longer needed, destroy it safely with gim_trimesh_destroy()</p>
|
||||
<p><strong>UPDATING TRIMESHES</strong></p>
|
||||
<p>On simulation loops, is needed to update trimeshes every time for update vertices althought updating triangle boxes and planes cache. There is two ways for update trimeshes: </p>
|
||||
<ul>
|
||||
<li> Updating vertices directly. You need to access to the \ref GIM_TRIMESH.m_source_vertex_buffer member; a vertex buffer which has access to the source vertices.
|
||||
\code
|
||||
// Access to the source vertices
|
||||
gim_buffer_array_lock(&mytrimesh.m_source_vertex_buffer, G_MA_READ_WRITE);
|
||||
|
||||
//Get a pointer to the vertex buffer
|
||||
vec3f * vertexpointer = GIM_BUFFER_ARRAY_POINTER(vec3f,mytrimesh.m_source_vertex_buffer,0);
|
||||
|
||||
//Get the amount of vertices
|
||||
int veccount = mytrimesh.m_source_vertex_buffer.m_element_count;
|
||||
|
||||
//Modify vertices
|
||||
for (int i=0;i<veccount ;i++ )
|
||||
{
|
||||
.....
|
||||
.....
|
||||
processing vertices
|
||||
.....
|
||||
.....
|
||||
}
|
||||
|
||||
// Don't forget to unlock the source vertex array
|
||||
gim_buffer_array_unlock(&mytrimesh.m_source_vertex_buffer);
|
||||
|
||||
// Notify that the state of the trimesh is changed
|
||||
gim_trimesh_post_update(&mytrimesh.m_source_vertex_buffer);
|
||||
|
||||
\endcode
|
||||
For making trimeshes that allow to update their vertices, use \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 0.
|
||||
</ul>
|
||||
<ul>
|
||||
<li> Aplying a transformation. Simply use \ref gim_trimesh_set_tranform . Remember that with this method trimeshes must be created with \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 1.
|
||||
</ul>
|
||||
<p> After updating vertices, you must call \ref gim_trimesh_update()</p>
|
||||
<p><strong>TRIMESHES COLLISION</strong></p>
|
||||
<p>Before collide trimeshes, you need to update them first.</p>
|
||||
<p>Then you must use \ref gim_trimesh_trimesh_collision().</p>
|
||||
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//! Prototype for updating vertices
|
||||
typedef void * gim_update_trimesh_function(struct GIM_TRIMESH *);
|
||||
|
||||
struct GIM_TRIMESH_CACHE
|
||||
{
|
||||
GDYNAMIC_ARRAY m_planes_cache_buffer;//! Allocated GIM_TRIPLANES_CACHE
|
||||
GDYNAMIC_ARRAY m_planes_cache_bitset;
|
||||
|
||||
//! Allocated transformed vertices vec3f
|
||||
/*!
|
||||
\invariant must be aligned
|
||||
*/
|
||||
GBUFFER_ARRAY m_transformed_vertex_buffer;
|
||||
GDYNAMIC_ARRAY m_transformed_vertices_cache_bitset;
|
||||
GUINT m_tranformed_scalar_type;
|
||||
|
||||
};
|
||||
|
||||
//! Constant which defines the Bounding volume method
|
||||
#define G_TRIMESH_BOUND_NONE 0
|
||||
//! Constant which defines the Bounding volume method
|
||||
#define G_TRIMESH_BOUND_AABB_TREE 1
|
||||
//! Constant which defines the Bounding volume method
|
||||
#define G_TRIMESH_BOUND_AABB_SET 2
|
||||
|
||||
///MAsk defines
|
||||
#define GIM_TRIMESH_APPLY_TRANSFORMATION 1
|
||||
#define GIM_TRIMESH_NEED_UPDATE 2
|
||||
|
||||
//! Trimesh
|
||||
struct GIM_TRIMESH
|
||||
{
|
||||
GUINT m_trimesh_data_handle;//!< Handle to a trimesh data object
|
||||
GIM_TRIMESH_DATA * m_unlocked_trimesh_data; //!< temporal pointer
|
||||
char m_mask;//!< Don't use directly
|
||||
GIM_AABB_SET * m_aabbset;
|
||||
GIM_TRIMESH_CACHE * m_cache;
|
||||
gim_update_trimesh_function * m_update_callback;//! If null, then m_transform is applied.
|
||||
mat4f m_transform;
|
||||
mat4f m_inv_transform;
|
||||
};
|
||||
//typedef struct _GIM_TRIMESH GIM_TRIMESH;
|
||||
|
||||
//! Return the bound method
|
||||
/*!
|
||||
\ return G_TRIMESH_BOUND_AABB_TREE or G_TRIMESH_BOUND_AABB_SET
|
||||
*/
|
||||
GUINT gim_trimesh_get_bound_method(GIM_TRIMESH * trimesh);
|
||||
|
||||
/// Info about mesh
|
||||
//! Return the trimesh triangle count
|
||||
GUINT gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh);
|
||||
|
||||
GUINT gim_trimesh_get_vertex_count(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
|
||||
char gim_trimesh_has_tranform(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Get the global bounding box
|
||||
void gim_trimesh_get_aabb(GIM_TRIMESH * trimesh,aabb3f * bound);
|
||||
|
||||
//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
|
||||
char gim_trimesh_needs_update(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Change the state of the trimesh for force it to update
|
||||
/*!
|
||||
Call it after made changes to the trimesh.
|
||||
\post gim_trimesh_need_update(trimesh) will return 1
|
||||
\sa gim_trimesh_needs_update
|
||||
*/
|
||||
void gim_trimesh_post_update(GIM_TRIMESH * trimesh);
|
||||
|
||||
|
||||
|
||||
//! Creates cache information for this mesh
|
||||
/*!
|
||||
*/
|
||||
void gim_trimesh_initialize_cache(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Destroys the cache
|
||||
/*!
|
||||
*/
|
||||
void gim_trimesh_destroy_cache(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Creates an AABB set for triangles.
|
||||
/*!
|
||||
*/
|
||||
void gim_trimesh_initialize_bound(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Destroys the AABB set
|
||||
/*!
|
||||
*/
|
||||
void gim_trimesh_destroy_bound(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Creates a trimesh
|
||||
/*!
|
||||
|
||||
\param trimesh for be created
|
||||
\param trimesh_data_handle Handle to a trimesh data
|
||||
\param apply_transform If 1, then it transforms the source vertices.
|
||||
\param create_Cache If 1, then it allocates a cache for transformed vertices and planes.
|
||||
\post Adds a reference to the trimesh_data_handle, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
|
||||
*/
|
||||
void gim_trimesh_create(GIM_TRIMESH * trimesh, GUINT trimesh_data_handle,char apply_transform,char create_cache);
|
||||
|
||||
//! Creates the aabb set and the triangles cache
|
||||
/*!
|
||||
|
||||
\param trimesh
|
||||
\param vertex_array
|
||||
\param triindex_array
|
||||
\param apply_transform If 1, then it transforms the source vertices.
|
||||
\param create_Cache If 1, then it allocates a cache for transformed vertices and planes.
|
||||
\param vertex_scalar_type G_STYPE_REAL or G_STYPE_REAL2
|
||||
\param index_scalar_type G_STYPE_SHORT,G_STYPE_USHORT,G_STYPE_INT or G_STYPE_UINT
|
||||
\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
|
||||
*/
|
||||
void gim_trimesh_create_from_arrays(GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type,
|
||||
char apply_transform,char create_cache);
|
||||
|
||||
|
||||
|
||||
//! Create a trimesh from vertex array and an index array
|
||||
/*!
|
||||
\param trimesh An uninitialized GIM_TRIMESH structure
|
||||
\param vertex_array A buffer to a vec3f array
|
||||
\param vertex_count
|
||||
\param triindex_array
|
||||
\param triangle_count
|
||||
\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
|
||||
\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
|
||||
\param apply_transform If 1, then it transforms the source vertices.
|
||||
\param create_Cache If 1, then it allocates a cache for transformed vertices and planes.
|
||||
*/
|
||||
void gim_trimesh_create_from_data(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT triangle_count,char copy_indices,
|
||||
char apply_transform,char create_cache);
|
||||
|
||||
//! Clears auxiliary data and releases buffer arrays
|
||||
void gim_trimesh_destroy(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Copies two meshes
|
||||
/*!
|
||||
\param source_trimesh
|
||||
\param dest_trimesh
|
||||
\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
|
||||
\param apply_transform If 1, then it transforms the source vertices.
|
||||
\param create_Cache If 1, then it allocates a cache for transformed vertices and planes.
|
||||
*/
|
||||
void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,GIM_TRIMESH * dest_trimesh, char copy_by_reference,
|
||||
char apply_transform,char create_cache);
|
||||
|
||||
|
||||
//! Locks the trimesh for working with it
|
||||
/*!
|
||||
\post locks m_trimesh_data_handle in G_MA_READ_ONLY and m_transformed_vertex_buffer in G_MA_READ_WRITE.
|
||||
\param trimesh
|
||||
*/
|
||||
void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh);
|
||||
|
||||
|
||||
//! unlocks the trimesh
|
||||
/*!
|
||||
\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
|
||||
\param trimesh
|
||||
*/
|
||||
void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Updates m_transformed_vertex_buffer
|
||||
/*!
|
||||
\pre m_transformed_vertex_buffer must be unlocked
|
||||
*/
|
||||
void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh);
|
||||
|
||||
|
||||
//! Updates the cache variables
|
||||
void gim_trimesh_update_cache(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Updates m_aabbset and m_planes_cache_bitset
|
||||
/*!
|
||||
\pre gim_trimesh_locks_work_data must be called before
|
||||
*/
|
||||
void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Calls before perfom collisions. Updates the trimesh if needed
|
||||
/*!
|
||||
\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
|
||||
*/
|
||||
void gim_trimesh_update(GIM_TRIMESH * trimesh);
|
||||
|
||||
//! Set the transform of a trimesh
|
||||
/*!
|
||||
\post This function calls to gim_trimesh_post_update
|
||||
*/
|
||||
void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform);
|
||||
|
||||
//! Fetch triangle data
|
||||
/*!
|
||||
\pre gim_trimesh_locks_work_data must be called before
|
||||
*/
|
||||
void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data);
|
||||
|
||||
//! Fetch triangle data
|
||||
/*!
|
||||
\pre gim_trimesh_locks_work_data must be called before
|
||||
If Planes cache is not avaliable, it doesn't calc the planes
|
||||
*/
|
||||
void gim_trimesh_get_triangle_data_lazy(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data);
|
||||
|
||||
|
||||
//! Fetch triangle vertices, transformed to global space
|
||||
/*!
|
||||
\pre gim_trimesh_locks_work_data must be called before
|
||||
*/
|
||||
void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3);
|
||||
|
||||
//! Fetch a single transformed vertex
|
||||
/*!
|
||||
\pre gim_trimesh_locks_work_data must be called before
|
||||
*/
|
||||
void gim_trimesh_get_vertex(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec);
|
||||
|
||||
//! Fetch triangle vertices, transformed to global space
|
||||
/*!
|
||||
\pre gim_trimesh_locks_work_data must be called before
|
||||
*/
|
||||
void gim_trimesh_get_triangle_vertices_local(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3);
|
||||
|
||||
//! Fetch a single transformed vertex
|
||||
/*!
|
||||
\pre gim_trimesh_locks_work_data must be called before
|
||||
*/
|
||||
void gim_trimesh_get_vertex_local(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec);
|
||||
|
||||
|
||||
//! Finds Intersected boxes
|
||||
/*!
|
||||
\param trimesh
|
||||
\param test_aabb Box for collision query, in global space
|
||||
\param collided Array of GUINT elements, indices of trinagles. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_trimesh_midphase_box_collision(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided);
|
||||
|
||||
|
||||
|
||||
//! Finds Intersected boxes in local space
|
||||
/*!
|
||||
\param trimesh
|
||||
\param test_aabb Box for collision query, in global space
|
||||
\param collided Array of GUINT elements, indices of trinagles. Must be initialized before (Reserve size ~ 100)
|
||||
*/
|
||||
void gim_trimesh_midphase_box_collision_local(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided);
|
||||
|
||||
|
||||
//! Finds overlapping boxes between sets
|
||||
/*!
|
||||
\param trimesh1
|
||||
\param trimesh2
|
||||
\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
|
||||
\param swaped If 1, result pairs are swaped and that would means that element 1 belongs to trimesh2 and element 2 belongs to trimesh1. 0 is normal.
|
||||
*/
|
||||
void gim_trimesh_midphase_trimesh_collision(GIM_TRIMESH * trimesh1,
|
||||
GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * collision_pairs, char * swaped);
|
||||
|
||||
|
||||
|
||||
|
||||
//! Trimesh Trimesh Collisions
|
||||
/*!
|
||||
Before use this function you must update each trimesh:
|
||||
\code
|
||||
gim_trimesh_update(TriMesh1);
|
||||
gim_trimesh_update(TriMesh2);
|
||||
\endcode
|
||||
Then you must use the trimesh collision in this way:
|
||||
\code
|
||||
int collide_trimeshes(GIM_TRIMESH * TriMesh1, GIM_TRIMESH * TriMesh2)
|
||||
{
|
||||
//Create contact list
|
||||
GDYNAMIC_ARRAY trimeshcontacts;
|
||||
GIM_CREATE_CONTACT_LIST(trimeshcontacts);
|
||||
|
||||
//Collide trimeshes
|
||||
gim_trimesh_trimesh_collision(TriMesh1,TriMesh2,&trimeshcontacts);
|
||||
|
||||
if(trimeshcontacts.m_size == 0) //do nothing
|
||||
{
|
||||
GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Getting a pointer to the contact array
|
||||
GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
|
||||
|
||||
int contactcount = trimeshcontacts.m_size;
|
||||
int i;
|
||||
//Process contacts
|
||||
for (i=0;i<contactcount ;i++)
|
||||
{
|
||||
//Do something with the contact (ptrimeshcontacts)
|
||||
......
|
||||
......
|
||||
// Like creating joints or anything else
|
||||
......
|
||||
......
|
||||
ptrimeshcontacts++;
|
||||
}
|
||||
GIM_DYNARRAY_DESTROY(trimeshcontacts);
|
||||
return contactcount;
|
||||
}
|
||||
\endcode
|
||||
In each contact
|
||||
<ul>
|
||||
<li> m_handle1 points to trimesh1.
|
||||
<li> m_handle2 points to trimesh2.
|
||||
<li> m_feature1 Is a triangle index of trimesh1.
|
||||
<li> m_feature2 Is a triangle index of trimesh2.
|
||||
</ul>
|
||||
|
||||
\param trimesh1 Collider
|
||||
\param trimesh2 Collidee
|
||||
\param contacts A GIM_CONTACT array. Must be initialized
|
||||
*/
|
||||
void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts);
|
||||
|
||||
|
||||
//! Trimesh Sphere Collisions
|
||||
/*!
|
||||
Before use this function you must update the trimesh:
|
||||
\code
|
||||
gim_trimesh_update(trimesh);
|
||||
\endcode
|
||||
Then you must use this function in this way:
|
||||
\code
|
||||
int collide_trimesh_sphere(GIM_TRIMESH * trimesh, vec3f center,GREAL radius)
|
||||
{
|
||||
//Create contact list
|
||||
GDYNAMIC_ARRAY trimeshcontacts;
|
||||
GIM_CREATE_CONTACT_LIST(trimeshcontacts);
|
||||
|
||||
//Collide trimeshes
|
||||
gim_trimesh_sphere_collision(trimesh,center,radius,&trimeshcontacts);
|
||||
|
||||
if(trimeshcontacts.m_size == 0) //do nothing
|
||||
{
|
||||
GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Getting a pointer to the contact array
|
||||
GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
|
||||
|
||||
int contactcount = trimeshcontacts.m_size;
|
||||
int i;
|
||||
//Process contacts
|
||||
for (i=0;i<contactcount ;i++)
|
||||
{
|
||||
//Do something with the contact (ptrimeshcontacts)
|
||||
......
|
||||
......
|
||||
// Like creating joints or anything else
|
||||
......
|
||||
......
|
||||
ptrimeshcontacts++;
|
||||
}
|
||||
GIM_DYNARRAY_DESTROY(trimeshcontacts);
|
||||
return contactcount;
|
||||
}
|
||||
\endcode
|
||||
|
||||
In each contact
|
||||
<ul>
|
||||
<li> m_handle1 points to trimesh.
|
||||
<li> m_handle2 points to NULL.
|
||||
<li> m_feature1 Is a triangle index of trimesh.
|
||||
</ul>
|
||||
|
||||
\param trimesh
|
||||
\param center
|
||||
\param radius
|
||||
\param contacts A GIM_CONTACT array. Must be initialized
|
||||
*/
|
||||
void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts);
|
||||
|
||||
|
||||
//! Trimesh Capsule collision
|
||||
/*!
|
||||
Find the closest primitive collided by the ray.
|
||||
|
||||
Before use this function you must update the trimesh:
|
||||
\code
|
||||
gim_trimesh_update(trimesh);
|
||||
\endcode
|
||||
Then you must use this function in this way:
|
||||
\code
|
||||
int collide_trimesh_capsule(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule)
|
||||
{
|
||||
//Create contact list
|
||||
GDYNAMIC_ARRAY trimeshcontacts;
|
||||
GIM_CREATE_CONTACT_LIST(trimeshcontacts);
|
||||
|
||||
//Collide trimeshes
|
||||
gim_trimesh_capsule_collision(trimesh,capsule,&trimeshcontacts);
|
||||
|
||||
if(trimeshcontacts.m_size == 0) //do nothing
|
||||
{
|
||||
GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Getting a pointer to the contact array
|
||||
GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
|
||||
|
||||
int contactcount = trimeshcontacts.m_size;
|
||||
int i;
|
||||
//Process contacts
|
||||
for (i=0;i<contactcount ;i++)
|
||||
{
|
||||
//Do something with the contact (ptrimeshcontacts)
|
||||
......
|
||||
......
|
||||
// Like creating joints or anything else
|
||||
......
|
||||
......
|
||||
ptrimeshcontacts++;
|
||||
}
|
||||
GIM_DYNARRAY_DESTROY(trimeshcontacts);
|
||||
return contactcount;
|
||||
}
|
||||
\endcode
|
||||
|
||||
In each contact
|
||||
<ul>
|
||||
<li> m_handle1 points to trimesh.
|
||||
<li> m_handle2 points to NULL.
|
||||
<li> m_feature1 Is a triangle index of trimesh.
|
||||
</ul>
|
||||
|
||||
\param trimesh
|
||||
\param capsule
|
||||
\param contacts A GIM_CONTACT array. Must be initialized
|
||||
*/
|
||||
void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
|
||||
|
||||
|
||||
///Function for create Trimesh Plane collision result
|
||||
#define GIM_CREATE_TRIMESHPLANE_CONTACTS(dynarray) GIM_DYNARRAY_CREATE(vec4f,dynarray,G_ARRAY_GROW_SIZE)
|
||||
|
||||
//! Trimesh Plane Collisions
|
||||
/*!
|
||||
|
||||
Before use this function you must update the trimesh:
|
||||
\code
|
||||
gim_trimesh_update(trimesh);
|
||||
\endcode
|
||||
Then you must use this function in this way:
|
||||
\code
|
||||
int collide_trimesh_plane(GIM_TRIMESH * trimesh, vec4f plane)
|
||||
{
|
||||
//Create contact list
|
||||
GDYNAMIC_ARRAY tri_plane_contacts;
|
||||
GIM_CREATE_TRIMESHPLANE_CONTACTS(tri_plane_contacts);
|
||||
|
||||
//Collide trimeshes
|
||||
gim_trimesh_plane_collision(trimesh,plane,&tri_plane_contacts);
|
||||
|
||||
if(tri_plane_contacts.m_size == 0) //do nothing
|
||||
{
|
||||
GIM_DYNARRAY_DESTROY(tri_plane_contacts);//clean contact array
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Getting a pointer to the contact array
|
||||
vec4f * planecontacts = GIM_DYNARRAY_POINTER(vec4f,tri_plane_contacts);
|
||||
|
||||
int contactcount = tri_plane_contacts.m_size;
|
||||
int i;
|
||||
//Process contacts
|
||||
for (i=0;i<contactcount ;i++)
|
||||
{
|
||||
vec3f contactpoint;
|
||||
GREAL contactdis;
|
||||
|
||||
VEC_COPY(contactpoint,planecontacts[i]); //Get contact point
|
||||
contactdis = planecontacts[i][3]; // Get distance depth
|
||||
|
||||
//Do something with the contact
|
||||
......
|
||||
......
|
||||
// Like creating joints or anything else
|
||||
......
|
||||
......
|
||||
}
|
||||
GIM_DYNARRAY_DESTROY(tri_plane_contacts);
|
||||
return contactcount;
|
||||
}
|
||||
\endcode
|
||||
|
||||
In each contact the 3 first coordinates refers to the contact point, the fourth refers to the distance depth and the normal is the normal of the plane.
|
||||
|
||||
\param trimesh
|
||||
\param plane vec4f plane
|
||||
\param contacts A vec4f array. Must be initialized (~100). Each element have the coordinate point in the first 3 elements, and vec4f[3] has the penetration depth.
|
||||
*/
|
||||
void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts);
|
||||
|
||||
|
||||
//! Trimesh Ray Collisions
|
||||
/*!
|
||||
\param trimesh
|
||||
\param origin
|
||||
\param dir
|
||||
\param tmax
|
||||
\param contact
|
||||
\return 1 if the ray collides, else 0
|
||||
*/
|
||||
int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
|
||||
|
||||
|
||||
//! Trimesh Ray Collisions closest
|
||||
/*!
|
||||
Find the closest primitive collided by the ray
|
||||
\param trimesh
|
||||
\param origin
|
||||
\param dir
|
||||
\param tmax
|
||||
\param contact
|
||||
\return 1 if the ray collides, else 0
|
||||
*/
|
||||
int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
|
||||
#endif // GIM_TRIMESH_H_INCLUDED
|
||||
@@ -1,182 +0,0 @@
|
||||
#ifndef GIM_TRIMESH_DATA_H_INCLUDED
|
||||
#define GIM_TRIMESH_DATA_H_INCLUDED
|
||||
/*! \file gim_trimesh_data.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "GIMPACT/gim_boxpruning.h"
|
||||
|
||||
/*! \addtogroup TRIMESH_DATA
|
||||
\brief
|
||||
|
||||
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//! Class for managing Mesh data
|
||||
struct GIM_TRIMESH_DATA
|
||||
{
|
||||
GUINT m_vertex_scalar_type;//!< G_STYPE_REAL or G_STYPE_REAL2
|
||||
GUINT m_index_scalar_type;//!< G_STYPE_INT,G_STYPE_UINT, G_STYPE_SHORT or G_STYPE_USHORT
|
||||
|
||||
GBUFFER_ARRAY m_source_vertex_buffer;//!< Buffer of vec3f coordinates
|
||||
|
||||
//! vec3ui,vec3i,vec3s or vec3us Indices of triangles,groups of three elements.
|
||||
/*!
|
||||
Array of Triangle indices. Each triple contains indices of the vertices for each triangle.
|
||||
Array size = Triangle count
|
||||
*/
|
||||
GBUFFER_ARRAY m_tri_index_buffer;
|
||||
|
||||
GIM_AABB_TREE m_bv_tree;
|
||||
|
||||
GUINT m_ref_count;//!< Refvertex_scalar_typeerence counting
|
||||
GUINT m_handle;
|
||||
};
|
||||
|
||||
//Functions for trimesh data
|
||||
//Trimesh data manager
|
||||
|
||||
void gim_trimesh_data_manager_init();
|
||||
void gim_trimesh_data_manager_end();
|
||||
int gim_trimesh_data_is_valid_manager();
|
||||
|
||||
//! Test if the trimesh data has bounding volume tree
|
||||
int gim_trimesh_data_has_bv_tree(GUINT trimesh_data_handle);
|
||||
|
||||
/*!
|
||||
\param trimesh_data_handle Must be superior to 0
|
||||
*/
|
||||
void gim_trimesh_data_get(GUINT trimesh_data_handle,GIM_TRIMESH_DATA ** trimesh_data);
|
||||
|
||||
|
||||
//! Creates an empty trimesh
|
||||
void gim_trimesh_data_create_empty(GUINT * trimesh_data_handle);
|
||||
|
||||
|
||||
//! Create a trimesh from vertex array and an index array
|
||||
/*!
|
||||
\param trimesh_data_handle A pointer to receive the trimesh handle
|
||||
\param vertex_array A buffer to a vec3f array
|
||||
\param vertex_count
|
||||
\param triindex_array
|
||||
\param index_count
|
||||
\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
|
||||
\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
|
||||
*/
|
||||
void gim_trimesh_data_create_from_arrays(GUINT * trimesh_data_handle, GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type);
|
||||
|
||||
//! Create a trimesh from vertex array and an index array
|
||||
/*!
|
||||
\param trimesh_data_handle A pointer to receive the trimesh handle
|
||||
\param vertex_array A buffer to a vec3f array
|
||||
\param vertex_count
|
||||
\param triindex_array
|
||||
\param index_count
|
||||
\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
|
||||
\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
|
||||
*/
|
||||
void gim_trimesh_data_create_from_array_data(GUINT * trimesh_data_handle, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT triangle_count,char copy_indices);
|
||||
|
||||
//! Increase the reference to a GIM_TRIMESH_DATA object
|
||||
/*!
|
||||
Use this function for prevents destroying the trimesh data when it stills
|
||||
is being used. If you have a singleton scene manager, increase the references to all trimesh data resources.
|
||||
*/
|
||||
void gim_trimesh_data_inc_ref(GUINT trimesh_data_handle);
|
||||
|
||||
//! Decrease the reference to a GIM_TRIMESH_DATA object, and attempts to destroy it
|
||||
/*!
|
||||
Use this function for safe destruction of the trimesh data. If the reference of the trimesh is bigger than 1, then
|
||||
it doen't destroy the trimesh data.
|
||||
*/
|
||||
void gim_trimesh_data_dec_ref(GUINT trimesh_data_handle);
|
||||
|
||||
|
||||
void gim_trimesh_data_destroy(GUINT trimesh_data_handle);
|
||||
|
||||
/*!
|
||||
Locks m_source_vertex_buffer and m_tri_index_buffer
|
||||
*/
|
||||
void gim_trimesh_data_lock(GUINT trimesh_data_handle, int access,GIM_TRIMESH_DATA ** trimesh_data);
|
||||
|
||||
/*!
|
||||
Unlocks m_source_vertex_buffer and m_tri_index_buffer
|
||||
*/
|
||||
void gim_trimesh_data_unlock(GUINT trimesh_data_handle);
|
||||
|
||||
GUINT gim_trimesh_data_get_vertex_count(GUINT trimesh_data_handle);
|
||||
GUINT gim_trimesh_data_get_triangle_count(GUINT trimesh_data_handle);
|
||||
|
||||
//! Get triangle indices
|
||||
/*!
|
||||
\pre trimesh_data must be locked
|
||||
*/
|
||||
void gim_trimesh_data_get_triangle_indices(GIM_TRIMESH_DATA * trimesh_data, GUINT tri_index, GUINT * indices);
|
||||
|
||||
//! Get trimesh vertex
|
||||
/*!
|
||||
\pre trimesh_data must be locked
|
||||
*/
|
||||
void gim_trimesh_data_get_vertex(GIM_TRIMESH_DATA * trimesh_data, GUINT vertex_index, vec3f vec);
|
||||
|
||||
//! Get triangle vertices
|
||||
/*!
|
||||
\pre trimesh_data must be locked
|
||||
*/
|
||||
void gim_trimesh_data_get_triangle_vertices(GIM_TRIMESH_DATA * trimesh_data, GUINT tri_index, vec3f v1, vec3f v2, vec3f v3);
|
||||
|
||||
//! Builds a Bounding Volume tree from the Trimesh data
|
||||
void gim_trimesh_data_build_aabbtree(GUINT trimesh_data_handle);
|
||||
|
||||
//! Copies two meshes
|
||||
/*!
|
||||
\param source_trimesh_data
|
||||
\param dest_trimesh_data
|
||||
\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
|
||||
\param transformed_reply If 1, transformed vertices are reply of source vertives. 1 Is recommended
|
||||
*/
|
||||
void gim_trimesh_data_copy(GUINT source_trimesh_data,GUINT dest_trimesh_data, char copy_by_reference);
|
||||
|
||||
//! Copies two meshes
|
||||
/*!
|
||||
\param source_trimesh_data
|
||||
\param dest_trimesh_data
|
||||
\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
|
||||
\param transformed_reply If 1, transformed vertices are reply of source vertives. 1 Is recommended
|
||||
*/
|
||||
void gim_trimesh_data_create_copy(GUINT source_trimesh_data,GUINT * dest_trimesh_data, char copy_by_reference);
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
|
||||
#endif // GIM_TRIMESH_DATA_H_INCLUDED
|
||||
@@ -1,106 +0,0 @@
|
||||
#ifndef GIM_VERTEX_BUFFER_UTIL_H_INCLUDED
|
||||
#define GIM_VERTEX_BUFFER_UTIL_H_INCLUDED
|
||||
/*! \file gim_trimesh_data.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "GIMPACT/gim_geometry.h"
|
||||
#include "GIMPACT/gim_memory.h"
|
||||
|
||||
/*! \addtogroup VERTEX_BUFFER_UTIL
|
||||
\brief
|
||||
Functions for processing vertex buffers
|
||||
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//Macro for processing vertex buffers
|
||||
#define GIM_PROCESS_VERTEX_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,_src_scalar_type,_dst_scalar_type)\
|
||||
{\
|
||||
if(_src_scalar_type == G_STYPE_REAL)\
|
||||
{\
|
||||
if(_dst_scalar_type == G_STYPE_REAL)\
|
||||
{\
|
||||
GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,vec3f,vec3f);\
|
||||
}\
|
||||
else if(_dst_scalar_type == G_STYPE_REAL2)\
|
||||
{\
|
||||
GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,vec3f,vec3d);\
|
||||
}\
|
||||
}\
|
||||
else if(_src_scalar_type == G_STYPE_REAL2)\
|
||||
{\
|
||||
if(_dst_scalar_type == G_STYPE_REAL)\
|
||||
{\
|
||||
GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,vec3d,vec3f);\
|
||||
}\
|
||||
else if(_dst_scalar_type == G_STYPE_REAL2)\
|
||||
{\
|
||||
GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,vec3d,vec3f);\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
|
||||
|
||||
//******Common kernels*******//
|
||||
#define MULT_MAT_VEC4_KERNEL(_mat,_src,_dst) MAT_DOT_VEC_3X4((_dst),(_mat),(_src))
|
||||
|
||||
#define COPY_VEC3_KERNEL(_uni,_src,_dst) VEC_COPY((_dst),(_src))
|
||||
//******+++++++++++*******//
|
||||
|
||||
//! Creates a packed vertex buffer with vec3f
|
||||
void gim_create_common_vertex_buffer(GBUFFER_ARRAY * vertex_buffer,GUINT vertex_count);
|
||||
|
||||
//! Copies vertex buffer arrays
|
||||
/*!
|
||||
They must have the same size
|
||||
*/
|
||||
void gim_copy_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type);
|
||||
|
||||
|
||||
//! Applies a linear transformation to vertices
|
||||
/*!
|
||||
They must have the same size
|
||||
*/
|
||||
void gim_transform_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type, mat4f transform);
|
||||
|
||||
|
||||
//! General processing for vertex arrays
|
||||
/*!
|
||||
It's an alternative to GIM_PROCESS_VERTEX_BUFFER_ARRAY
|
||||
*/
|
||||
void gim_process_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type, void *uniform_data,gim_kernel_func kernel_func);
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
|
||||
#endif // GIM_VERTEX_BUFFER_UTIL_H_INCLUDED
|
||||
@@ -1,47 +0,0 @@
|
||||
#ifndef GIMPACT_H_INCLUDED
|
||||
#define GIMPACT_H_INCLUDED
|
||||
|
||||
/*! \file gimpact.h
|
||||
\author Francisco Le<4C>n N<>jera
|
||||
*/
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
This source file is part of GIMPACT Library.
|
||||
|
||||
For the latest info, see http://gimpact.sourceforge.net/
|
||||
|
||||
Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
|
||||
email: projectileman@yahoo.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of EITHER:
|
||||
(1) The GNU Lesser General Public License as published by the Free
|
||||
Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version. The text of the GNU Lesser
|
||||
General Public License is included with this library in the
|
||||
file GIMPACT-LICENSE-LGPL.TXT.
|
||||
(2) The BSD-style license that is included with this library in
|
||||
the file GIMPACT-LICENSE-BSD.TXT.
|
||||
(3) The zlib/libpng license that is included with this library in
|
||||
the file GIMPACT-LICENSE-ZLIB.TXT.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
|
||||
GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "GIMPACT/gim_trimesh.h"
|
||||
|
||||
/*! \defgroup GIMPACT_INIT
|
||||
*/
|
||||
//! @{
|
||||
//! Call this for initialize GIMPACT system structures.
|
||||
void gimpact_init();
|
||||
//! Call this for clean GIMPACT system structures.
|
||||
void gimpact_terminate();
|
||||
//! @}
|
||||
#endif // GIMPACT_H_INCLUDED
|
||||
Reference in New Issue
Block a user