gimpact 0.2 prep

This commit is contained in:
ejcoumans
2007-06-22 16:59:13 +00:00
parent a399784077
commit 55258a8a72
36 changed files with 0 additions and 12082 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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