aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/GIMPACT/include
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/GIMPACT/include')
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h323
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h115
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h1872
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h147
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h1040
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h258
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h111
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_collision.h253
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h51
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h539
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gimpact.h45
11 files changed, 4754 insertions, 0 deletions
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h
new file mode 100644
index 0000000..68b68d0
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h
@@ -0,0 +1,323 @@
1#ifndef GIM_BOXPRUNING_H_INCLUDED
2#define GIM_BOXPRUNING_H_INCLUDED
3
4/*! \file gim_boxpruning.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include "GIMPACT/gim_radixsort.h"
36#include "GIMPACT/gim_geometry.h"
37
38/*! \defgroup BOX_PRUNNING
39
40\brief
41Tools 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 .
42<ul>
43<li> For using these collision routines, you must create a \ref GIM_AABB_SET by using this function : \ref gim_aabbset_alloc.
44<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
45<li> Before calling collision functions, you must create a pair set with \ref GIM_CREATE_PAIR_SET
46<li> For finding collision pairs on a scene (common space for objects), call \ref gim_aabbset_self_intersections
47<li> For finding collision pairs between two box sets , call \ref gim_aabbset_box_collision
48<li> After using collision routines, you must destroy the pairset with \ref GIM_DESTROY_PAIR_SET
49<li> When the box set is no longer used, you must destroy it by calling \ref gim_aabbset_destroy
50</ul>
51*/
52//! @{
53//! Overlapping pair
54struct GIM_PAIR
55{
56 GUINT m_index1;
57 GUINT m_index2;
58};
59//typedef struct _GIM_PAIR GIM_PAIR;
60
61//! Box container
62struct GIM_AABB_SET
63{
64 GUINT m_count;
65 aabb3f m_global_bound;//!< Global calculated bound of all boxes
66 aabb3f * m_boxes;
67 GUINT * m_maxcoords;//!<Upper corners of the boxes, in integer representation
68 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
69 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
70};
71//typedef struct _GIM_AABB_SET GIM_AABB_SET;
72
73//! Function for creating an overlapping pair set
74#define GIM_CREATE_PAIR_SET(dynarray) GIM_DYNARRAY_CREATE(GIM_PAIR,dynarray,G_ARRAY_GROW_SIZE)
75//! Function for destroying an overlapping pair set
76#define GIM_DESTROY_PAIR_SET(dynarray) GIM_DYNARRAY_DESTROY(dynarray)
77
78//! Allocate memory for all aabb set.
79void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT count);
80
81//! Destroys the aabb set.
82void gim_aabbset_destroy(GIM_AABB_SET * aabbset);
83
84//! Calcs the global bound only
85/*!
86\pre aabbset must be allocated. And the boxes must be already set.
87*/
88void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset);
89
90//! Sorts the boxes for box prunning.
91/*!
921) find the integer representation of the aabb coords
932) Sorts the min coords
943) Calcs the global bound
95\pre aabbset must be allocated. And the boxes must be already set.
96\param aabbset
97\param calc_global_bound If 1 , calcs the global bound
98\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
99*/
100void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound);
101
102//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
103/*!
104\pre aabbset must be allocated and sorted, the boxes must be already set.
105\param aabbset Must be sorted. Global bound isn't required
106\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
107*/
108void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
109
110//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
111/*!
112\pre aabbset must be allocated, the boxes must be already set.
113\param aabbset Global bound isn't required. Doen't need to be sorted.
114\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
115*/
116void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
117
118//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
119/*!
120\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
121\param aabbset1 Must be sorted, Global bound is required.
122\param aabbset2 Must be sorted, Global bound is required.
123\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
124*/
125void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
126
127//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
128/*!
129\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
130\param aabbset1 Must be sorted, Global bound is required.
131\param aabbset2 Must be sorted, Global bound is required.
132\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
133*/
134void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
135
136
137/*
138 Brute-Force Vs Sorted pruning
139Different approaches must be applied when colliding sets with different number of
140elements. When sets have less of 100 boxes, is often better to apply force brute
141approach instead of sorted methods, because at lowlevel bruteforce routines gives
142better perormance and consumes less resources, due of their simplicity.
143But when sets are larger, the complexiity of bruteforce increases exponencially.
144In the case of large sets, sorted approach is applied. So GIMPACT has the following
145strategies:
146
147On Sorting sets:
148!) When sets have more of 140 boxes, the boxes are sorted by its coded min coord
149and the global box is calculated. But when sets are smaller (less of 140 boxes),
150Is convenient to apply brute force approach.
151
152*******************************************************************************/
153
154//! Constant for apply approaches between brute force and sorted pruning on bipartite queries
155#define GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES 600
156//! Constant for apply approaches between brute force and sorted pruning for box collision
157#define GIM_MIN_SORTED_PRUNING_BOXES 140
158
159
160//Use these functions for general initialization
161
162//! Initalizes the set. Sort Boxes if needed.
163/*!
164\pre aabbset must be allocated. And the boxes must be already set.
165\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
166 else it Sorts the entire set( Only applicable for large sets)
167*/
168void gim_aabbset_update(GIM_AABB_SET * aabbset);
169
170///Use these functions for general collision
171
172//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
173/*!
174This 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:
175\code
176//Create contact list
177GDYNAMIC_ARRAY collision_pairs;
178GIM_CREATE_PAIR_SET(collision_pairs);
179//Do collision
180gim_aabbset_self_intersections(&aabbset,&collision_pairs);
181if(collision_pairs.m_size==0)
182{
183 GIM_DYNARRAY_DESTROY(collision_pairs);//
184 return; //no collisioin
185}
186
187//pair pointer
188GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
189GUINT i, ti1,ti2;
190for (i=0;i<collision_pairs.m_size; i++)
191{
192 ti1 = pairs[i].m_index1;
193 ti2 = pairs[i].m_index2;
194 //Do something with the pairs
195 ....
196 ....
197 ...
198
199}
200//Terminate
201GIM_DYNARRAY_DESTROY(dummycontacts);
202GIM_DYNARRAY_DESTROY(collision_pairs);
203\endcode
204\param aabbset Set of boxes. Sorting isn't required.
205\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
206\pre aabbset must be allocated and initialized.
207\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.
208*/
209void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
210
211//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
212/*!
213\pre aabbset1 and aabbset2 must be allocated and updated. See gim_aabbset_update.
214\param aabbset1 Must be updated.
215\param aabbset2 Must be updated.
216\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
217*/
218void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
219
220///Function for create Box collision result set
221
222#define GIM_CREATE_BOXQUERY_LIST(dynarray) GIM_DYNARRAY_CREATE(GUINT,dynarray,G_ARRAY_GROW_SIZE)
223
224//! Finds intersections between a box and a set. Return the colliding boxes of the set
225/*!
226\pre aabbset must be allocated and initialized.
227\param test_aabb Box for collision query
228\param aabbset Set of boxes .Global bound is required.
229\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
230*/
231void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
232
233//! Finds intersections between a box and a set. Return the colliding boxes of the set
234/*!
235\pre aabbset must be allocated and initialized.
236\param vorigin Origin point of ray.
237\param vdir Direction vector of ray.
238\param tmax Max distance param for ray.
239\param aabbset Set of boxes .Global bound is required.
240\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
241*/
242void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
243
244
245/*
246For sorting, each box corner must be discretized to a 32 bit integer.
247For this, we take the x and z coordinates from the box corner (a vector vec3f)
248Then convert the (x,z) pair to an integer. For convenience, we choose an error
249constant for converting the coordinates (0.05).
250*******************************************************************************/
251
252/**
253 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.
254 20 give us a 0.05 floating point error
255*/
256#define ERROR_AABB 20.0f
257
258/**
259An error of 0.05 allows to make coordinates up to 1638.0f and no less of -1638.0f.
260So the maximum size of a room should be about 3276x3276 . Its dimensions must lie between [-1638,1638.0f]
261*/
262#define MAX_AABB_SIZE 1638.0f
263
264//! Converts a vector coordinate to an integer for box sorting
265/*!
266\param vx X component
267\param vz Z component
268\param uint_key a GUINT
269*/
270#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key)\
271{\
272 GUINT _z = ((GUINT)(vz*ERROR_AABB))+32768;\
273 uint_key = ((GUINT)(vx*ERROR_AABB))+32768;\
274 uint_key = (uint_key<<16) + _z;\
275}\
276
277//! Converts a vector coordinate to an integer for box sorting,rounding to the upper int
278/*!
279\param vx X component
280\param vz Z component
281\param uint_key a GUINT
282*/
283#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key)\
284{\
285 GUINT _z = ((GUINT)ceilf(vz*ERROR_AABB))+32768;\
286 uint_key = ((GUINT)ceilf(vx*ERROR_AABB))+32768;\
287 uint_key = (uint_key<<16) + _z;\
288}\
289
290
291//! Converts a vector coordinate to an integer for box sorting. Secure clamped
292/*!
293\param vx X component
294\param vz Z component
295\param uint_key a GUINT
296*/
297#define GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key)\
298{\
299 GREAL _cx = CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
300 GREAL _cz = CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
301 GUINT _z = ((GUINT)(_cz*ERROR_AABB))+32768;\
302 uint_key = ((GUINT)(_cx*ERROR_AABB))+32768;\
303 uint_key = (uint_key<<16) + _z;\
304}\
305
306//! Converts a vector coordinate to an integer for box sorting. Secure clamped, rounded
307/*!
308\param vx X component
309\param vz Z component
310\param uint_key a GUINT
311*/
312#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key)\
313{\
314 GREAL _cx = CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
315 GREAL _cz = CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
316 GUINT _z = ((GUINT)ceilf(_cz*ERROR_AABB))+32768;\
317 uint_key = ((GUINT)ceilf(_cx*ERROR_AABB))+32768;\
318 uint_key = (uint_key<<16) + _z;\
319}\
320
321//! @}
322
323#endif // GIM_BOXPRUNING_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h
new file mode 100644
index 0000000..bad8f0f
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h
@@ -0,0 +1,115 @@
1#ifndef GIM_CONTACT_H_INCLUDED
2#define GIM_CONTACT_H_INCLUDED
3
4/*! \file gim_contact.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include "GIMPACT/gim_geometry.h"
36#include "GIMPACT/gim_radixsort.h"
37
38/*! \defgroup CONTACTS
39\brief
40Functions for managing and sorting contacts resulting from a collision query.
41<ul>
42<li> Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
43<li> After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
44<li> Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
45</ul>
46
47*/
48//! @{
49/// Structure for collision results
50struct GIM_CONTACT
51{
52 vec3f m_point;
53 vec3f m_normal;
54 GREAL m_depth;//Positive value indicates interpenetration
55 void * m_handle1;
56 void * m_handle2;
57 GUINT m_feature1;//Face number
58 GUINT m_feature2;//Face number
59};
60//typedef struct _GIM_CONTACT GIM_CONTACT;
61
62#define CONTACT_DIFF_EPSILON 0.00001f
63
64#define GIM_CALC_KEY_CONTACT(pos,hash)\
65{\
66 GINT _coords[] = {(GINT)(pos[0]*1000.0f+1.0f),(GINT)(pos[1]*1333.0f),(GINT)(pos[2]*2133.0f+3.0f)};\
67 GUINT _hash=0;\
68 GUINT *_uitmp = (GUINT *)(&_coords[0]);\
69 _hash = *_uitmp;\
70 _uitmp++;\
71 _hash += (*_uitmp)<<4;\
72 _uitmp++;\
73 _hash += (*_uitmp)<<8;\
74 hash = _hash;\
75}\
76
77///Creates a contact list for queries
78#define GIM_CREATE_CONTACT_LIST(contact_array) GIM_DYNARRAY_CREATE(GIM_CONTACT,contact_array,100)
79
80#define GIM_PUSH_CONTACT(contact_array, point, normal, deep,handle1, handle2, feat1, feat2)\
81{\
82 GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,contact_array);\
83 GIM_CONTACT * _last = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,contact_array);\
84 VEC_COPY(_last->m_point,point);\
85 VEC_COPY(_last->m_normal,normal);\
86 _last->m_depth = deep;\
87 _last->m_handle1 = handle1;\
88 _last->m_handle2 = handle2;\
89 _last->m_feature1 = feat1;\
90 _last->m_feature2 = feat2;\
91}\
92
93///Receive pointer to contacts
94#define GIM_COPY_CONTACTS(dest_contact, source_contact)\
95{\
96 VEC_COPY(dest_contact->m_point,source_contact->m_point);\
97 VEC_COPY(dest_contact->m_normal,source_contact->m_normal);\
98 dest_contact->m_depth = source_contact->m_depth;\
99 dest_contact->m_handle1 = source_contact->m_handle1;\
100 dest_contact->m_handle2 = source_contact->m_handle2;\
101 dest_contact->m_feature1 = source_contact->m_feature1;\
102 dest_contact->m_feature2 = source_contact->m_feature2;\
103}\
104
105//! Merges duplicate contacts with minimum depth criterion
106void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
107 GDYNAMIC_ARRAY * dest_contacts);
108
109
110//! Merges to an unique contact
111void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
112 GDYNAMIC_ARRAY * dest_contacts);
113
114//! @}
115#endif // GIM_CONTACT_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h
new file mode 100644
index 0000000..6d89a94
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h
@@ -0,0 +1,1872 @@
1#ifndef GIM_VECTOR_H_INCLUDED
2#define GIM_VECTOR_H_INCLUDED
3
4/*! \file gim_geometry.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include "GIMPACT/gim_math.h"
36
37/*! \defgroup GEOMETRIC_TYPES
38\brief
39Basic types and constants for geometry
40*/
41//! @{
42
43//! Integer vector 2D
44typedef GINT vec2i[2];
45//! Integer vector 3D
46typedef GINT vec3i[3];
47//! Integer vector 4D
48typedef GINT vec4i[4];
49
50//! Float vector 2D
51typedef GREAL vec2f[2];
52//! Float vector 3D
53typedef GREAL vec3f[3];
54//! Float vector 4D
55typedef GREAL vec4f[4];
56
57//! Matrix 2D, row ordered
58typedef GREAL mat2f[2][2];
59//! Matrix 3D, row ordered
60typedef GREAL mat3f[3][3];
61//! Matrix 4D, row ordered
62typedef GREAL mat4f[4][4];
63
64//! Quaternion
65typedef GREAL quatf[4];
66
67//! Axis aligned box
68struct aabb3f{
69 GREAL minX;
70 GREAL maxX;
71 GREAL minY;
72 GREAL maxY;
73 GREAL minZ;
74 GREAL maxZ;
75};
76//typedef struct _aabb3f aabb3f;
77//! @}
78
79
80/*! \defgroup VECTOR_OPERATIONS
81Operations for vectors : vec2f,vec3f and vec4f
82*/
83//! @{
84
85//! Zero out a 2D vector
86#define VEC_ZERO_2(a) \
87{ \
88 (a)[0] = (a)[1] = 0.0f; \
89}\
90
91
92//! Zero out a 3D vector
93#define VEC_ZERO(a) \
94{ \
95 (a)[0] = (a)[1] = (a)[2] = 0.0f; \
96}\
97
98
99/// Zero out a 4D vector
100#define VEC_ZERO_4(a) \
101{ \
102 (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \
103}\
104
105
106/// Vector copy
107#define VEC_COPY_2(b,a) \
108{ \
109 (b)[0] = (a)[0]; \
110 (b)[1] = (a)[1]; \
111}\
112
113
114/// Copy 3D vector
115#define VEC_COPY(b,a) \
116{ \
117 (b)[0] = (a)[0]; \
118 (b)[1] = (a)[1]; \
119 (b)[2] = (a)[2]; \
120}\
121
122
123/// Copy 4D vector
124#define VEC_COPY_4(b,a) \
125{ \
126 (b)[0] = (a)[0]; \
127 (b)[1] = (a)[1]; \
128 (b)[2] = (a)[2]; \
129 (b)[3] = (a)[3]; \
130}\
131
132
133/// Vector difference
134#define VEC_DIFF_2(v21,v2,v1) \
135{ \
136 (v21)[0] = (v2)[0] - (v1)[0]; \
137 (v21)[1] = (v2)[1] - (v1)[1]; \
138}\
139
140
141/// Vector difference
142#define VEC_DIFF(v21,v2,v1) \
143{ \
144 (v21)[0] = (v2)[0] - (v1)[0]; \
145 (v21)[1] = (v2)[1] - (v1)[1]; \
146 (v21)[2] = (v2)[2] - (v1)[2]; \
147}\
148
149
150/// Vector difference
151#define VEC_DIFF_4(v21,v2,v1) \
152{ \
153 (v21)[0] = (v2)[0] - (v1)[0]; \
154 (v21)[1] = (v2)[1] - (v1)[1]; \
155 (v21)[2] = (v2)[2] - (v1)[2]; \
156 (v21)[3] = (v2)[3] - (v1)[3]; \
157}\
158
159
160/// Vector sum
161#define VEC_SUM_2(v21,v2,v1) \
162{ \
163 (v21)[0] = (v2)[0] + (v1)[0]; \
164 (v21)[1] = (v2)[1] + (v1)[1]; \
165}\
166
167
168/// Vector sum
169#define VEC_SUM(v21,v2,v1) \
170{ \
171 (v21)[0] = (v2)[0] + (v1)[0]; \
172 (v21)[1] = (v2)[1] + (v1)[1]; \
173 (v21)[2] = (v2)[2] + (v1)[2]; \
174}\
175
176
177/// Vector sum
178#define VEC_SUM_4(v21,v2,v1) \
179{ \
180 (v21)[0] = (v2)[0] + (v1)[0]; \
181 (v21)[1] = (v2)[1] + (v1)[1]; \
182 (v21)[2] = (v2)[2] + (v1)[2]; \
183 (v21)[3] = (v2)[3] + (v1)[3]; \
184}\
185
186
187/// scalar times vector
188#define VEC_SCALE_2(c,a,b) \
189{ \
190 (c)[0] = (a)*(b)[0]; \
191 (c)[1] = (a)*(b)[1]; \
192}\
193
194
195/// scalar times vector
196#define VEC_SCALE(c,a,b) \
197{ \
198 (c)[0] = (a)*(b)[0]; \
199 (c)[1] = (a)*(b)[1]; \
200 (c)[2] = (a)*(b)[2]; \
201}\
202
203
204/// scalar times vector
205#define VEC_SCALE_4(c,a,b) \
206{ \
207 (c)[0] = (a)*(b)[0]; \
208 (c)[1] = (a)*(b)[1]; \
209 (c)[2] = (a)*(b)[2]; \
210 (c)[3] = (a)*(b)[3]; \
211}\
212
213
214/// accumulate scaled vector
215#define VEC_ACCUM_2(c,a,b) \
216{ \
217 (c)[0] += (a)*(b)[0]; \
218 (c)[1] += (a)*(b)[1]; \
219}\
220
221
222/// accumulate scaled vector
223#define VEC_ACCUM(c,a,b) \
224{ \
225 (c)[0] += (a)*(b)[0]; \
226 (c)[1] += (a)*(b)[1]; \
227 (c)[2] += (a)*(b)[2]; \
228}\
229
230
231/// accumulate scaled vector
232#define VEC_ACCUM_4(c,a,b) \
233{ \
234 (c)[0] += (a)*(b)[0]; \
235 (c)[1] += (a)*(b)[1]; \
236 (c)[2] += (a)*(b)[2]; \
237 (c)[3] += (a)*(b)[3]; \
238}\
239
240
241/// Vector dot product
242#define VEC_DOT_2(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1])
243
244
245/// Vector dot product
246#define VEC_DOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2])
247
248/// Vector dot product
249#define VEC_DOT_4(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3])
250
251/// vector impact parameter (squared)
252#define VEC_IMPACT_SQ(bsq,direction,position) {\
253 GREAL _llel_ = VEC_DOT(direction, position);\
254 bsq = VEC_DOT(position, position) - _llel_*_llel_;\
255}\
256
257
258/// vector impact parameter
259#define VEC_IMPACT(bsq,direction,position) {\
260 VEC_IMPACT_SQ(bsq,direction,position); \
261 GIM_SQRT(bsq,bsq); \
262}\
263
264/// Vector length
265#define VEC_LENGTH_2(a,l)\
266{\
267 GREAL _pp = VEC_DOT_2(a,a);\
268 GIM_SQRT(_pp,l);\
269}\
270
271
272/// Vector length
273#define VEC_LENGTH(a,l)\
274{\
275 GREAL _pp = VEC_DOT(a,a);\
276 GIM_SQRT(_pp,l);\
277}\
278
279
280/// Vector length
281#define VEC_LENGTH_4(a,l)\
282{\
283 GREAL _pp = VEC_DOT_4(a,a);\
284 GIM_SQRT(_pp,l);\
285}\
286
287/// Vector inv length
288#define VEC_INV_LENGTH_2(a,l)\
289{\
290 GREAL _pp = VEC_DOT_2(a,a);\
291 GIM_INV_SQRT(_pp,l);\
292}\
293
294
295/// Vector inv length
296#define VEC_INV_LENGTH(a,l)\
297{\
298 GREAL _pp = VEC_DOT(a,a);\
299 GIM_INV_SQRT(_pp,l);\
300}\
301
302
303/// Vector inv length
304#define VEC_INV_LENGTH_4(a,l)\
305{\
306 GREAL _pp = VEC_DOT_4(a,a);\
307 GIM_INV_SQRT(_pp,l);\
308}\
309
310
311
312/// distance between two points
313#define VEC_DISTANCE(_len,_va,_vb) {\
314 vec3f _tmp_; \
315 VEC_DIFF(_tmp_, _vb, _va); \
316 VEC_LENGTH(_tmp_,_len); \
317}\
318
319
320/// Vector length
321#define VEC_CONJUGATE_LENGTH(a,l)\
322{\
323 GREAL _pp = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\
324 GIM_SQRT(_pp,l);\
325}\
326
327
328/// Vector length
329#define VEC_NORMALIZE(a) { \
330 GREAL len;\
331 VEC_INV_LENGTH(a,len); \
332 if(len<G_REAL_INFINITY)\
333 {\
334 a[0] *= len; \
335 a[1] *= len; \
336 a[2] *= len; \
337 } \
338}\
339
340/// Set Vector size
341#define VEC_RENORMALIZE(a,newlen) { \
342 GREAL len;\
343 VEC_INV_LENGTH(a,len); \
344 if(len<G_REAL_INFINITY)\
345 {\
346 len *= newlen;\
347 a[0] *= len; \
348 a[1] *= len; \
349 a[2] *= len; \
350 } \
351}\
352
353/// Vector cross
354#define VEC_CROSS(c,a,b) \
355{ \
356 c[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \
357 c[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \
358 c[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \
359}\
360
361
362/*! Vector perp -- assumes that n is of unit length
363 * accepts vector v, subtracts out any component parallel to n */
364#define VEC_PERPENDICULAR(vp,v,n) \
365{ \
366 GREAL dot = VEC_DOT(v, n); \
367 vp[0] = (v)[0] - dot*(n)[0]; \
368 vp[1] = (v)[1] - dot*(n)[1]; \
369 vp[2] = (v)[2] - dot*(n)[2]; \
370}\
371
372
373/*! Vector parallel -- assumes that n is of unit length */
374#define VEC_PARALLEL(vp,v,n) \
375{ \
376 GREAL dot = VEC_DOT(v, n); \
377 vp[0] = (dot) * (n)[0]; \
378 vp[1] = (dot) * (n)[1]; \
379 vp[2] = (dot) * (n)[2]; \
380}\
381
382/*! Same as Vector parallel -- n can have any length
383 * accepts vector v, subtracts out any component perpendicular to n */
384#define VEC_PROJECT(vp,v,n) \
385{ \
386 GREAL scalar = VEC_DOT(v, n); \
387 scalar/= VEC_DOT(n, n); \
388 vp[0] = (scalar) * (n)[0]; \
389 vp[1] = (scalar) * (n)[1]; \
390 vp[2] = (scalar) * (n)[2]; \
391}\
392
393
394/*! accepts vector v*/
395#define VEC_UNPROJECT(vp,v,n) \
396{ \
397 GREAL scalar = VEC_DOT(v, n); \
398 scalar = VEC_DOT(n, n)/scalar; \
399 vp[0] = (scalar) * (n)[0]; \
400 vp[1] = (scalar) * (n)[1]; \
401 vp[2] = (scalar) * (n)[2]; \
402}\
403
404
405/*! Vector reflection -- assumes n is of unit length
406 Takes vector v, reflects it against reflector n, and returns vr */
407#define VEC_REFLECT(vr,v,n) \
408{ \
409 GREAL dot = VEC_DOT(v, n); \
410 vr[0] = (v)[0] - 2.0 * (dot) * (n)[0]; \
411 vr[1] = (v)[1] - 2.0 * (dot) * (n)[1]; \
412 vr[2] = (v)[2] - 2.0 * (dot) * (n)[2]; \
413}\
414
415
416/*! Vector blending
417Takes two vectors a, b, blends them together with two scalars */
418#define VEC_BLEND_AB(vr,sa,a,sb,b) \
419{ \
420 vr[0] = (sa) * (a)[0] + (sb) * (b)[0]; \
421 vr[1] = (sa) * (a)[1] + (sb) * (b)[1]; \
422 vr[2] = (sa) * (a)[2] + (sb) * (b)[2]; \
423}\
424
425/*! Vector blending
426Takes two vectors a, b, blends them together with s <=1 */
427#define VEC_BLEND(vr,a,b,s) VEC_BLEND_AB(vr,1-s,a,sb,s)
428
429#define VEC_SET3(a,b,op,c) a[0]=b[0] op c[0]; a[1]=b[1] op c[1]; a[2]=b[2] op c[2];
430//! @}
431
432
433/*! \defgroup MATRIX_OPERATIONS
434Operations for matrices : mat2f, mat3f and mat4f
435*/
436//! @{
437
438/// initialize matrix
439#define IDENTIFY_MATRIX_3X3(m) \
440{ \
441 m[0][0] = 1.0; \
442 m[0][1] = 0.0; \
443 m[0][2] = 0.0; \
444 \
445 m[1][0] = 0.0; \
446 m[1][1] = 1.0; \
447 m[1][2] = 0.0; \
448 \
449 m[2][0] = 0.0; \
450 m[2][1] = 0.0; \
451 m[2][2] = 1.0; \
452}\
453
454/*! initialize matrix */
455#define IDENTIFY_MATRIX_4X4(m) \
456{ \
457 m[0][0] = 1.0; \
458 m[0][1] = 0.0; \
459 m[0][2] = 0.0; \
460 m[0][3] = 0.0; \
461 \
462 m[1][0] = 0.0; \
463 m[1][1] = 1.0; \
464 m[1][2] = 0.0; \
465 m[1][3] = 0.0; \
466 \
467 m[2][0] = 0.0; \
468 m[2][1] = 0.0; \
469 m[2][2] = 1.0; \
470 m[2][3] = 0.0; \
471 \
472 m[3][0] = 0.0; \
473 m[3][1] = 0.0; \
474 m[3][2] = 0.0; \
475 m[3][3] = 1.0; \
476}\
477
478/*! initialize matrix */
479#define ZERO_MATRIX_4X4(m) \
480{ \
481 m[0][0] = 0.0; \
482 m[0][1] = 0.0; \
483 m[0][2] = 0.0; \
484 m[0][3] = 0.0; \
485 \
486 m[1][0] = 0.0; \
487 m[1][1] = 0.0; \
488 m[1][2] = 0.0; \
489 m[1][3] = 0.0; \
490 \
491 m[2][0] = 0.0; \
492 m[2][1] = 0.0; \
493 m[2][2] = 0.0; \
494 m[2][3] = 0.0; \
495 \
496 m[3][0] = 0.0; \
497 m[3][1] = 0.0; \
498 m[3][2] = 0.0; \
499 m[3][3] = 0.0; \
500}\
501
502/*! matrix rotation X */
503#define ROTX_CS(m,cosine,sine) \
504{ \
505 /* rotation about the x-axis */ \
506 \
507 m[0][0] = 1.0; \
508 m[0][1] = 0.0; \
509 m[0][2] = 0.0; \
510 m[0][3] = 0.0; \
511 \
512 m[1][0] = 0.0; \
513 m[1][1] = (cosine); \
514 m[1][2] = (sine); \
515 m[1][3] = 0.0; \
516 \
517 m[2][0] = 0.0; \
518 m[2][1] = -(sine); \
519 m[2][2] = (cosine); \
520 m[2][3] = 0.0; \
521 \
522 m[3][0] = 0.0; \
523 m[3][1] = 0.0; \
524 m[3][2] = 0.0; \
525 m[3][3] = 1.0; \
526}\
527
528/*! matrix rotation Y */
529#define ROTY_CS(m,cosine,sine) \
530{ \
531 /* rotation about the y-axis */ \
532 \
533 m[0][0] = (cosine); \
534 m[0][1] = 0.0; \
535 m[0][2] = -(sine); \
536 m[0][3] = 0.0; \
537 \
538 m[1][0] = 0.0; \
539 m[1][1] = 1.0; \
540 m[1][2] = 0.0; \
541 m[1][3] = 0.0; \
542 \
543 m[2][0] = (sine); \
544 m[2][1] = 0.0; \
545 m[2][2] = (cosine); \
546 m[2][3] = 0.0; \
547 \
548 m[3][0] = 0.0; \
549 m[3][1] = 0.0; \
550 m[3][2] = 0.0; \
551 m[3][3] = 1.0; \
552}\
553
554/*! matrix rotation Z */
555#define ROTZ_CS(m,cosine,sine) \
556{ \
557 /* rotation about the z-axis */ \
558 \
559 m[0][0] = (cosine); \
560 m[0][1] = (sine); \
561 m[0][2] = 0.0; \
562 m[0][3] = 0.0; \
563 \
564 m[1][0] = -(sine); \
565 m[1][1] = (cosine); \
566 m[1][2] = 0.0; \
567 m[1][3] = 0.0; \
568 \
569 m[2][0] = 0.0; \
570 m[2][1] = 0.0; \
571 m[2][2] = 1.0; \
572 m[2][3] = 0.0; \
573 \
574 m[3][0] = 0.0; \
575 m[3][1] = 0.0; \
576 m[3][2] = 0.0; \
577 m[3][3] = 1.0; \
578}\
579
580/*! matrix copy */
581#define COPY_MATRIX_2X2(b,a) \
582{ \
583 b[0][0] = a[0][0]; \
584 b[0][1] = a[0][1]; \
585 \
586 b[1][0] = a[1][0]; \
587 b[1][1] = a[1][1]; \
588 \
589}\
590
591
592/*! matrix copy */
593#define COPY_MATRIX_2X3(b,a) \
594{ \
595 b[0][0] = a[0][0]; \
596 b[0][1] = a[0][1]; \
597 b[0][2] = a[0][2]; \
598 \
599 b[1][0] = a[1][0]; \
600 b[1][1] = a[1][1]; \
601 b[1][2] = a[1][2]; \
602}\
603
604
605/*! matrix copy */
606#define COPY_MATRIX_3X3(b,a) \
607{ \
608 b[0][0] = a[0][0]; \
609 b[0][1] = a[0][1]; \
610 b[0][2] = a[0][2]; \
611 \
612 b[1][0] = a[1][0]; \
613 b[1][1] = a[1][1]; \
614 b[1][2] = a[1][2]; \
615 \
616 b[2][0] = a[2][0]; \
617 b[2][1] = a[2][1]; \
618 b[2][2] = a[2][2]; \
619}\
620
621
622/*! matrix copy */
623#define COPY_MATRIX_4X4(b,a) \
624{ \
625 b[0][0] = a[0][0]; \
626 b[0][1] = a[0][1]; \
627 b[0][2] = a[0][2]; \
628 b[0][3] = a[0][3]; \
629 \
630 b[1][0] = a[1][0]; \
631 b[1][1] = a[1][1]; \
632 b[1][2] = a[1][2]; \
633 b[1][3] = a[1][3]; \
634 \
635 b[2][0] = a[2][0]; \
636 b[2][1] = a[2][1]; \
637 b[2][2] = a[2][2]; \
638 b[2][3] = a[2][3]; \
639 \
640 b[3][0] = a[3][0]; \
641 b[3][1] = a[3][1]; \
642 b[3][2] = a[3][2]; \
643 b[3][3] = a[3][3]; \
644}\
645
646
647/*! matrix transpose */
648#define TRANSPOSE_MATRIX_2X2(b,a) \
649{ \
650 b[0][0] = a[0][0]; \
651 b[0][1] = a[1][0]; \
652 \
653 b[1][0] = a[0][1]; \
654 b[1][1] = a[1][1]; \
655}\
656
657
658/*! matrix transpose */
659#define TRANSPOSE_MATRIX_3X3(b,a) \
660{ \
661 b[0][0] = a[0][0]; \
662 b[0][1] = a[1][0]; \
663 b[0][2] = a[2][0]; \
664 \
665 b[1][0] = a[0][1]; \
666 b[1][1] = a[1][1]; \
667 b[1][2] = a[2][1]; \
668 \
669 b[2][0] = a[0][2]; \
670 b[2][1] = a[1][2]; \
671 b[2][2] = a[2][2]; \
672}\
673
674
675/*! matrix transpose */
676#define TRANSPOSE_MATRIX_4X4(b,a) \
677{ \
678 b[0][0] = a[0][0]; \
679 b[0][1] = a[1][0]; \
680 b[0][2] = a[2][0]; \
681 b[0][3] = a[3][0]; \
682 \
683 b[1][0] = a[0][1]; \
684 b[1][1] = a[1][1]; \
685 b[1][2] = a[2][1]; \
686 b[1][3] = a[3][1]; \
687 \
688 b[2][0] = a[0][2]; \
689 b[2][1] = a[1][2]; \
690 b[2][2] = a[2][2]; \
691 b[2][3] = a[3][2]; \
692 \
693 b[3][0] = a[0][3]; \
694 b[3][1] = a[1][3]; \
695 b[3][2] = a[2][3]; \
696 b[3][3] = a[3][3]; \
697}\
698
699
700/*! multiply matrix by scalar */
701#define SCALE_MATRIX_2X2(b,s,a) \
702{ \
703 b[0][0] = (s) * a[0][0]; \
704 b[0][1] = (s) * a[0][1]; \
705 \
706 b[1][0] = (s) * a[1][0]; \
707 b[1][1] = (s) * a[1][1]; \
708}\
709
710
711/*! multiply matrix by scalar */
712#define SCALE_MATRIX_3X3(b,s,a) \
713{ \
714 b[0][0] = (s) * a[0][0]; \
715 b[0][1] = (s) * a[0][1]; \
716 b[0][2] = (s) * a[0][2]; \
717 \
718 b[1][0] = (s) * a[1][0]; \
719 b[1][1] = (s) * a[1][1]; \
720 b[1][2] = (s) * a[1][2]; \
721 \
722 b[2][0] = (s) * a[2][0]; \
723 b[2][1] = (s) * a[2][1]; \
724 b[2][2] = (s) * a[2][2]; \
725}\
726
727
728/*! multiply matrix by scalar */
729#define SCALE_MATRIX_4X4(b,s,a) \
730{ \
731 b[0][0] = (s) * a[0][0]; \
732 b[0][1] = (s) * a[0][1]; \
733 b[0][2] = (s) * a[0][2]; \
734 b[0][3] = (s) * a[0][3]; \
735 \
736 b[1][0] = (s) * a[1][0]; \
737 b[1][1] = (s) * a[1][1]; \
738 b[1][2] = (s) * a[1][2]; \
739 b[1][3] = (s) * a[1][3]; \
740 \
741 b[2][0] = (s) * a[2][0]; \
742 b[2][1] = (s) * a[2][1]; \
743 b[2][2] = (s) * a[2][2]; \
744 b[2][3] = (s) * a[2][3]; \
745 \
746 b[3][0] = s * a[3][0]; \
747 b[3][1] = s * a[3][1]; \
748 b[3][2] = s * a[3][2]; \
749 b[3][3] = s * a[3][3]; \
750}\
751
752
753/*! multiply matrix by scalar */
754#define ACCUM_SCALE_MATRIX_2X2(b,s,a) \
755{ \
756 b[0][0] += (s) * a[0][0]; \
757 b[0][1] += (s) * a[0][1]; \
758 \
759 b[1][0] += (s) * a[1][0]; \
760 b[1][1] += (s) * a[1][1]; \
761}\
762
763
764/*! multiply matrix by scalar */
765#define ACCUM_SCALE_MATRIX_3X3(b,s,a) \
766{ \
767 b[0][0] += (s) * a[0][0]; \
768 b[0][1] += (s) * a[0][1]; \
769 b[0][2] += (s) * a[0][2]; \
770 \
771 b[1][0] += (s) * a[1][0]; \
772 b[1][1] += (s) * a[1][1]; \
773 b[1][2] += (s) * a[1][2]; \
774 \
775 b[2][0] += (s) * a[2][0]; \
776 b[2][1] += (s) * a[2][1]; \
777 b[2][2] += (s) * a[2][2]; \
778}\
779
780
781/*! multiply matrix by scalar */
782#define ACCUM_SCALE_MATRIX_4X4(b,s,a) \
783{ \
784 b[0][0] += (s) * a[0][0]; \
785 b[0][1] += (s) * a[0][1]; \
786 b[0][2] += (s) * a[0][2]; \
787 b[0][3] += (s) * a[0][3]; \
788 \
789 b[1][0] += (s) * a[1][0]; \
790 b[1][1] += (s) * a[1][1]; \
791 b[1][2] += (s) * a[1][2]; \
792 b[1][3] += (s) * a[1][3]; \
793 \
794 b[2][0] += (s) * a[2][0]; \
795 b[2][1] += (s) * a[2][1]; \
796 b[2][2] += (s) * a[2][2]; \
797 b[2][3] += (s) * a[2][3]; \
798 \
799 b[3][0] += (s) * a[3][0]; \
800 b[3][1] += (s) * a[3][1]; \
801 b[3][2] += (s) * a[3][2]; \
802 b[3][3] += (s) * a[3][3]; \
803}\
804
805/*! matrix product */
806/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
807#define MATRIX_PRODUCT_2X2(c,a,b) \
808{ \
809 c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \
810 c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \
811 \
812 c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \
813 c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \
814 \
815}\
816
817/*! matrix product */
818/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
819#define MATRIX_PRODUCT_3X3(c,a,b) \
820{ \
821 c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \
822 c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \
823 c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \
824 \
825 c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \
826 c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \
827 c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \
828 \
829 c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \
830 c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \
831 c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \
832}\
833
834
835/*! matrix product */
836/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
837#define MATRIX_PRODUCT_4X4(c,a,b) \
838{ \
839 c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]+a[0][3]*b[3][0];\
840 c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]+a[0][3]*b[3][1];\
841 c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]+a[0][3]*b[3][2];\
842 c[0][3] = a[0][0]*b[0][3]+a[0][1]*b[1][3]+a[0][2]*b[2][3]+a[0][3]*b[3][3];\
843 \
844 c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]+a[1][3]*b[3][0];\
845 c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1];\
846 c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2];\
847 c[1][3] = a[1][0]*b[0][3]+a[1][1]*b[1][3]+a[1][2]*b[2][3]+a[1][3]*b[3][3];\
848 \
849 c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]+a[2][3]*b[3][0];\
850 c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]+a[2][3]*b[3][1];\
851 c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]+a[2][3]*b[3][2];\
852 c[2][3] = a[2][0]*b[0][3]+a[2][1]*b[1][3]+a[2][2]*b[2][3]+a[2][3]*b[3][3];\
853 \
854 c[3][0] = a[3][0]*b[0][0]+a[3][1]*b[1][0]+a[3][2]*b[2][0]+a[3][3]*b[3][0];\
855 c[3][1] = a[3][0]*b[0][1]+a[3][1]*b[1][1]+a[3][2]*b[2][1]+a[3][3]*b[3][1];\
856 c[3][2] = a[3][0]*b[0][2]+a[3][1]*b[1][2]+a[3][2]*b[2][2]+a[3][3]*b[3][2];\
857 c[3][3] = a[3][0]*b[0][3]+a[3][1]*b[1][3]+a[3][2]*b[2][3]+a[3][3]*b[3][3];\
858}\
859
860
861/*! matrix times vector */
862#define MAT_DOT_VEC_2X2(p,m,v) \
863{ \
864 p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \
865 p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \
866}\
867
868
869/*! matrix times vector */
870#define MAT_DOT_VEC_3X3(p,m,v) \
871{ \
872 p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \
873 p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \
874 p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \
875}\
876
877
878/*! matrix times vector
879v is a vec4f
880*/
881#define MAT_DOT_VEC_4X4(p,m,v) \
882{ \
883 p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \
884 p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \
885 p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \
886 p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \
887}\
888
889/*! matrix times vector
890v is a vec3f
891and m is a mat4f<br>
892Last column is added as the position
893*/
894#define MAT_DOT_VEC_3X4(p,m,v) \
895{ \
896 p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]; \
897 p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]; \
898 p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]; \
899}\
900
901/*! vector transpose times matrix */
902/*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */
903#define VEC_DOT_MAT_3X3(p,v,m) \
904{ \
905 p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0]; \
906 p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1]; \
907 p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2]; \
908}\
909
910
911/*! affine matrix times vector */
912/** The matrix is assumed to be an affine matrix, with last two
913 * entries representing a translation */
914#define MAT_DOT_VEC_2X3(p,m,v) \
915{ \
916 p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]; \
917 p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]; \
918}\
919
920
921/** inverse transpose of matrix times vector
922 *
923 * This macro computes inverse transpose of matrix m,
924 * and multiplies vector v into it, to yeild vector p
925 *
926 * DANGER !!! Do Not use this on normal vectors!!!
927 * It will leave normals the wrong length !!!
928 * See macro below for use on normals.
929 */
930#define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \
931{ \
932 GREAL det; \
933 \
934 det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; \
935 p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \
936 p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \
937 \
938 /* if matrix not singular, and not orthonormal, then renormalize */ \
939 if ((det!=1.0f) && (det != 0.0f)) { \
940 det = 1.0f / det; \
941 p[0] *= det; \
942 p[1] *= det; \
943 } \
944}\
945
946
947/** transform normal vector by inverse transpose of matrix
948 * and then renormalize the vector
949 *
950 * This macro computes inverse transpose of matrix m,
951 * and multiplies vector v into it, to yeild vector p
952 * Vector p is then normalized.
953 */
954#define NORM_XFORM_2X2(p,m,v) \
955{ \
956 double len; \
957 \
958 /* do nothing if off-diagonals are zero and diagonals are \
959 * equal */ \
960 if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \
961 p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \
962 p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \
963 \
964 len = p[0]*p[0] + p[1]*p[1]; \
965 GIM_INV_SQRT(len,len); \
966 p[0] *= len; \
967 p[1] *= len; \
968 } else { \
969 VEC_COPY_2 (p, v); \
970 } \
971}\
972
973
974/** outer product of vector times vector transpose
975 *
976 * The outer product of vector v and vector transpose t yeilds
977 * dyadic matrix m.
978 */
979#define OUTER_PRODUCT_2X2(m,v,t) \
980{ \
981 m[0][0] = v[0] * t[0]; \
982 m[0][1] = v[0] * t[1]; \
983 \
984 m[1][0] = v[1] * t[0]; \
985 m[1][1] = v[1] * t[1]; \
986}\
987
988
989/** outer product of vector times vector transpose
990 *
991 * The outer product of vector v and vector transpose t yeilds
992 * dyadic matrix m.
993 */
994#define OUTER_PRODUCT_3X3(m,v,t) \
995{ \
996 m[0][0] = v[0] * t[0]; \
997 m[0][1] = v[0] * t[1]; \
998 m[0][2] = v[0] * t[2]; \
999 \
1000 m[1][0] = v[1] * t[0]; \
1001 m[1][1] = v[1] * t[1]; \
1002 m[1][2] = v[1] * t[2]; \
1003 \
1004 m[2][0] = v[2] * t[0]; \
1005 m[2][1] = v[2] * t[1]; \
1006 m[2][2] = v[2] * t[2]; \
1007}\
1008
1009
1010/** outer product of vector times vector transpose
1011 *
1012 * The outer product of vector v and vector transpose t yeilds
1013 * dyadic matrix m.
1014 */
1015#define OUTER_PRODUCT_4X4(m,v,t) \
1016{ \
1017 m[0][0] = v[0] * t[0]; \
1018 m[0][1] = v[0] * t[1]; \
1019 m[0][2] = v[0] * t[2]; \
1020 m[0][3] = v[0] * t[3]; \
1021 \
1022 m[1][0] = v[1] * t[0]; \
1023 m[1][1] = v[1] * t[1]; \
1024 m[1][2] = v[1] * t[2]; \
1025 m[1][3] = v[1] * t[3]; \
1026 \
1027 m[2][0] = v[2] * t[0]; \
1028 m[2][1] = v[2] * t[1]; \
1029 m[2][2] = v[2] * t[2]; \
1030 m[2][3] = v[2] * t[3]; \
1031 \
1032 m[3][0] = v[3] * t[0]; \
1033 m[3][1] = v[3] * t[1]; \
1034 m[3][2] = v[3] * t[2]; \
1035 m[3][3] = v[3] * t[3]; \
1036}\
1037
1038
1039/** outer product of vector times vector transpose
1040 *
1041 * The outer product of vector v and vector transpose t yeilds
1042 * dyadic matrix m.
1043 */
1044#define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \
1045{ \
1046 m[0][0] += v[0] * t[0]; \
1047 m[0][1] += v[0] * t[1]; \
1048 \
1049 m[1][0] += v[1] * t[0]; \
1050 m[1][1] += v[1] * t[1]; \
1051}\
1052
1053
1054/** outer product of vector times vector transpose
1055 *
1056 * The outer product of vector v and vector transpose t yeilds
1057 * dyadic matrix m.
1058 */
1059#define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \
1060{ \
1061 m[0][0] += v[0] * t[0]; \
1062 m[0][1] += v[0] * t[1]; \
1063 m[0][2] += v[0] * t[2]; \
1064 \
1065 m[1][0] += v[1] * t[0]; \
1066 m[1][1] += v[1] * t[1]; \
1067 m[1][2] += v[1] * t[2]; \
1068 \
1069 m[2][0] += v[2] * t[0]; \
1070 m[2][1] += v[2] * t[1]; \
1071 m[2][2] += v[2] * t[2]; \
1072}\
1073
1074
1075/** outer product of vector times vector transpose
1076 *
1077 * The outer product of vector v and vector transpose t yeilds
1078 * dyadic matrix m.
1079 */
1080#define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \
1081{ \
1082 m[0][0] += v[0] * t[0]; \
1083 m[0][1] += v[0] * t[1]; \
1084 m[0][2] += v[0] * t[2]; \
1085 m[0][3] += v[0] * t[3]; \
1086 \
1087 m[1][0] += v[1] * t[0]; \
1088 m[1][1] += v[1] * t[1]; \
1089 m[1][2] += v[1] * t[2]; \
1090 m[1][3] += v[1] * t[3]; \
1091 \
1092 m[2][0] += v[2] * t[0]; \
1093 m[2][1] += v[2] * t[1]; \
1094 m[2][2] += v[2] * t[2]; \
1095 m[2][3] += v[2] * t[3]; \
1096 \
1097 m[3][0] += v[3] * t[0]; \
1098 m[3][1] += v[3] * t[1]; \
1099 m[3][2] += v[3] * t[2]; \
1100 m[3][3] += v[3] * t[3]; \
1101}\
1102
1103
1104/** determinant of matrix
1105 *
1106 * Computes determinant of matrix m, returning d
1107 */
1108#define DETERMINANT_2X2(d,m) \
1109{ \
1110 d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \
1111}\
1112
1113
1114/** determinant of matrix
1115 *
1116 * Computes determinant of matrix m, returning d
1117 */
1118#define DETERMINANT_3X3(d,m) \
1119{ \
1120 d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \
1121 d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \
1122 d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \
1123}\
1124
1125
1126/** i,j,th cofactor of a 4x4 matrix
1127 *
1128 */
1129#define COFACTOR_4X4_IJ(fac,m,i,j) \
1130{ \
1131 int __ii[4], __jj[4], __k; \
1132 \
1133 for (__k=0; __k<i; __k++) __ii[__k] = __k; \
1134 for (__k=i; __k<3; __k++) __ii[__k] = __k+1; \
1135 for (__k=0; __k<j; __k++) __jj[__k] = __k; \
1136 for (__k=j; __k<3; __k++) __jj[__k] = __k+1; \
1137 \
1138 (fac) = m[__ii[0]][__jj[0]] * (m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[2]] \
1139 - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[1]]); \
1140 (fac) -= m[__ii[0]][__jj[1]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[2]] \
1141 - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[0]]);\
1142 (fac) += m[__ii[0]][__jj[2]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[1]] \
1143 - m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[0]]);\
1144 \
1145 __k = i+j; \
1146 if ( __k != (__k/2)*2) { \
1147 (fac) = -(fac); \
1148 } \
1149}\
1150
1151
1152/** determinant of matrix
1153 *
1154 * Computes determinant of matrix m, returning d
1155 */
1156#define DETERMINANT_4X4(d,m) \
1157{ \
1158 double cofac; \
1159 COFACTOR_4X4_IJ (cofac, m, 0, 0); \
1160 d = m[0][0] * cofac; \
1161 COFACTOR_4X4_IJ (cofac, m, 0, 1); \
1162 d += m[0][1] * cofac; \
1163 COFACTOR_4X4_IJ (cofac, m, 0, 2); \
1164 d += m[0][2] * cofac; \
1165 COFACTOR_4X4_IJ (cofac, m, 0, 3); \
1166 d += m[0][3] * cofac; \
1167}\
1168
1169
1170/** cofactor of matrix
1171 *
1172 * Computes cofactor of matrix m, returning a
1173 */
1174#define COFACTOR_2X2(a,m) \
1175{ \
1176 a[0][0] = (m)[1][1]; \
1177 a[0][1] = - (m)[1][0]; \
1178 a[1][0] = - (m)[0][1]; \
1179 a[1][1] = (m)[0][0]; \
1180}\
1181
1182
1183/** cofactor of matrix
1184 *
1185 * Computes cofactor of matrix m, returning a
1186 */
1187#define COFACTOR_3X3(a,m) \
1188{ \
1189 a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; \
1190 a[0][1] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]); \
1191 a[0][2] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; \
1192 a[1][0] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]); \
1193 a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; \
1194 a[1][2] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]); \
1195 a[2][0] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; \
1196 a[2][1] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]); \
1197 a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
1198}\
1199
1200
1201/** cofactor of matrix
1202 *
1203 * Computes cofactor of matrix m, returning a
1204 */
1205#define COFACTOR_4X4(a,m) \
1206{ \
1207 int i,j; \
1208 \
1209 for (i=0; i<4; i++) { \
1210 for (j=0; j<4; j++) { \
1211 COFACTOR_4X4_IJ (a[i][j], m, i, j); \
1212 } \
1213 } \
1214}\
1215
1216
1217/** adjoint of matrix
1218 *
1219 * Computes adjoint of matrix m, returning a
1220 * (Note that adjoint is just the transpose of the cofactor matrix)
1221 */
1222#define ADJOINT_2X2(a,m) \
1223{ \
1224 a[0][0] = (m)[1][1]; \
1225 a[1][0] = - (m)[1][0]; \
1226 a[0][1] = - (m)[0][1]; \
1227 a[1][1] = (m)[0][0]; \
1228}\
1229
1230
1231/** adjoint of matrix
1232 *
1233 * Computes adjoint of matrix m, returning a
1234 * (Note that adjoint is just the transpose of the cofactor matrix)
1235 */
1236#define ADJOINT_3X3(a,m) \
1237{ \
1238 a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; \
1239 a[1][0] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]); \
1240 a[2][0] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; \
1241 a[0][1] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]); \
1242 a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; \
1243 a[2][1] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]); \
1244 a[0][2] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; \
1245 a[1][2] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]); \
1246 a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
1247}\
1248
1249
1250/** adjoint of matrix
1251 *
1252 * Computes adjoint of matrix m, returning a
1253 * (Note that adjoint is just the transpose of the cofactor matrix)
1254 */
1255#define ADJOINT_4X4(a,m) \
1256{ \
1257 char _i_,_j_; \
1258 \
1259 for (_i_=0; _i_<4; _i_++) { \
1260 for (_j_=0; _j_<4; _j_++) { \
1261 COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_); \
1262 } \
1263 } \
1264}\
1265
1266
1267/** compute adjoint of matrix and scale
1268 *
1269 * Computes adjoint of matrix m, scales it by s, returning a
1270 */
1271#define SCALE_ADJOINT_2X2(a,s,m) \
1272{ \
1273 a[0][0] = (s) * m[1][1]; \
1274 a[1][0] = - (s) * m[1][0]; \
1275 a[0][1] = - (s) * m[0][1]; \
1276 a[1][1] = (s) * m[0][0]; \
1277}\
1278
1279
1280/** compute adjoint of matrix and scale
1281 *
1282 * Computes adjoint of matrix m, scales it by s, returning a
1283 */
1284#define SCALE_ADJOINT_3X3(a,s,m) \
1285{ \
1286 a[0][0] = (s) * (m[1][1] * m[2][2] - m[1][2] * m[2][1]); \
1287 a[1][0] = (s) * (m[1][2] * m[2][0] - m[1][0] * m[2][2]); \
1288 a[2][0] = (s) * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); \
1289 \
1290 a[0][1] = (s) * (m[0][2] * m[2][1] - m[0][1] * m[2][2]); \
1291 a[1][1] = (s) * (m[0][0] * m[2][2] - m[0][2] * m[2][0]); \
1292 a[2][1] = (s) * (m[0][1] * m[2][0] - m[0][0] * m[2][1]); \
1293 \
1294 a[0][2] = (s) * (m[0][1] * m[1][2] - m[0][2] * m[1][1]); \
1295 a[1][2] = (s) * (m[0][2] * m[1][0] - m[0][0] * m[1][2]); \
1296 a[2][2] = (s) * (m[0][0] * m[1][1] - m[0][1] * m[1][0]); \
1297}\
1298
1299
1300/** compute adjoint of matrix and scale
1301 *
1302 * Computes adjoint of matrix m, scales it by s, returning a
1303 */
1304#define SCALE_ADJOINT_4X4(a,s,m) \
1305{ \
1306 char _i_,_j_; \
1307 for (_i_=0; _i_<4; _i_++) { \
1308 for (_j_=0; _j_<4; _j_++) { \
1309 COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_); \
1310 a[_j_][_i_] *= s; \
1311 } \
1312 } \
1313}\
1314
1315/** inverse of matrix
1316 *
1317 * Compute inverse of matrix a, returning determinant m and
1318 * inverse b
1319 */
1320#define INVERT_2X2(b,det,a) \
1321{ \
1322 GREAL _tmp_; \
1323 DETERMINANT_2X2 (det, a); \
1324 _tmp_ = 1.0 / (det); \
1325 SCALE_ADJOINT_2X2 (b, _tmp_, a); \
1326}\
1327
1328
1329/** inverse of matrix
1330 *
1331 * Compute inverse of matrix a, returning determinant m and
1332 * inverse b
1333 */
1334#define INVERT_3X3(b,det,a) \
1335{ \
1336 GREAL _tmp_; \
1337 DETERMINANT_3X3 (det, a); \
1338 _tmp_ = 1.0 / (det); \
1339 SCALE_ADJOINT_3X3 (b, _tmp_, a); \
1340}\
1341
1342
1343/** inverse of matrix
1344 *
1345 * Compute inverse of matrix a, returning determinant m and
1346 * inverse b
1347 */
1348#define INVERT_4X4(b,det,a) \
1349{ \
1350 GREAL _tmp_; \
1351 DETERMINANT_4X4 (det, a); \
1352 _tmp_ = 1.0 / (det); \
1353 SCALE_ADJOINT_4X4 (b, _tmp_, a); \
1354}\
1355
1356//! @}
1357
1358/*! \defgroup BOUND_AABB_OPERATIONS
1359*/
1360//! @{
1361
1362//!Initializes an AABB
1363#define INVALIDATE_AABB(aabb) {\
1364 (aabb).minX = G_REAL_INFINITY;\
1365 (aabb).maxX = -G_REAL_INFINITY;\
1366 (aabb).minY = G_REAL_INFINITY;\
1367 (aabb).maxY = -G_REAL_INFINITY;\
1368 (aabb).minZ = G_REAL_INFINITY;\
1369 (aabb).maxZ = -G_REAL_INFINITY;\
1370}\
1371
1372#define AABB_GET_MIN(aabb,vmin) {\
1373 vmin[0] = (aabb).minX;\
1374 vmin[1] = (aabb).minY;\
1375 vmin[2] = (aabb).minZ;\
1376}\
1377
1378#define AABB_GET_MAX(aabb,vmax) {\
1379 vmax[0] = (aabb).maxX;\
1380 vmax[1] = (aabb).maxY;\
1381 vmax[2] = (aabb).maxZ;\
1382}\
1383
1384//!Copy boxes
1385#define AABB_COPY(dest_aabb,src_aabb)\
1386{\
1387 (dest_aabb).minX = (src_aabb).minX;\
1388 (dest_aabb).maxX = (src_aabb).maxX;\
1389 (dest_aabb).minY = (src_aabb).minY;\
1390 (dest_aabb).maxY = (src_aabb).maxY;\
1391 (dest_aabb).minZ = (src_aabb).minZ;\
1392 (dest_aabb).maxZ = (src_aabb).maxZ;\
1393}\
1394
1395//! Computes an Axis aligned box from a triangle
1396#define COMPUTEAABB_FOR_TRIANGLE(aabb,V1,V2,V3) {\
1397 (aabb).minX = MIN3(V1[0],V2[0],V3[0]);\
1398 (aabb).maxX = MAX3(V1[0],V2[0],V3[0]);\
1399 (aabb).minY = MIN3(V1[1],V2[1],V3[1]);\
1400 (aabb).maxY = MAX3(V1[1],V2[1],V3[1]);\
1401 (aabb).minZ = MIN3(V1[2],V2[2],V3[2]);\
1402 (aabb).maxZ = MAX3(V1[2],V2[2],V3[2]);\
1403}\
1404
1405//! Merge two boxes to destaabb
1406#define MERGEBOXES(destaabb,aabb) {\
1407 (destaabb).minX = MIN((aabb).minX,(destaabb).minX);\
1408 (destaabb).minY = MIN((aabb).minY,(destaabb).minY);\
1409 (destaabb).minZ = MIN((aabb).minZ,(destaabb).minZ);\
1410 (destaabb).maxX = MAX((aabb).maxX,(destaabb).maxX);\
1411 (destaabb).maxY = MAX((aabb).maxY,(destaabb).maxY);\
1412 (destaabb).maxZ = MAX((aabb).maxZ,(destaabb).maxZ);\
1413}\
1414
1415//! Extends the box
1416#define AABB_POINT_EXTEND(destaabb,p) {\
1417 (destaabb).minX = MIN(p[0],(destaabb).minX);\
1418 (destaabb).maxX = MAX(p[0],(destaabb).maxX);\
1419 (destaabb).minY = MIN(p[1],(destaabb).minY);\
1420 (destaabb).maxY = MAX(p[1],(destaabb).maxY);\
1421 (destaabb).minZ = MIN(p[2],(destaabb).minZ);\
1422 (destaabb).maxZ = MAX(p[2],(destaabb).maxZ);\
1423}\
1424
1425//! Finds the intersection box of two boxes
1426#define BOXINTERSECTION(aabb1, aabb2, iaabb) {\
1427 (iaabb).minX = MAX((aabb1).minX,(aabb2).minX);\
1428 (iaabb).minY = MAX((aabb1).minY,(aabb2).minY);\
1429 (iaabb).minZ = MAX((aabb1).minZ,(aabb2).minZ);\
1430 (iaabb).maxX = MIN((aabb1).maxX,(aabb2).maxX);\
1431 (iaabb).maxY = MIN((aabb1).maxY,(aabb2).maxY);\
1432 (iaabb).maxZ = MIN((aabb1).maxZ,(aabb2).maxZ);\
1433}\
1434
1435//! Determines if two aligned boxes do intersect
1436#define AABBCOLLISION(intersected,aabb1,aabb2) {\
1437 intersected = 1;\
1438 if ((aabb1).minX > (aabb2).maxX ||\
1439 (aabb1).maxX < (aabb2).minX ||\
1440 (aabb1).minY > (aabb2).maxY ||\
1441 (aabb1).maxY < (aabb2).minY ||\
1442 (aabb1).minZ > (aabb2).maxZ ||\
1443 (aabb1).maxZ < (aabb2).minZ )\
1444 {\
1445 intersected = 0;\
1446 }\
1447}\
1448
1449#define AXIS_INTERSECT(min,max, a, d,tfirst, tlast,is_intersected) {\
1450 if(IS_ZERO(d))\
1451 {\
1452 is_intersected = !(a < min || a > max);\
1453 }\
1454 else\
1455 {\
1456 GREAL a0, a1;\
1457 a0 = (min - a) / (d);\
1458 a1 = (max - a) / (d);\
1459 if(a0 > a1) SWAP_NUMBERS(a0, a1);\
1460 tfirst = MAX(a0, tfirst);\
1461 tlast = MIN(a1, tlast);\
1462 if (tlast < tfirst)\
1463 {\
1464 is_intersected = 0;\
1465 }\
1466 else\
1467 {\
1468 is_intersected = 1;\
1469 }\
1470 }\
1471}\
1472
1473/*! \brief Finds the Ray intersection parameter.
1474
1475\param aabb Aligned box
1476\param vorigin A vec3f with the origin of the ray
1477\param vdir A vec3f with the direction of the ray
1478\param tparam Output parameter
1479\param tmax Max lenght of the ray
1480\param is_intersected 1 if the ray collides the box, else false
1481
1482*/
1483#define BOX_INTERSECTS_RAY(aabb, vorigin, vdir, tparam, tmax,is_intersected) { \
1484 GREAL _tfirst = 0.0f, _tlast = tmax;\
1485 AXIS_INTERSECT(aabb.minX,aabb.maxX,vorigin[0], vdir[0], _tfirst, _tlast,is_intersected);\
1486 if(is_intersected)\
1487 {\
1488 AXIS_INTERSECT(aabb.minY,aabb.maxY,vorigin[1], vdir[1], _tfirst, _tlast,is_intersected);\
1489 }\
1490 if(is_intersected)\
1491 {\
1492 AXIS_INTERSECT(aabb.minZ,aabb.maxZ,vorigin[2], vdir[2], _tfirst, _tlast,is_intersected);\
1493 }\
1494 tparam = _tfirst;\
1495}\
1496
1497#define AABB_PROJECTION_INTERVAL(aabb,direction, vmin, vmax)\
1498{\
1499 GREAL _center[] = {(aabb.minX + aabb.maxX)*0.5f, (aabb.minY + aabb.maxY)*0.5f, (aabb.minZ + aabb.maxZ)*0.5f};\
1500 \
1501 GREAL _extend[] = {aabb.maxX-_center[0],aabb.maxY-_center[1],aabb.maxZ-_center[2]};\
1502 GREAL _fOrigin = VEC_DOT(direction,_center);\
1503 GREAL _fMaximumExtent = _extend[0]*fabsf(direction[0]) + \
1504 _extend[1]*fabsf(direction[1]) + \
1505 _extend[2]*fabsf(direction[2]); \
1506\
1507 vmin = _fOrigin - _fMaximumExtent; \
1508 vmax = _fOrigin + _fMaximumExtent; \
1509}\
1510
1511/*!
1512classify values:
1513<ol>
1514<li> 0 : In back of plane
1515<li> 1 : Spanning
1516<li> 2 : In front of
1517</ol>
1518*/
1519#define PLANE_CLASSIFY_BOX(plane,aabb,classify)\
1520{\
1521 GREAL _fmin,_fmax; \
1522 AABB_PROJECTION_INTERVAL(aabb,plane, _fmin, _fmax); \
1523 if(plane[3] >= _fmax) \
1524 { \
1525 classify = 0;/*In back of*/ \
1526 } \
1527 else \
1528 { \
1529 if(plane[3]+0.000001f>=_fmin) \
1530 { \
1531 classify = 1;/*Spanning*/ \
1532 } \
1533 else \
1534 { \
1535 classify = 2;/*In front of*/ \
1536 } \
1537 } \
1538}\
1539//! @}
1540
1541/*! \defgroup GEOMETRIC_OPERATIONS
1542*/
1543//! @{
1544
1545
1546#define PLANEDIREPSILON 0.0000001f
1547#define PARALELENORMALS 0.000001f
1548
1549#define TRIANGLE_NORMAL(v1,v2,v3,n){\
1550 vec3f _dif1,_dif2; \
1551 VEC_DIFF(_dif1,v2,v1); \
1552 VEC_DIFF(_dif2,v3,v1); \
1553 VEC_CROSS(n,_dif1,_dif2); \
1554 VEC_NORMALIZE(n); \
1555}\
1556
1557/// plane is a vec4f
1558#define TRIANGLE_PLANE(v1,v2,v3,plane) {\
1559 TRIANGLE_NORMAL(v1,v2,v3,plane);\
1560 plane[3] = VEC_DOT(v1,plane);\
1561}\
1562
1563/// Calc a plane from an edge an a normal. plane is a vec4f
1564#define EDGE_PLANE(e1,e2,n,plane) {\
1565 vec3f _dif; \
1566 VEC_DIFF(_dif,e2,e1); \
1567 VEC_CROSS(plane,_dif,n); \
1568 VEC_NORMALIZE(plane); \
1569 plane[3] = VEC_DOT(e1,plane);\
1570}\
1571
1572#define DISTANCE_PLANE_POINT(plane,point) (VEC_DOT(plane,point) - plane[3])
1573
1574#define PROJECT_POINT_PLANE(point,plane,projected) {\
1575 GREAL _dis;\
1576 _dis = DISTANCE_PLANE_POINT(plane,point);\
1577 VEC_SCALE(projected,-_dis,plane);\
1578 VEC_SUM(projected,projected,point); \
1579}\
1580
1581#define POINT_IN_HULL(point,planes,plane_count,outside)\
1582{\
1583 GREAL _dis;\
1584 outside = 0;\
1585 GUINT _i = 0;\
1586 do\
1587 {\
1588 _dis = DISTANCE_PLANE_POINT(planes[_i],point);\
1589 if(_dis>0.0f) outside = 1;\
1590 _i++;\
1591 }while(_i<plane_count&&outside==0);\
1592}\
1593
1594
1595#define PLANE_CLIP_SEGMENT(s1,s2,plane,clipped) {\
1596 GREAL _dis1,_dis2;\
1597 _dis1 = DISTANCE_PLANE_POINT(plane,s1);\
1598 VEC_DIFF(clipped,s2,s1);\
1599 _dis2 = VEC_DOT(clipped,plane);\
1600 VEC_SCALE(clipped,-_dis1/_dis2,clipped);\
1601 VEC_SUM(clipped,clipped,s1); \
1602}\
1603
1604//! Confirms if the plane intersect the edge or nor
1605/*!
1606intersection type must have the following values
1607<ul>
1608<li> 0 : Segment in front of plane, s1 closest
1609<li> 1 : Segment in front of plane, s2 closest
1610<li> 2 : Segment in back of plane, s1 closest
1611<li> 3 : Segment in back of plane, s2 closest
1612<li> 4 : Segment collides plane, s1 in back
1613<li> 5 : Segment collides plane, s2 in back
1614</ul>
1615*/
1616#define PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped,intersection_type) \
1617{\
1618 GREAL _dis1,_dis2;\
1619 _dis1 = DISTANCE_PLANE_POINT(plane,s1);\
1620 _dis2 = DISTANCE_PLANE_POINT(plane,s2);\
1621 if(_dis1 >-G_EPSILON && _dis2 >-G_EPSILON)\
1622 {\
1623 if(_dis1<_dis2) intersection_type = 0;\
1624 else intersection_type = 1;\
1625 }\
1626 else if(_dis1 <G_EPSILON && _dis2 <G_EPSILON)\
1627 {\
1628 if(_dis1>_dis2) intersection_type = 2;\
1629 else intersection_type = 3; \
1630 }\
1631 else\
1632 {\
1633 if(_dis1<_dis2) intersection_type = 4;\
1634 else intersection_type = 5;\
1635 VEC_DIFF(clipped,s2,s1);\
1636 _dis2 = VEC_DOT(clipped,plane);\
1637 VEC_SCALE(clipped,-_dis1/_dis2,clipped);\
1638 VEC_SUM(clipped,clipped,s1); \
1639 }\
1640}\
1641
1642//! Confirms if the plane intersect the edge or not
1643/*!
1644clipped1 and clipped2 are the vertices behind the plane.
1645clipped1 is the closest
1646
1647intersection_type must have the following values
1648<ul>
1649<li> 0 : Segment in front of plane, s1 closest
1650<li> 1 : Segment in front of plane, s2 closest
1651<li> 2 : Segment in back of plane, s1 closest
1652<li> 3 : Segment in back of plane, s2 closest
1653<li> 4 : Segment collides plane, s1 in back
1654<li> 5 : Segment collides plane, s2 in back
1655</ul>
1656*/
1657#define PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,plane,clipped1,clipped2,intersection_type)\
1658{\
1659 PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped1,intersection_type);\
1660 if(intersection_type == 0)\
1661 {\
1662 VEC_COPY(clipped1,s1);\
1663 VEC_COPY(clipped2,s2);\
1664 }\
1665 else if(intersection_type == 1)\
1666 {\
1667 VEC_COPY(clipped1,s2);\
1668 VEC_COPY(clipped2,s1);\
1669 }\
1670 else if(intersection_type == 2)\
1671 {\
1672 VEC_COPY(clipped1,s1);\
1673 VEC_COPY(clipped2,s2);\
1674 }\
1675 else if(intersection_type == 3)\
1676 {\
1677 VEC_COPY(clipped1,s2);\
1678 VEC_COPY(clipped2,s1);\
1679 }\
1680 else if(intersection_type == 4)\
1681 { \
1682 VEC_COPY(clipped2,s1);\
1683 }\
1684 else if(intersection_type == 5)\
1685 { \
1686 VEC_COPY(clipped2,s2);\
1687 }\
1688}\
1689
1690
1691//! Finds the 2 smallest cartesian coordinates of a plane normal
1692#define PLANE_MINOR_AXES(plane, i0, i1)\
1693{\
1694 GREAL A[] = {fabs(plane[0]),fabs(plane[1]),fabs(plane[2])};\
1695 if(A[0]>A[1])\
1696 {\
1697 if(A[0]>A[2])\
1698 {\
1699 i0=1; /* A[0] is greatest */ \
1700 i1=2;\
1701 }\
1702 else \
1703 {\
1704 i0=0; /* A[2] is greatest */ \
1705 i1=1; \
1706 }\
1707 }\
1708 else /* A[0]<=A[1] */ \
1709 {\
1710 if(A[2]>A[1]) \
1711 { \
1712 i0=0; /* A[2] is greatest */ \
1713 i1=1; \
1714 }\
1715 else \
1716 {\
1717 i0=0; /* A[1] is greatest */ \
1718 i1=2; \
1719 }\
1720 } \
1721}\
1722
1723//! Ray plane collision
1724#define RAY_PLANE_COLLISION(plane,vDir,vPoint,pout,tparam,does_intersect)\
1725{\
1726 GREAL _dis,_dotdir; \
1727 _dotdir = VEC_DOT(plane,vDir);\
1728 if(_dotdir<PLANEDIREPSILON)\
1729 {\
1730 does_intersect = 0;\
1731 }\
1732 else\
1733 {\
1734 _dis = DISTANCE_PLANE_POINT(plane,vPoint); \
1735 tparam = -_dis/_dotdir;\
1736 VEC_SCALE(pout,tparam,vDir);\
1737 VEC_SUM(pout,vPoint,pout); \
1738 does_intersect = 1;\
1739 }\
1740}\
1741
1742//! Bidireccional ray
1743#define LINE_PLANE_COLLISION(plane,vDir,vPoint,pout,tparam, tmin, tmax)\
1744{\
1745 tparam = -DISTANCE_PLANE_POINT(plane,vPoint);\
1746 tparam /= VEC_DOT(plane,vDir);\
1747 tparam = CLAMP(tparam,tmin,tmax);\
1748 VEC_SCALE(pout,tparam,vDir);\
1749 VEC_SUM(pout,vPoint,pout); \
1750}\
1751
1752/*! \brief Returns the Ray on which 2 planes intersect if they do.
1753 Written by Rodrigo Hernandez on ODE convex collision
1754
1755 \param p1 Plane 1
1756 \param p2 Plane 2
1757 \param p Contains the origin of the ray upon returning if planes intersect
1758 \param d Contains the direction of the ray upon returning if planes intersect
1759 \param dointersect 1 if the planes intersect, 0 if paralell.
1760
1761*/
1762#define INTERSECT_PLANES(p1,p2,p,d,dointersect) \
1763{ \
1764 VEC_CROSS(d,p1,p2); \
1765 GREAL denom = VEC_DOT(d, d);\
1766 if (IS_ZERO(denom)) \
1767 { \
1768 dointersect = 0; \
1769 } \
1770 else \
1771 { \
1772 vec3f _n;\
1773 _n[0]=p1[3]*p2[0] - p2[3]*p1[0]; \
1774 _n[1]=p1[3]*p2[1] - p2[3]*p1[1]; \
1775 _n[2]=p1[3]*p2[2] - p2[3]*p1[2]; \
1776 VEC_CROSS(p,_n,d); \
1777 p[0]/=denom; \
1778 p[1]/=denom; \
1779 p[2]/=denom; \
1780 dointersect = 1; \
1781 }\
1782}\
1783
1784//***************** SEGMENT and LINE FUNCTIONS **********************************///
1785
1786/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
1787 */
1788#define CLOSEST_POINT_ON_SEGMENT(cp,v,e1,e2) \
1789{ \
1790 vec3f _n;\
1791 VEC_DIFF(_n,e2,e1);\
1792 VEC_DIFF(cp,v,e1);\
1793 GREAL _scalar = VEC_DOT(cp, _n); \
1794 _scalar/= VEC_DOT(_n, _n); \
1795 if(_scalar <0.0f)\
1796 {\
1797 VEC_COPY(cp,e1);\
1798 }\
1799 else if(_scalar >1.0f)\
1800 {\
1801 VEC_COPY(cp,e2);\
1802 }\
1803 else \
1804 {\
1805 VEC_SCALE(cp,_scalar,_n);\
1806 VEC_SUM(cp,cp,e1);\
1807 } \
1808}\
1809
1810
1811/*! \brief Finds the line params where these lines intersect.
1812
1813\param dir1 Direction of line 1
1814\param point1 Point of line 1
1815\param dir2 Direction of line 2
1816\param point2 Point of line 2
1817\param t1 Result Parameter for line 1
1818\param t2 Result Parameter for line 2
1819\param dointersect 0 if the lines won't intersect, else 1
1820
1821*/
1822#define LINE_INTERSECTION_PARAMS(dir1,point1, dir2, point2,t1,t2,dointersect) {\
1823 GREAL det;\
1824 GREAL e1e1 = VEC_DOT(dir1,dir1);\
1825 GREAL e1e2 = VEC_DOT(dir1,dir2);\
1826 GREAL e2e2 = VEC_DOT(dir2,dir2);\
1827 vec3f p1p2;\
1828 VEC_DIFF(p1p2,point1,point2);\
1829 GREAL p1p2e1 = VEC_DOT(p1p2,dir1);\
1830 GREAL p1p2e2 = VEC_DOT(p1p2,dir2);\
1831 det = e1e2*e1e2 - e1e1*e2e2;\
1832 if(IS_ZERO(det))\
1833 {\
1834 dointersect = 0;\
1835 }\
1836 else\
1837 {\
1838 t1 = (e1e2*p1p2e2 - e2e2*p1p2e1)/det;\
1839 t2 = (e1e1*p1p2e2 - e1e2*p1p2e1)/det;\
1840 dointersect = 1;\
1841 }\
1842}\
1843
1844//! Find closest points on segments
1845#define SEGMENT_COLLISION(vA1,vA2,vB1,vB2,vPointA,vPointB)\
1846{\
1847 vec3f _AD,_BD,_N;\
1848 vec4f _M;\
1849 VEC_DIFF(_AD,vA2,vA1);\
1850 VEC_DIFF(_BD,vB2,vB1);\
1851 VEC_CROSS(_N,_AD,_BD);\
1852 VEC_CROSS(_M,_N,_BD);\
1853 _M[3] = VEC_DOT(_M,vB1);\
1854 float _tp; \
1855 LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,0.0f, 1.0f);\
1856 /*Closest point on segment*/ \
1857 VEC_DIFF(vPointB,vPointA,vB1);\
1858 _tp = VEC_DOT(vPointB, _BD); \
1859 _tp/= VEC_DOT(_BD, _BD); \
1860 _tp = CLAMP(_tp,0.0f,1.0f); \
1861 VEC_SCALE(vPointB,_tp,_BD);\
1862 VEC_SUM(vPointB,vPointB,vB1);\
1863}\
1864
1865//! @}
1866
1867///Additional Headers for Collision
1868#include "GIMPACT/gim_tri_collision.h"
1869#include "GIMPACT/gim_tri_sphere_collision.h"
1870#include "GIMPACT/gim_tri_capsule_collision.h"
1871
1872#endif // GIM_VECTOR_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h
new file mode 100644
index 0000000..68f226e
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h
@@ -0,0 +1,147 @@
1#ifndef GIM_MATH_H_INCLUDED
2#define GIM_MATH_H_INCLUDED
3
4/*! \file gim_math.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include <math.h>
36#include <float.h>
37
38
39/*! \defgroup BASIC_TYPES
40Basic types and constants
41Conventions:
42Types starting with G
43Constants starting with G_
44*/
45//! @{
46/*! Types */
47#define GREAL float
48#define GINT long
49#define GUINT unsigned long
50/*! Constants for integers*/
51#define GUINT_BIT_COUNT 32
52#define GUINT_EXPONENT 5
53
54#define G_FASTMATH 1
55#define G_PI 3.14159265358979f
56#define G_HALF_PI 1.5707963f
57//267948966
58#define G_TWO_PI 6.28318530f
59//71795864
60#define G_ROOT3 1.73205f
61#define G_ROOT2 1.41421f
62#define G_UINT_INFINITY 65534
63#define G_REAL_INFINITY FLT_MAX
64#define G_SIGN_BITMASK 0x80000000
65#define G_USE_EPSILON_TEST
66#define G_EPSILON 0.0000001f
67//! @}
68
69/*! \defgroup MATH_FUNCTIONS
70mathematical functions
71*/
72//! @{
73#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f)
74#define G_RADTODEG(X) ((X)*180.0f/3.1415926f)
75
76//! Integer representation of a floating-point value.
77#define IR(x) ((GUINT&)(x))
78
79//! Signed integer representation of a floating-point value.
80#define SIR(x) ((GINT&)(x))
81
82//! Absolute integer representation of a floating-point value
83#define AIR(x) (IR(x)&0x7fffffff)
84
85//! Floating-point representation of an integer value.
86#define FR(x) ((GREAL&)(x))
87
88#define MAX(a,b) (a<b?b:a)
89#define MIN(a,b) (a>b?b:a)
90
91#define MAX3(a,b,c) MAX(a,MAX(b,c))
92#define MIN3(a,b,c) MIN(a,MIN(b,c))
93
94#define IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON)
95
96#define IS_NEGATIVE(value) (value <= -G_EPSILON)
97
98#define IS_POSISITVE(value) (value >= G_EPSILON)
99
100///returns a clamped number
101#define CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
102
103///Swap numbers
104#define SWAP_NUMBERS(a,b){ \
105 a = a+b; \
106 b = a-b; \
107 a = a-b; \
108}\
109
110#define GIM_INV_SQRT(va,isva)\
111{\
112 if(va<=0.0000001f)\
113 {\
114 isva = G_REAL_INFINITY;\
115 }\
116 else\
117 {\
118 GREAL _x = va * 0.5f;\
119 GUINT _y = 0x5f3759df - ( IR(va) >> 1);\
120 isva = FR(_y);\
121 isva = isva * ( 1.5f - ( _x * isva * isva ) );\
122 }\
123}\
124
125#define GIM_SQRT(va,sva)\
126{\
127 GIM_INV_SQRT(va,sva);\
128 sva = 1.0f/sva;\
129}\
130
131//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html
132GREAL gim_inv_sqrt(GREAL f);
133
134//! Computes sqrtf(x) faster.
135/*!
136\sa gim_inv_sqrt
137*/
138GREAL gim_sqrt(GREAL f);
139
140//!Initializes mathematical functions
141void gim_init_math();
142
143//! Generates an unit random
144GREAL gim_unit_random();
145//! @}
146
147#endif // GIM_MATH_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h
new file mode 100644
index 0000000..58661f1
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h
@@ -0,0 +1,1040 @@
1#ifndef GIM_MEMORY_H_INCLUDED
2#define GIM_MEMORY_H_INCLUDED
3/*! \file gim_memory.h
4\author Francisco León
5*/
6/*
7-----------------------------------------------------------------------------
8This source file is part of GIMPACT Library.
9
10For the latest info, see http://gimpact.sourceforge.net/
11
12Copyright (c) 2006 Francisco Leon. C.C. 80087371.
13email: projectileman@yahoo.com
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of EITHER:
17 (1) The GNU Lesser General Public License as published by the Free
18 Software Foundation; either version 2.1 of the License, or (at
19 your option) any later version. The text of the GNU Lesser
20 General Public License is included with this library in the
21 file GIMPACT-LICENSE-LGPL.TXT.
22 (2) The BSD-style license that is included with this library in
23 the file GIMPACT-LICENSE-BSD.TXT.
24
25 This library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
28 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
29
30-----------------------------------------------------------------------------
31*/
32
33
34#include "GIMPACT/gim_math.h"
35#include <memory.h>
36
37//#define PREFETCH 1
38//! \defgroup PREFETCH
39//! @{
40#ifdef PREFETCH
41#include <xmmintrin.h> // for prefetch
42#define pfval 64
43#define pfval2 128
44//! Prefetch 64
45#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0)
46//! Prefetch 128
47#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
48#else
49//! Prefetch 64
50#define pf(_x,_i)
51//! Prefetch 128
52#define pf2(_x,_i)
53#endif
54//! @}
55
56/*! \defgroup ARRAY_UTILITIES
57\brief
58Functions for manip packed arrays of numbers
59*/
60//! @{
61#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\
62{\
63 GUINT _i_;\
64 for (_i_=0;_i_<element_count ;_i_++)\
65 {\
66 dest_array[_i_] = source_array[_i_];\
67 }\
68}\
69
70#define GIM_COPY_ARRAYS_1(dest_array,source_array,element_count,copy_macro)\
71{\
72 GUINT _i_;\
73 for (_i_=0;_i_<element_count ;_i_++)\
74 {\
75 copy_macro(dest_array[_i_],source_array[_i_]);\
76 }\
77}\
78
79
80#define GIM_ZERO_ARRAY(array,element_count)\
81{\
82 GUINT _i_;\
83 for (_i_=0;_i_<element_count ;_i_++)\
84 {\
85 array[_i_] = 0;\
86 }\
87}\
88
89#define GIM_CONSTANT_ARRAY(array,element_count,constant)\
90{\
91 GUINT _i_;\
92 for (_i_=0;_i_<element_count ;_i_++)\
93 {\
94 array[_i_] = constant;\
95 }\
96}\
97//! @}
98
99/*! \defgroup MEMORY_FUNCTION_PROTOTYPES
100Function prototypes to allocate and free memory.
101*/
102//! @{
103typedef void * gim_alloc_function (size_t size);
104typedef void * gim_alloca_function (size_t size);//Allocs on the heap
105typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
106typedef void gim_free_function (void *ptr, size_t size);
107//! @}
108
109/*! \defgroup MEMORY_FUNCTION_HANDLERS
110\brief
111Memory Function Handlers
112 set new memory management functions. if fn is 0, the default handlers are
113 used. */
114//! @{
115void gim_set_alloc_handler (gim_alloc_function *fn);
116void gim_set_alloca_handler (gim_alloca_function *fn);
117void gim_set_realloc_handler (gim_realloc_function *fn);
118void gim_set_free_handler (gim_free_function *fn);
119//! @}
120
121/*! \defgroup MEMORY_FUNCTION_GET_HANDLERS
122\brief
123get current memory management functions.
124*/
125//! @{
126gim_alloc_function *gim_get_alloc_handler (void);
127gim_alloca_function *gim_get_alloca_handler(void);
128gim_realloc_function *gim_get_realloc_handler (void);
129gim_free_function *gim_get_free_handler (void);
130//! @}
131
132/*! \defgroup MEMORY_FUNCTIONS
133Standar Memory functions
134*/
135//! @{
136void * gim_alloc(size_t size);
137void * gim_alloca(size_t size);
138void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
139void gim_free(void *ptr, size_t size);
140//! @}
141
142/*! \defgroup DYNAMIC_ARRAYS
143\brief
144Dynamic Arrays. Allocated from system memory.
145<ul>
146<li> For initializes a dynamic array, use GIM_DYNARRAY_CREATE or GIM_DYNARRAY_CREATE_SIZED.
147<li> When an array is no longer used, must be terminated with the macro GIM_DYNARRAY_DESTROY.
148</ul>
149*/
150//! @{
151#define G_ARRAY_GROW_SIZE 100
152
153//! Dynamic array handle.
154struct GDYNAMIC_ARRAY
155{
156 char * m_pdata;
157 GUINT m_size;
158 GUINT m_reserve_size;
159};
160//typedef struct _GDYNAMIC_ARRAY GDYNAMIC_ARRAY;
161
162//! Creates a dynamic array zero sized
163#define GIM_DYNARRAY_CREATE(type,array_data,reserve_size) \
164{ \
165 array_data.m_pdata = (char *)gim_alloc(reserve_size*sizeof(type)); \
166 array_data.m_size = 0; \
167 array_data.m_reserve_size = reserve_size; \
168}\
169
170//! Creates a dynamic array with n = size elements
171#define GIM_DYNARRAY_CREATE_SIZED(type,array_data,size) \
172{ \
173 array_data.m_pdata = (char *)gim_alloc(size*sizeof(type)); \
174 array_data.m_size = size; \
175 array_data.m_reserve_size = size; \
176}\
177
178//! Reserves memory for a dynamic array.
179#define GIM_DYNARRAY_RESERVE_SIZE(type,array_data,reserve_size) \
180{ \
181 if(reserve_size>array_data.m_reserve_size )\
182 { \
183 array_data.m_pdata = (char *) gim_realloc(array_data.m_pdata,array_data.m_size*sizeof(type),reserve_size*sizeof(type));\
184 array_data.m_reserve_size = reserve_size; \
185 }\
186}\
187
188//! Set the size of the array
189#define GIM_DYNARRAY_SET_SIZE(type,array_data,size) \
190{ \
191 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,size);\
192 array_data.m_size = size;\
193}\
194
195//! Gets a pointer from the beginning of the array
196#define GIM_DYNARRAY_POINTER(type,array_data) (type *)(array_data.m_pdata)
197
198//! Gets a pointer from the last elemento of the array
199#define GIM_DYNARRAY_POINTER_LAST(type,array_data) (((type *)array_data.m_pdata)+array_data.m_size-1)
200
201//! Inserts an element at the last position
202#define GIM_DYNARRAY_PUSH_ITEM(type,array_data,item)\
203{\
204 if(array_data.m_reserve_size<=array_data.m_size)\
205 {\
206 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
207 }\
208 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
209 memcpy(&_pt[array_data.m_size],&item,sizeof(type));\
210 array_data.m_size++; \
211}\
212
213//! Inserts an element at the last position
214#define GIM_DYNARRAY_PUSH_EMPTY(type,array_data)\
215{\
216 if(array_data.m_reserve_size<=array_data.m_size)\
217 {\
218 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
219 }\
220 array_data.m_size++; \
221}\
222
223//! Inserts an element
224#define GIM_DYNARRAY_INSERT_ITEM(type,array_data,item,index) \
225{ \
226 if(array_data.m_reserve_size<=array_data.m_size)\
227 {\
228 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
229 }\
230 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
231 if(index<array_data.m_size-1) \
232 { \
233 memcpy(&_pt[index+1],&_pt[index],(array_data.m_size-index)*sizeof(type));\
234 } \
235 memcpy(&_pt[index],&item,sizeof(type));\
236 array_data.m_size++; \
237}\
238
239//! Removes an element
240#define GIM_DYNARRAY_DELETE_ITEM(type,array_data,index) \
241{ \
242 if(index<array_data.m_size-1) \
243 { \
244 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
245 memcpy(&_pt[index],&_pt[index+1],(array_data.m_size-index-1)*sizeof(type));\
246 } \
247 array_data.m_size--; \
248}\
249
250//! Removes an element at the last position
251#define GIM_DYNARRAY_POP_ITEM(array_data) \
252{ \
253 if(array_data.m_size>0) \
254 { \
255 array_data.m_size--; \
256 } \
257}\
258
259//! Destroys the array
260void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data);
261//! @}
262
263/*! \defgroup BITSET
264\brief
265Bitsets , based on \ref DYNAMIC_ARRAYS .
266<ul>
267<li> For initializes a bitset array, use \ref GIM_BITSET_CREATE or \ref GIM_BITSET_CREATE_SIZED.
268<li> When the bitset is no longer used, must be terminated with the macro \ref GIM_DYNARRAY_DESTROY.
269<li> For putting a mark on the bitset, call \ref GIM_BITSET_SET
270<li> For clearing a mark on the bitset, call \ref GIM_BITSET_CLEAR
271<li> For retrieving a bit value from a bitset, call \ref GIM_BITSET_GET-
272</ul>
273*/
274//! @{
275
276//! Creates a bitset
277#define GIM_BITSET_CREATE(array_data) GIM_DYNARRAY_CREATE(GUINT,array_data,G_ARRAY_GROW_SIZE)
278
279//! Creates a bitset, with their bits set to 0.
280#define GIM_BITSET_CREATE_SIZED(array_data,bits_count)\
281{\
282 array_data.m_size = bits_count/GUINT_BIT_COUNT + 1;\
283 GIM_DYNARRAY_CREATE(GUINT,array_data,array_data.m_size);\
284 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
285 memset(_pt,0,sizeof(GUINT)*(array_data.m_size));\
286}\
287
288//! Gets the bitset bit count.
289#define GIM_BITSET_SIZE(array_data) (array_data.m_size*GUINT_BIT_COUNT)
290
291//! Resizes a bitset, with their bits set to 0.
292#define GIM_BITSET_RESIZE(array_data,new_bits_count)\
293{ \
294 GUINT _oldsize = array_data.m_size;\
295 array_data.m_size = new_bits_count/GUINT_BIT_COUNT + 1; \
296 if(_oldsize<array_data.m_size)\
297 {\
298 if(array_data.m_size > array_data.m_reserve_size)\
299 {\
300 GIM_DYNARRAY_RESERVE_SIZE(GUINT,array_data,array_data.m_size+G_ARRAY_GROW_SIZE);\
301 }\
302 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
303 memset(&_pt[_oldsize],0,sizeof(GUINT)*(array_data.m_size-_oldsize));\
304 }\
305}\
306
307//! Sets all bitset bit to 0.
308#define GIM_BITSET_CLEAR_ALL(array_data)\
309{\
310 memset(array_data.m_pdata,0,sizeof(GUINT)*array_data.m_size);\
311}\
312
313//! Sets all bitset bit to 1.
314#define GIM_BITSET_SET_ALL(array_data)\
315{\
316 memset(array_data.m_pdata,0xFF,sizeof(GUINT)*array_data.m_size);\
317}\
318
319///Sets the desired bit to 1
320#define GIM_BITSET_SET(array_data,bit_index)\
321{\
322 if(bit_index>=GIM_BITSET_SIZE(array_data))\
323 {\
324 GIM_BITSET_RESIZE(array_data,bit_index);\
325 }\
326 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
327 _pt[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT-1)));\
328}\
329
330///Return 0 or 1
331#define GIM_BITSET_GET(array_data,bit_index,get_value) \
332{\
333 if(bit_index>=GIM_BITSET_SIZE(array_data))\
334 {\
335 get_value = 0;\
336 }\
337 else\
338 {\
339 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
340 get_value = _pt[bit_index >> GUINT_EXPONENT] & (1 << (bit_index & (GUINT_BIT_COUNT-1)));\
341 }\
342}\
343
344///Sets the desired bit to 0
345#define GIM_BITSET_CLEAR(array_data,bit_index) \
346{\
347 if(bit_index<GIM_BITSET_SIZE(array_data))\
348 {\
349 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
350 _pt[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT-1)));\
351 }\
352}\
353//! @}
354
355/*! \defgroup MEMORY_ACCESS_CONSTANTS
356\brief
357Memory Access constants.
358\sa BUFFERS
359*/
360//! @{
361#define G_MA_READ_ONLY 1
362#define G_MA_WRITE_ONLY 2
363#define G_MA_READ_WRITE 3
364//! @}
365
366/*! \defgroup MEMORY_USAGE_CONSTANTS
367\brief
368Memory usage constants.
369\sa BUFFERS
370*/
371//! @{
372/// Don't care how memory is used
373#define G_MU_EITHER 0
374/// specified once, doesn't allow read information
375#define G_MU_STATIC_WRITE 1
376/// specified once, allows to read information from a shadow buffer
377#define G_MU_STATIC_READ 2
378/// write directly on buffer, allows to read information from a shadow buffer
379#define G_MU_STATIC_READ_DYNAMIC_WRITE 3
380/// upload data to buffer from the shadow buffer, allows to read information from a shadow buffer
381#define G_MU_STATIC_READ_DYNAMIC_WRITE_COPY 4
382/// specified once, allows to read information directly from memory
383#define G_MU_STATIC_WRITE_DYNAMIC_READ 5
384/// write directly on buffer, allows to read information directly from memory
385#define G_MU_DYNAMIC_READ_WRITE 6
386//! @}
387
388/*! \defgroup BUFFER_ERRORS
389\brief
390Buffer operation errors
391\sa BUFFERS
392*/
393//! @{
394#define G_BUFFER_OP_SUCCESS 0
395#define G_BUFFER_OP_INVALID 1
396#define G_BUFFER_OP_STILLREFCOUNTED 2
397//! @}
398
399/*! \defgroup BUFFER_MANAGER_IDS
400\brief
401Buffer manager identifiers
402\sa BUFFERS, BUFFER_MANAGERS
403*/
404//! @{
405#define G_BUFFER_MANAGER_SYSTEM 0
406#define G_BUFFER_MANAGER_SHARED 1
407#define G_BUFFER_MANAGER_USER 2
408//! @}
409
410/*! \defgroup BUFFERS
411\brief
412Buffer operations and structs.
413<ul>
414<li> Before using buffers you must initializes GIMPACT buffer managers by calling \ref gimpact_init.
415<li> For initializes a buffer, use \ref gim_create_buffer, \ref gim_create_buffer_from_data , \ref gim_create_common_buffer, \ref gim_create_common_buffer_from_data or \ref gim_create_shared_buffer_from_data.
416<li> For accessing to the buffer memory, you must call \ref gim_lock_buffer, and then \ref gim_unlock_buffer for finish the access.
417<li> When a buffer is no longer needed, you must free it by calling \ref gim_buffer_free.
418<li> You must call \ref gimpact_terminate when finish your application.
419<li> For a safe manipulation of buffers, use \ref BUFFER_ARRAYS
420</ul>
421\sa BUFFER_MANAGERS, BUFFER_ARRAYS
422*/
423//! @{
424
425//! Buffer handle.
426struct GBUFFER_ID
427{
428 GUINT m_buffer_id;
429 GUINT m_buffer_manager_id;
430};
431//typedef struct _GBUFFER_ID GBUFFER_ID;
432
433//! Buffer internal data
434struct GBUFFER_DATA
435{
436 GUINT m_buffer_handle;//!< if 0, buffer doesn't exists
437 GUINT m_size;
438 GUINT m_usage;
439 GINT m_access;
440 GUINT m_lock_count;
441 char * m_mapped_pointer;
442 GBUFFER_ID m_shadow_buffer;
443 GUINT m_refcount;//! Reference counting for safe garbage collection
444};
445//typedef struct _GBUFFER_DATA GBUFFER_DATA;
446//! @}
447
448/*! \defgroup BUFFERS_MANAGER_PROTOTYPES
449\brief
450Function prototypes to allocate and free memory for buffers
451\sa BUFFER_MANAGERS, BUFFERS
452*/
453//! @{
454
455//! Returns a Buffer handle
456typedef GUINT gim_buffer_alloc_function(GUINT size,int usage);
457
458//! Returns a Buffer handle, and copies the pdata to the buffer
459typedef GUINT gim_buffer_alloc_data_function(const void * pdata,GUINT size,int usage);
460
461//! Changes the size of the buffer preserving the content, and returns the new buffer id
462typedef GUINT gim_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage);
463
464//! It changes the m_buffer_handle member to 0/0
465typedef void gim_buffer_free_function(GUINT buffer_handle,GUINT size);
466
467//! It maps the m_mapped_pointer. Returns a pointer
468typedef char * gim_lock_buffer_function(GUINT buffer_handle,int access);
469
470//! It sets the m_mapped_pointer to 0
471typedef void gim_unlock_buffer_function(GUINT buffer_handle);
472
473typedef void gim_download_from_buffer_function(
474 GUINT source_buffer_handle,
475 GUINT source_pos,
476 void * destdata,
477 GUINT copysize);
478
479typedef void gim_upload_to_buffer_function(
480 GUINT dest_buffer_handle,
481 GUINT dest_pos,
482 void * sourcedata,
483 GUINT copysize);
484
485typedef void gim_copy_buffers_function(
486 GUINT source_buffer_handle,
487 GUINT source_pos,
488 GUINT dest_buffer_handle,
489 GUINT dest_pos,
490 GUINT copysize);
491//! @}
492
493
494/*! \defgroup BUFFER_MANAGERS
495\brief
496Buffer Manager operations
497*/
498//! @{
499//! Buffer manager prototype
500struct GBUFFER_MANAGER_PROTOTYPE
501{
502 gim_buffer_alloc_function * alloc_fn;
503 gim_buffer_alloc_data_function *alloc_data_fn;
504 gim_buffer_realloc_function * realloc_fn;
505 gim_buffer_free_function * free_fn;
506 gim_lock_buffer_function * lock_buffer_fn;
507 gim_unlock_buffer_function * unlock_buffer_fn;
508 gim_download_from_buffer_function * download_from_buffer_fn;
509 gim_upload_to_buffer_function * upload_to_buffer_fn;
510 gim_copy_buffers_function * copy_buffers_fn;
511};
512//typedef struct _GBUFFER_MANAGER_PROTOTYPE GBUFFER_MANAGER_PROTOTYPE;
513
514//! Buffer manager
515struct GBUFFER_MANAGER_DATA
516{
517 GDYNAMIC_ARRAY m_buffer_array;//!< Array of GBUFFER_DATA objects
518 GDYNAMIC_ARRAY m_free_positions;//!< Array of GUINT elements. Free positions
519 GBUFFER_MANAGER_PROTOTYPE m_prototype;//! Prototype of functions
520 GUINT m_active; //!< 0 or 1
521};
522//typedef struct _GBUFFER_MANAGER_DATA GBUFFER_MANAGER_DATA;
523
524//! Adds a buffer Manager to the Memory Singleton
525void gim_create_buffer_manager(GBUFFER_MANAGER_PROTOTYPE * prototype,GUINT buffer_manager_id);
526//! Gets buffer manager
527GUINT gim_get_buffer_manager_count();
528//! Destroys a buffer manager
529void gim_destroy_buffer_manager(GUINT buffer_manager_id);
530void gim_get_buffer_manager_data(GUINT buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data);
531void gim_init_buffer_managers();
532void gim_terminate_buffer_managers();
533
534//! @}
535
536
537/*! \addtogroup BUFFERS
538*/
539//! @{
540
541//!Creates a buffer on the buffer manager specified by buffer_manager_id
542/*!
543\param buffer_manager_id
544\param buffer_size
545\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
546\param buffer_id a pointer for receive the new buffer id
547\return An error code. 0 if success.
548\post m_refcount = 0
549*/
550GUINT gim_create_buffer(
551 GUINT buffer_manager_id,
552 GUINT buffer_size,
553 int usage,
554 GBUFFER_ID * buffer_id);
555
556//!Creates a buffer on the buffer manager specified by buffer_manager_id
557/*!
558\param buffer_manager_id
559\param pdata Data for allocating
560\param buffer_size Size of the data buffer
561\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
562\param buffer_id a pointer for receive the new buffer id
563\return An error code. 0 if success.
564\post m_refcount = 0
565*/
566GUINT gim_create_buffer_from_data(
567 GUINT buffer_manager_id,
568 const void * pdata,
569 GUINT buffer_size,
570 int usage,
571 GBUFFER_ID * buffer_id);
572
573//!Allocates on the G_BUFFER_MANAGER_SYSTEM
574GUINT gim_create_common_buffer(GUINT buffer_size, GBUFFER_ID * buffer_id);
575//!Allocates on the G_BUFFER_MANAGER_SYSTEM, and copies the data
576GUINT gim_create_common_buffer_from_data(
577 const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id);
578//!Creates a buffer with shared data
579GUINT gim_create_shared_buffer_from_data(
580 const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id);
581
582
583//! Add reference counting to buffer.
584GINT gim_buffer_add_ref(GBUFFER_ID * buffer_id);
585
586//! Function for resize buffer, preserving the content
587/*!
588\param buffer_id
589\param newsize
590\return An error code. 0 if success.
591\post If m_refcount>0 then it decrements it.
592*/
593GINT gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT newsize);
594
595//! Eliminates the buffer.
596/*!
597If the buffer reference counting is <= 1 and is unlocked, then it eliminates the buffer.
598*/
599GINT gim_buffer_free(GBUFFER_ID * buffer_id);
600
601//! Locks the buffer for memory access.
602/*!
603\param buffer_id Id from buffer.
604\param access Must have the following values: G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE.
605\param map_pointer Dest Pointer of the memory address from buffer.
606\post m_lock_count increases.
607*/
608GINT gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer);
609
610//! Unlocks the buffer for memory access.
611GINT gim_unlock_buffer(GBUFFER_ID * buffer_id);
612
613//! Gets the buffer size in bytes
614GINT gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT * buffer_size);
615
616//! Determines if the buffer is locked
617GINT gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT * lock_count);
618
619//! Copies the content of the buffer to a dest pointer
620GINT gim_download_from_buffer(
621 GBUFFER_ID * buffer_id,
622 GUINT source_pos,
623 void * destdata,
624 GUINT copysize);
625
626//! Copies the content of a memory pointer to the buffer
627GINT gim_upload_to_buffer(
628 GBUFFER_ID * buffer_id,
629 GUINT dest_pos,
630 void * sourcedata,
631 GUINT copysize);
632
633//! Copies two buffers.
634GINT gim_copy_buffers(
635 GBUFFER_ID * source_buffer_id,
636 GUINT source_pos,
637 GBUFFER_ID * dest_buffer_id,
638 GUINT dest_pos,
639 GUINT copysize);
640//! @}
641
642
643/*! \defgroup BUFFER_ARRAYS
644
645\brief
646Buffered Arrays, for manip elements on a buffer and treat it as an array.
647<ul>
648<li> Before using buffer arrays you must initializes GIMPACT buffer managers by calling gimpact_init.
649<li> Before creating buffer arrays, you must create a buffer. see \ref BUFFERS.
650<li> Create a buffer narray by calling \ref GIM_BUFFER_ARRAY_INIT_TYPE, \ref GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET or \ref GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE.
651<li> For accessing to the array elements, you must call \ref gim_buffer_array_lock, and then \ref gim_buffer_array_unlock for finish the access.
652<li> When a buffer array is no longer needed, you must free it by calling \ref GIM_BUFFER_ARRAY_DESTROY.
653</ul>
654The following example shows how Buffer arrays can be used:
655
656\code
657int main()
658{
659 //init gimpact
660 gimpact_init();
661
662 //Buffer handle to use
663 GBUFFER_ID bufferhandle;
664
665 //Create a memory buffer of 100 float numbers
666 gim_create_common_buffer(100*sizeof(float), &bufferhandle);
667
668 //Create a buffer array from the bufferhandle
669 GBUFFER_ARRAY buffer_float_array;
670 GIM_BUFFER_ARRAY_INIT_TYPE(float,buffer_float_array,bufferhandle,100);
671
672 ////Access to the buffer data, set all elements of the array
673
674 int i, count;
675 count = buffer_float_array.m_element_count;
676 //Locks the array
677 gim_buffer_array_lock(&buffer_float_array,G_MA_READ_WRITE);
678 float * pelements = GIM_BUFFER_ARRAY_POINTER(float, buffer_float_array, 0); // A pointer to the buffer memory
679
680 //fill the array with random numbers
681 for (i = 0;i < count;i++ )
682 {
683 pelements[i] = gim_unit_random();
684 }
685 //unlock buffer
686 gim_buffer_array_unlock(&buffer_float_array);
687
688 //Program code
689 ....
690 ....
691
692 //Destroy array
693 GIM_BUFFER_ARRAY_DESTROY(buffer_float_array);
694
695 //terminate gimpact
696 gimpact_terminate();
697}
698\endcode
699
700\sa BUFFERS
701*/
702//! @{
703
704//! Buffer managed array struct.
705struct GBUFFER_ARRAY
706{
707 GBUFFER_ID m_buffer_id;
708 char * m_buffer_data;
709 char m_byte_stride;
710 GUINT m_byte_offset;
711 GUINT m_element_count;
712};
713//typedef struct _GBUFFER_ARRAY GBUFFER_ARRAY;
714
715//! Sets offset for a buffered array.
716#define GIM_BUFFER_ARRAY_SET_OFFSET(_array_data,_offset) (_array_data).m_byte_offset = _offset*(_array_data).m_byte_stride;
717
718//! Sets offset for a buffered array.
719#define GIM_BUFFER_ARRAY_GET_OFFSET(_array_data,_offset) _offset = (_array_data).m_byte_offset/(_array_data).m_byte_stride;
720
721//!Return a pointer of the element at the _index
722#define GIM_BUFFER_ARRAY_POINTER(_type,_array_data,_index) (_type *)((_array_data).m_buffer_data + _index*(_array_data).m_byte_stride)
723
724//! Sets stride for a buffered array.
725#define GIM_BUFFER_ARRAY_SET_STRIDE(_type,_array_data) (_array_data).m_byte_stride = sizeof(_type);
726
727//! Is array stride equal to the size of the type ?
728#define GIM_BUFFER_ARRAY_IS_ALIGNED(_type,_array_data) ((_array_data).m_byte_stride == sizeof(_type))
729
730///Verify if two arrays have the same data
731#define GIM_BUFFER_ARRAY_ARE_SAME(_array_data1,_array_data2,aresame)\
732{\
733 aresame = 1;\
734 if((_array_data1).m_buffer_id.m_buffer_id != (_array_data2).m_buffer_id.m_buffer_id || (_array_data1).m_buffer_id.m_buffer_manager_id != (_array_data2).m_buffer_id.m_buffer_manager_id || (_array_data1).m_byte_offset != (_array_data2).m_byte_offset)\
735 {\
736 aresame = 0;\
737 }\
738}\
739
740//! Reserve size for a buffered array.
741/*!
742\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
743*/
744#define GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,reserve_size)\
745{ \
746 if(reserve_size>(array_data).m_element_count)\
747 {\
748 GUINT _buffer_size,_newarray_size;\
749 gim_get_buffer_size(&(array_data).m_buffer_id,_buffer_size);\
750 _newarray_size = reserve_size*(array_data).m_byte_stride;\
751 if(_newarray_size>_buffer_size)\
752 { \
753 _newarray_size += G_ARRAY_GROW_SIZE*(array_data).m_byte_stride;\
754 gim_buffer_realloc(&(array_data).m_buffer_id,_newarray_size);\
755 }\
756 }\
757}\
758
759//! Pushes an element at last position
760/*!
761\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
762*/
763#define GIM_BUFFER_ARRAY_PUSH_ITEM(type,array_data,item)\
764{\
765 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
766 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
767 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,(array_data).m_element_count);\
768 memcpy(_pt,&item,sizeof(type));\
769 gim_buffer_array_unlock(&array_data);\
770 (array_data)->m_element_count++; \
771}\
772
773//! Pushes a new element at last position
774/*!
775\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
776*/
777#define GIM_BUFFER_ARRAY_PUSH_EMPTY(type,array_data)\
778{\
779 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
780 array_data->m_element_count++; \
781}\
782
783//! Inserts an element
784/*!
785\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
786*/
787#define GIM_BUFFER_ARRAY_INSERT_ITEM(type,array_data,item,index) \
788{ \
789 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
790 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
791 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
792 if(index<(array_data)->m_element_count-1) \
793 { \
794 memcpy(&_pt[index+1],&_pt[index],((array_data).m_element_count-index)*sizeof(type));\
795 } \
796 memcpy(&_pt[index],&item,sizeof(type));\
797 gim_buffer_array_unlock(&array_data);\
798 (array_data).m_element_count++; \
799}\
800
801//! Deletes an element
802/*!
803\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
804*/
805#define GIM_BUFFER_ARRAY_DELETE_ITEM(type,array_data,index) \
806{ \
807 if(index<(array_data).m_element_count-1) \
808 { \
809 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
810 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
811 memcpy(&_pt[index],&_pt[index+1],((array_data).m_element_count-index-1)*sizeof(type));\
812 gim_buffer_array_unlock(&array_data);\
813 } \
814 (array_data).m_element_count--; \
815}\
816
817//! Deletes an element at last position
818/*!
819\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
820*/
821#define GIM_BUFFER_ARRAY_POP_ITEM(array_data) \
822{ \
823 if((array_data).m_element_count>0) \
824 { \
825 (array_data).m_element_count--; \
826 } \
827}\
828
829
830//! Initializes an GBUFFER_ARRAY object from a buffer ID
831/*!
832m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
833\param array_data Array structure to be filled
834\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
835\param element_count Number of elements
836\param offset element offset, it isn't byte offset. 0 is recomended
837\param byte_stride size of each element. 0 is recomended.
838\post Adds reference to the buffer
839\sa gim_buffer_add_ref
840*/
841#define GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE(array_data,buffer_id,element_count,offset,byte_stride)\
842{\
843 (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
844 (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
845 (array_data).m_buffer_data = 0;\
846 (array_data).m_element_count = element_count;\
847 (array_data).m_byte_stride = byte_stride;\
848 GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
849 gim_buffer_add_ref(&(buffer_id));\
850}\
851
852//! Initializes an GBUFFER_ARRAY object from a buffer ID and a Given type
853/*!
854m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
855\param type Type of the Array. It determines the stride.
856\param array_data Array structure to be filled
857\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
858\param element_count Number of elements
859\param offset element offset, it isn't byte offset. 0 is recomended
860\post Adds reference to the buffer
861\sa gim_buffer_add_ref
862*/
863#define GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type,array_data,buffer_id,element_count,offset)\
864{\
865 (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
866 (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
867 (array_data).m_buffer_data = 0;\
868 (array_data).m_element_count = element_count;\
869 GIM_BUFFER_ARRAY_SET_STRIDE(type,array_data);\
870 GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
871 gim_buffer_add_ref(&(buffer_id));\
872}\
873
874//! Initializes a buffer array giving a data type and a buffer id
875/*!
876m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array.
877\param type Type of the Array. It determines the stride.
878\param array_data Array structure to be filled
879\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
880\param element_count Number of elements
881\post Adds reference to the buffer
882\sa gim_buffer_add_ref
883*/
884#define GIM_BUFFER_ARRAY_INIT_TYPE(type,array_data,buffer_id,element_count) GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type,array_data,buffer_id,element_count,0)
885
886//! Gain access to the array buffer through the m_buffer_data element
887/*!
888m_buffer_data pointer will be located at the m_byte_offset position of the buffer m_buffer
889Then, You'd need to call unlock_array when finish to using the array access.
890
891\pre if m_buffer_data != 0, the function returns
892\param array_data Array structure to be locked
893\param access A constant for access to the buffer. can be G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE
894\return an Buffer error code
895*/
896GINT gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access);
897
898//! close the access to the array buffer through the m_buffer_data element
899/*!
900\param array_data Array structure to be locked
901\return an Buffer error code
902*/
903GINT gim_buffer_array_unlock(GBUFFER_ARRAY * array_data);
904
905//! Copy an array by reference
906/*!
907\post A reference to the m_buffer_id is increased.
908*/
909void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data);
910
911
912//! Copy an array by value
913/*!
914\post A new buffer is created
915*/
916void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data, GUINT buffer_manager_id,int usage);
917
918//! Destroys an GBUFFER_ARRAY object
919/*!
920\post Attemps to destroy the buffer, decreases reference counting
921*/
922void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data);
923
924//! Copy the content of the array to a pointer
925/*!
926\pre dest_data must have the same size as the array_data
927\param type
928\param array_data A GBUFFERED_ARRAY structure
929\param dest_data A type pointer
930*/
931#define GIM_BUFFER_ARRAY_DOWNLOAD(type,array_data,dest_data)\
932{\
933 if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
934 {\
935 gim_download_from_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset,(void *) dest_data, (array_data).m_element_count*(array_data).m_byte_stride);\
936 }\
937 else\
938 {\
939 GUINT _k_, _ecount_= (array_data).m_element_count;\
940 type * _source_vert_;\
941 type * _dest_vert_ = dest_data;\
942 gim_buffer_array_lock(&(array_data),G_MA_READ_ONLY);\
943 for (_k_ = 0;_k_< _ecount_; _k_++)\
944 {\
945 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
946 memcpy(_dest_vert_,_source_vert_,sizeof(type));\
947 _dest_vert_++;\
948 }\
949 gim_buffer_array_unlock(&(array_data));\
950 }\
951}\
952
953//! Upload the content of a a pointer to a buffered array
954/*!
955\pre source_data must have the same size as the array_data
956\param type
957\param array_data A GBUFFERED_ARRAY structure
958\param source_data A void pointer
959*/
960#define GIM_BUFFER_ARRAY_UPLOAD(type,array_data,source_data)\
961{\
962 if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
963 {\
964 gim_upload_to_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset,(void *) source_data, (array_data).m_element_count*(array_data).m_byte_stride);\
965 }\
966 else\
967 {\
968 GUINT _k_, _ecount_= (array_data).m_element_count;\
969 type * _source_vert_ = source_data;\
970 type * _dest_vert_;\
971 gim_buffer_array_lock(&(array_data),G_MA_WRITE_ONLY);\
972 for (_k_ = 0;_k_< _ecount_; _k_++)\
973 {\
974 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
975 memcpy(_dest_vert_,_source_vert_,sizeof(type));\
976 _source_vert_++;\
977 }\
978 gim_buffer_array_unlock(&(array_data));\
979 }\
980}\
981
982
983//!Kernel function prototype for process streams, given a buffered array as source and
984/*!
985\param 1 the uniform arguments
986\param 2 the source stream
987\param 3 the destination stream
988*/
989typedef void (* gim_kernel_func)(void *,GBUFFER_ARRAY *,GBUFFER_ARRAY *);
990
991//! Generic Stream Processingp loop
992/*!
993
994This macro executes a kernel macro or function for each element of the streams
995\pre _src_array->m_count <= _dst_array->m_count
996
997\param _uniform_data An argument to be passed to the Kernel function
998\param _src_array An GBUFFER_ARRAY structure passed as the source stream
999\param _dst_array An GBUFFER_ARRAY structure passed as the source stream
1000\param _kernel Macro or function of the kernel
1001\param _src_type Required. Type of all elements of the source stream
1002\param _dst_type Required. Type of all elements of the dest stream
1003*/
1004#define GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,_src_type,_dst_type) {\
1005\
1006 gim_buffer_array_lock(&_src_array,G_MA_READ_ONLY);\
1007 gim_buffer_array_lock(&_dst_array,G_MA_WRITE_ONLY);\
1008\
1009 GUINT _i_, _count_=(_src_array).m_element_count;\
1010\
1011 _src_type * _source_vert_;\
1012 _dst_type * _dest_vert_;\
1013 if(GIM_BUFFER_ARRAY_IS_ALIGNED(_src_type,_src_array) && GIM_BUFFER_ARRAY_IS_ALIGNED(_dst_type,_dst_array))\
1014 {\
1015\
1016 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,0);\
1017 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,0);\
1018 for (_i_ = 0;_i_< _count_; _i_++)\
1019 {\
1020 _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
1021 _source_vert_++;\
1022 _dest_vert_++;\
1023 }\
1024 }\
1025 else\
1026 {\
1027 for (_i_ = 0;_i_< _count_; _i_++)\
1028 {\
1029 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,_i_);\
1030 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,_i_);\
1031 _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
1032 }\
1033 }\
1034 gim_buffer_array_unlock(&_src_array);\
1035 gim_buffer_array_unlock(&_dst_array);\
1036}\
1037
1038//! @}
1039
1040#endif // GIM_MEMORY_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h
new file mode 100644
index 0000000..a5f8e12
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h
@@ -0,0 +1,258 @@
1#ifndef GIM_RADIXSORT_H_INCLUDED
2#define GIM_RADIXSORT_H_INCLUDED
3/*! \file gim_radixsort.h
4\author Francisco León.
5Based on the work of Michael Herf : "fast floating-point radix sort"
6Avaliable on http://www.stereopsis.com/radix.html
7*/
8/*
9-----------------------------------------------------------------------------
10This source file is part of GIMPACT Library.
11
12For the latest info, see http://gimpact.sourceforge.net/
13
14Copyright (c) 2006 Francisco Leon. C.C. 80087371.
15email: projectileman@yahoo.com
16
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of EITHER:
19 (1) The GNU Lesser General Public License as published by the Free
20 Software Foundation; either version 2.1 of the License, or (at
21 your option) any later version. The text of the GNU Lesser
22 General Public License is included with this library in the
23 file GIMPACT-LICENSE-LGPL.TXT.
24 (2) The BSD-style license that is included with this library in
25 the file GIMPACT-LICENSE-BSD.TXT.
26
27 This library is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
30 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
31
32-----------------------------------------------------------------------------
33*/
34
35#include "GIMPACT/gim_memory.h"
36
37/*! \defgroup SORTING
38\brief
39Macros for sorting.
40*/
41//! @{
42struct GIM_RSORT_TOKEN
43{
44 GUINT m_key;
45 GUINT m_value;
46};
47//typedef struct _GIM_RSORT_TOKEN GIM_RSORT_TOKEN;
48
49//comparator for sorting
50#define RSORT_TOKEN_COMPARATOR(x, y) ((int)((x.m_key) - (y.m_key)))
51
52// ---- utils for accessing 11-bit quantities
53#define D11_0(x) (x & 0x7FF)
54#define D11_1(x) (x >> 11 & 0x7FF)
55#define D11_2(x) (x >> 22 )
56
57
58//COMMON FUNCTIONS FOR ACCESSING THE KEY OF AN ELEMENT
59
60
61//For the type of your array, you need to declare a macro for obtaining the key, like these:
62#define SIMPLE_GET_FLOAT32KEY(e,key) {key =(GREAL)(e);}
63
64#define SIMPLE_GET_INTKEY(e,key) {key =(GINT)(e);}
65
66#define SIMPLE_GET_UINTKEY(e,key) {key =(GUINT)(e);}
67
68//For the type of your array, you need to declare a macro for copy elements, like this:
69
70#define SIMPLE_COPY_ELEMENTS(dest,src) {dest = src;}
71
72#define kHist 2048
73
74///Radix sort for unsigned integer keys
75
76#define GIM_RADIX_SORT_RTOKENS(array,sorted,element_count)\
77{\
78 GUINT i;\
79 GUINT b0[kHist * 3];\
80 GUINT *b1 = b0 + kHist;\
81 GUINT *b2 = b1 + kHist;\
82 for (i = 0; i < kHist * 3; i++)\
83 {\
84 b0[i] = 0;\
85 }\
86 GUINT fi;\
87 GUINT pos;\
88 for (i = 0; i < element_count; i++)\
89 {\
90 fi = array[i].m_key;\
91 b0[D11_0(fi)] ++;\
92 b1[D11_1(fi)] ++;\
93 b2[D11_2(fi)] ++;\
94 }\
95 {\
96 GUINT sum0 = 0, sum1 = 0, sum2 = 0;\
97 GUINT tsum;\
98 for (i = 0; i < kHist; i++)\
99 {\
100 tsum = b0[i] + sum0;\
101 b0[i] = sum0 - 1;\
102 sum0 = tsum;\
103 tsum = b1[i] + sum1;\
104 b1[i] = sum1 - 1;\
105 sum1 = tsum;\
106 tsum = b2[i] + sum2;\
107 b2[i] = sum2 - 1;\
108 sum2 = tsum;\
109 }\
110 }\
111 for (i = 0; i < element_count; i++)\
112 {\
113 fi = array[i].m_key;\
114 pos = D11_0(fi);\
115 pos = ++b0[pos];\
116 sorted[pos].m_key = array[i].m_key;\
117 sorted[pos].m_value = array[i].m_value;\
118 }\
119 for (i = 0; i < element_count; i++)\
120 {\
121 fi = sorted[i].m_key;\
122 pos = D11_1(fi);\
123 pos = ++b1[pos];\
124 array[pos].m_key = sorted[i].m_key;\
125 array[pos].m_value = sorted[i].m_value;\
126 }\
127 for (i = 0; i < element_count; i++)\
128 {\
129 fi = array[i].m_key;\
130 pos = D11_2(fi);\
131 pos = ++b2[pos];\
132 sorted[pos].m_key = array[i].m_key;\
133 sorted[pos].m_value = array[i].m_value;\
134 }\
135}\
136
137/// Get the sorted tokens from an array. For generic use. Tokens are GIM_RSORT_TOKEN
138#define GIM_RADIX_SORT_ARRAY_TOKENS(array, sorted_tokens, element_count, get_uintkey_macro)\
139{\
140 GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
141 GUINT _i;\
142 for (_i=0;_i<element_count;_i++)\
143 {\
144 get_uintkey_macro(array[_i],_unsorted[_i].m_key);\
145 _unsorted[_i].m_value = _i;\
146 }\
147 GIM_RADIX_SORT_RTOKENS(_unsorted,sorted_tokens,element_count);\
148 gim_free(_unsorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
149}\
150
151/// Sorts array in place. For generic use
152#define GIM_RADIX_SORT(type,array,element_count,get_uintkey_macro,copy_elements_macro)\
153{\
154 GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
155 GIM_RADIX_SORT_ARRAY_TOKENS(array,_sorted,element_count,get_uintkey_macro);\
156 type * _original_array = (type *) gim_alloc(sizeof(type)*element_count); \
157 memcpy(_original_array,array,sizeof(type)*element_count);\
158 GUINT _i;\
159 for (_i=0;_i<element_count;_i++)\
160 {\
161 copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);\
162 }\
163 gim_free(_original_array,sizeof(type)*element_count);\
164 gim_free(_sorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
165}\
166
167/// Sorts array in place using quick sort
168#define GIM_QUICK_SORT_ARRAY(type, array, array_count, comp_macro, exchange_macro) \
169{\
170 GINT _i_, _j_, _p_, _stack_index_, _start_, _end_;\
171 GINT _start_stack_[64]; \
172 GINT _end_stack_[64];\
173 _start_stack_[0] = 0;\
174 _end_stack_[0] = (array_count);\
175 _stack_index_ = 1;\
176 while (_stack_index_ > 0)\
177 {\
178 _stack_index_ --;\
179 _start_ = _start_stack_[_stack_index_];\
180 _end_ = _end_stack_[_stack_index_];\
181 while (_end_ - _start_ > 2)\
182 {\
183 _p_ = _start_;\
184 _i_ = _start_ + 1;\
185 _j_ = _end_ - 1;\
186 while (_i_<_j_) \
187 {\
188 for(; _i_<=_j_ && comp_macro(((array)[_i_]),((array)[_p_]))<=0; _i_++) ;\
189 if (_i_ > _j_) \
190 {\
191 exchange_macro(type, array, _j_, _p_);\
192 _i_ = _j_;\
193 }\
194 else\
195 {\
196 for(; _i_<=_j_ && comp_macro(((array)[_j_]),((array)[_p_]))>=0; _j_--) ;\
197 if (_i_ > _j_) \
198 {\
199 exchange_macro(type, array, _j_, _p_);\
200 _i_ = _j_;\
201 }\
202 else if (_i_ < _j_)\
203 {\
204 exchange_macro(type, array, _i_, _j_);\
205 if (_i_+2 < _j_) {_i_++; _j_--;}\
206 else if (_i_+1 < _j_) _i_++;\
207 }\
208 }\
209 }\
210 if (_i_-_start_ > 1 && _end_-_j_ > 1) \
211 {\
212 if (_i_-_start_ < _end_-_j_-1) \
213 {\
214 _start_stack_[_stack_index_] = _j_+1;\
215 _end_stack_[_stack_index_] = _end_;\
216 _stack_index_ ++;\
217 _end_ = _i_;\
218 }\
219 else\
220 {\
221 _start_stack_[_stack_index_] = _start_;\
222 _end_stack_[_stack_index_] = _i_;\
223 _stack_index_ ++;\
224 _start_ = _j_+1;\
225 }\
226 }\
227 else\
228 {\
229 if (_i_-_start_ > 1)\
230 {\
231 _end_ = _i_;\
232 }\
233 else \
234 {\
235 _start_ = _j_+1;\
236 }\
237 }\
238 }\
239 if (_end_ - _start_ == 2) \
240 {\
241 if (comp_macro(((array)[_start_]),((array)[_end_-1])) > 0) \
242 {\
243 exchange_macro(type, array, _start_, _end_-1);\
244 }\
245 }\
246 }\
247}\
248
249#define GIM_DEF_EXCHANGE_MACRO(type, _array, _i, _j)\
250{\
251 type _e_tmp_ =(_array)[(_i)];\
252 (_array)[(_i)]=(_array)[(_j)];\
253 (_array)[(_j)]= _e_tmp_;\
254}\
255
256#define GIM_COMP_MACRO(x, y) ((GINT)((x) - (y)))
257//! @}
258#endif // GIM_RADIXSORT_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h
new file mode 100644
index 0000000..2b31604
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h
@@ -0,0 +1,111 @@
1#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
2#define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
3
4/*! \file gim_tri_capsule_collision.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34#include "GIMPACT/gim_memory.h"
35
36/*! \addtogroup GEOMETRIC_OPERATIONS
37*/
38//! @{
39
40//! Capsule struct
41struct GIM_CAPSULE_DATA
42{
43 GREAL m_radius;
44 vec3f m_point1;
45 vec3f m_point2;
46};
47//typedef struct _GIM_CAPSULE_DATA GIM_CAPSULE_DATA;
48
49#define CALC_CAPSULE_AABB(capsule,aabb)\
50{\
51 if(capsule.m_point1[0]<capsule.m_point2[0])\
52 {\
53 aabb.minX = capsule.m_point1[0] - capsule.m_radius;\
54 aabb.maxX = capsule.m_point2[0] + capsule.m_radius;\
55 }\
56 else\
57 {\
58 aabb.minX = capsule.m_point2[0] - capsule.m_radius;\
59 aabb.maxX = capsule.m_point1[0] + capsule.m_radius;\
60 }\
61 if(capsule.m_point1[1]<capsule.m_point2[1])\
62 {\
63 aabb.minY = capsule.m_point1[1] - capsule.m_radius;\
64 aabb.maxY = capsule.m_point2[1] + capsule.m_radius;\
65 }\
66 else\
67 {\
68 aabb.minY = capsule.m_point2[1] - capsule.m_radius;\
69 aabb.maxY = capsule.m_point1[1] + capsule.m_radius;\
70 }\
71 if(capsule.m_point1[2]<capsule.m_point2[2])\
72 {\
73 aabb.minZ = capsule.m_point1[2] - capsule.m_radius;\
74 aabb.maxZ = capsule.m_point2[2] + capsule.m_radius;\
75 }\
76 else\
77 {\
78 aabb.minZ = capsule.m_point2[2] - capsule.m_radius;\
79 aabb.maxZ = capsule.m_point1[2] + capsule.m_radius;\
80 }\
81}\
82
83//! Utility function for find the closest point between a segment and a triangle
84/*!
85
86\param triangle
87\param s1
88\param s2
89\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
90
91\post The contacts array is not set to 0. It adds aditional contacts
92*/
93void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts);
94
95
96
97
98
99//! Utility function for find the closest point between a capsule and a triangle
100/*!
101
102\param triangle
103\param capsule
104\param contacts Contains the closest points on the capsule, and the normal points to triangle
105\return 1 if the triangle collides the capsule
106\post The contacts array is not set to 0. It adds aditional contacts
107*/
108int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
109//! @}
110
111#endif // GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_collision.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_collision.h
new file mode 100644
index 0000000..80b34eb
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_collision.h
@@ -0,0 +1,253 @@
1#ifndef GIM_TRI_COLLISION_H_INCLUDED
2#define GIM_TRI_COLLISION_H_INCLUDED
3
4/*! \file gim_tri_collision.h
5\author Francisco León Nájera
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34/*! \addtogroup GEOMETRIC_OPERATIONS
35*/
36//! @{
37
38
39#define MAX_TRI_CLIPPING 8
40
41//! Clips a polygon by a plane
42#define PLANE_CLIP_POLYGON(plane,polygon_points,polygon_point_count,clipped,clipped_count,max_clipped) \
43{ \
44 clipped_count = 0; \
45 GUINT _i, _vi, _prevclassif=32000, _classif; \
46 GREAL _d; \
47 for(_i=0;_i<=polygon_point_count;_i++) \
48 { \
49 _vi = _i%polygon_point_count; \
50 _d = DISTANCE_PLANE_POINT(plane,polygon_points[_vi]); \
51 _classif = _d>G_EPSILON ?1:0; \
52 if(_classif == 0) \
53 { \
54 if(_prevclassif==1) \
55 {\
56 if(clipped_count<max_clipped) \
57 {\
58 PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
59 clipped_count++; \
60 } \
61 } \
62 if(clipped_count<max_clipped&&_i<polygon_point_count) \
63 { \
64 VEC_COPY(clipped[clipped_count],polygon_points[_vi]); \
65 clipped_count++; \
66 } \
67 } \
68 else \
69 { \
70 if(_prevclassif==0) \
71 { \
72 if(clipped_count<max_clipped) \
73 { \
74 PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
75 clipped_count++; \
76 } \
77 } \
78 } \
79 _prevclassif = _classif; \
80 } \
81}\
82
83
84struct GIM_TRIPLANES_CACHE
85{
86 /*!
87 Planes are:
88 0 : Face normal plane (0,3)
89 1 : Edge 1 plane (4,7)
90 2 : Edge 2 plane (8,11)
91 3 : Edge 3 plane (12,15)
92 */
93 vec4f m_planes[4];
94};
95//typedef struct _GIM_TRIPLANES_CACHE GIM_TRIPLANES_CACHE;
96
97
98struct GIM_TRIANGLE_DATA
99{
100 vec3f m_vertices[3];
101 GIM_TRIPLANES_CACHE m_planes;
102};
103//typedef struct _GIM_TRIANGLE_DATA GIM_TRIANGLE_DATA;
104
105//! tri_data is a GIM_TRIANGLE_DATA
106#define GIM_CALC_TRIANGLE_DATA_PLANES(tri_data)\
107{\
108 TRIANGLE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],(tri_data).m_vertices[2],(tri_data).m_planes.m_planes[0]);\
109 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]));\
110 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]));\
111 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]));\
112}\
113
114//Structure for collision
115
116struct GIM_TRIANGLE_CONTACT_DATA
117{
118 GREAL m_penetration_depth;
119 GUINT m_point_count;
120 vec3f m_separating_normal;
121 vec3f m_points[MAX_TRI_CLIPPING];
122};
123//typedef struct _GIM_TRIANGLE_CONTACT_DATA GIM_TRIANGLE_CONTACT_DATA;
124
125struct GIM_TRIANGLE_RAY_CONTACT_DATA
126{
127 GREAL u;
128 GREAL v;
129 GREAL tparam;
130 GUINT m_face_id;
131 vec3f m_point;
132 vec3f m_normal;
133};
134//typedef struct _GIM_TRIANGLE_RAY_CONTACT_DATA GIM_TRIANGLE_RAY_CONTACT_DATA;
135
136//! Fast Triangle Triangle overlapping test
137int gim_triangle_triangle_overlap(
138 GIM_TRIANGLE_DATA *tri1,
139 GIM_TRIANGLE_DATA *tri2);
140
141
142//! Fast but inacurate conservative Triangle Triangle overlapping test
143int gim_triangle_triangle_overlap_fast(
144 GIM_TRIANGLE_DATA *tri1,
145 GIM_TRIANGLE_DATA *tri2);
146
147
148//! Finds the contact points from a collision of two triangles
149/*!
150Returns the contact points, the penetration depth and the separating normal of the collision
151between two triangles. The normal is pointing toward triangle 1 from triangle 2
152*/
153int gim_triangle_triangle_collision(
154 GIM_TRIANGLE_DATA *tri1,
155 GIM_TRIANGLE_DATA *tri2,
156 GIM_TRIANGLE_CONTACT_DATA * contact_data);
157
158//Ray triangle
159
160
161/*!
162 Solve the System for u,v parameters:
163
164 u*axe1[i1] + v*axe2[i1] = vecproj[i1]
165 u*axe1[i2] + v*axe2[i2] = vecproj[i2]
166
167 sustitute:
168 v = (vecproj[i2] - u*axe1[i2])/axe2[i2]
169
170 then the first equation in terms of 'u':
171
172 --> u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1]
173
174 --> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1]
175
176 --> u*(axe1[i1] - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2]
177
178 --> u*((axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2]
179
180 --> u*(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]
181
182 --> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])
183
184if 0.0<= u+v <=1.0 then they are inside of triangle
185
186 */
187#define TRIANGLE_GET_UVPARAMETERS(point,vec1,vec2,vec3,tri_plane,u,v,outside)\
188{\
189 vec3f _axe1, _axe2, _vecproj;\
190 VEC_DIFF(_axe1,vec2,vec1);\
191 VEC_DIFF(_axe2,vec3,vec1);\
192 VEC_DIFF(_vecproj,point,vec1);\
193 GUINT _i1,_i2;\
194 PLANE_MINOR_AXES(tri_plane, _i1, _i2);\
195 if(fabsf(_axe2[_i2])<G_EPSILON)\
196 {\
197 u = (_vecproj[_i2]*_axe2[_i1] - _vecproj[_i1]*_axe2[_i2]) /(_axe1[_i2]*_axe2[_i1] - _axe1[_i1]*_axe2[_i2]);\
198 v = (_vecproj[_i1] - u*_axe1[_i1])/_axe2[_i1];\
199 }\
200 else\
201 {\
202 u = (_vecproj[_i1]*_axe2[_i2] - _vecproj[_i2]*_axe2[_i1]) /(_axe1[_i1]*_axe2[_i2] - _axe1[_i2]*_axe2[_i1]);\
203 v = (_vecproj[_i2] - u*_axe1[_i2])/_axe2[_i2];\
204 }\
205 if(u<-G_EPSILON)\
206 {\
207 outside = 1;\
208 }\
209 else if(v<-G_EPSILON)\
210 {\
211 outside = 1;\
212 }\
213 else\
214 {\
215 float sumuv;\
216 sumuv = u+v;\
217 if(sumuv<-G_EPSILON)\
218 {\
219 outside = 1;\
220 }\
221 else if(sumuv-1.0f>G_EPSILON)\
222 {\
223 outside = 1;\
224 }\
225 else\
226 {\
227 outside = 0;\
228 }\
229 }\
230}\
231
232//! Finds the collision of a ray and a triangle.
233#define RAY_TRIANGLE_INTERSECTION(vOrigin,vDir,vec1,vec2,vec3,tri_plane,pout,u,v,tparam,tmax,does_intersect)\
234{\
235 RAY_PLANE_COLLISION(tri_plane,vDir,vOrigin,pout,tparam,does_intersect);\
236 if(does_intersect != 0)\
237 {\
238 if(tparam<-G_EPSILON||tparam>tmax+G_EPSILON)\
239 {\
240 does_intersect = 0;\
241 }\
242 else\
243 {\
244 TRIANGLE_GET_UVPARAMETERS(pout,vec1,vec2,vec3,tri_plane,u,v,does_intersect);\
245 does_intersect = !does_intersect;\
246 }\
247 }\
248}\
249
250
251//! @}
252
253#endif // GIM_TRI_COLLISION_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h
new file mode 100644
index 0000000..a2a81d6
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h
@@ -0,0 +1,51 @@
1#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED
2#define GIM_TRI_SPHERE_COLLISION_H_INCLUDED
3
4/*! \file gim_tri_sphere_collision.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34/*! \addtogroup GEOMETRIC_OPERATIONS
35*/
36//! @{
37
38//! Finds the contact points from a collision of a triangle and a sphere
39/*!
40\param tri
41\param center
42\param radius
43\param contact_data Contains the closest points on the Sphere, and the normal is pointing to triangle
44*/
45int gim_triangle_sphere_collision(
46 GIM_TRIANGLE_DATA *tri,
47 vec3f center, GREAL radius,
48 GIM_TRIANGLE_CONTACT_DATA * contact_data);
49
50//! @}
51#endif // GIM_TRI_SPHERE_COLLISION_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h
new file mode 100644
index 0000000..b1cdf7f
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h
@@ -0,0 +1,539 @@
1#ifndef GIM_TRIMESH_H_INCLUDED
2#define GIM_TRIMESH_H_INCLUDED
3/*! \file gim_trimesh.h
4\author Francisco León
5*/
6/*
7-----------------------------------------------------------------------------
8This source file is part of GIMPACT Library.
9
10For the latest info, see http://gimpact.sourceforge.net/
11
12Copyright (c) 2006 Francisco Leon. C.C. 80087371.
13email: projectileman@yahoo.com
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of EITHER:
17 (1) The GNU Lesser General Public License as published by the Free
18 Software Foundation; either version 2.1 of the License, or (at
19 your option) any later version. The text of the GNU Lesser
20 General Public License is included with this library in the
21 file GIMPACT-LICENSE-LGPL.TXT.
22 (2) The BSD-style license that is included with this library in
23 the file GIMPACT-LICENSE-BSD.TXT.
24
25 This library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
28 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
29
30-----------------------------------------------------------------------------
31*/
32
33#include "GIMPACT/gim_boxpruning.h"
34#include "GIMPACT/gim_contact.h"
35
36
37///MAsk defines
38#define GIM_TRIMESH_TRANSFORMED_REPLY 1
39#define GIM_TRIMESH_NEED_UPDATE 2
40
41/*! \addtogroup TRIMESH
42\brief
43A Trimesh is the basic geometric structure for representing solid objects.
44<p><strong>CREATING TRIMESHES</strong></p>
45<ul>
46<li> For creating trimeshes, you must initialize Buffer managers by calling \ref gimpact_init
47<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.
48<li> An alternative way for creaing trimesh objects is calling \ref gim_trimesh_create_from_data.
49<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.
50<li> Each time when the trimesh data is modified, you must call \ref gim_trimesh_update after.
51<li> When a trimesh is no longer needed, you must call \ref gim_trimesh_destroy.
52</ul>
53
54<p>This is an example of how to create a deformable trimesh that shares vertices with the user application:</p>
55\code
56//Declaration of vertices
57vec3f trimeshvertices[200];
58//Declaration of indices
59GUINT trimeshindices[100];
60
61... Initializing vertices and triangle indices at beginning
62
63//Then create trimesh
64GIM_TRIMESH mytrimesh;
65
66//Calling trimesh create function
67
68gim_trimesh_create_from_data(
69&mytrimesh,
70trimeshvertices,200,
710 ,//copy_vertices is 0
72trimeshindices,
73100,
740, //copy_indices is 0
750 //transformed_reply is 0
76);
77\endcode
78<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>
79<p>When the trimesh is no longer needed, destroy it safely with gim_trimesh_destroy()</p>
80<p><strong>UPDATING TRIMESHES</strong></p>
81<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>
82<ul>
83<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.
84\code
85// Access to the source vertices
86gim_buffer_array_lock(&mytrimesh.m_source_vertex_buffer, G_MA_READ_WRITE);
87
88//Get a pointer to the vertex buffer
89vec3f * vertexpointer = GIM_BUFFER_ARRAY_POINTER(vec3f,mytrimesh.m_source_vertex_buffer,0);
90
91//Get the amount of vertices
92int veccount = mytrimesh.m_source_vertex_buffer.m_element_count;
93
94//Modify vertices
95for (int i=0;i<veccount ;i++ )
96{
97 .....
98 .....
99 processing vertices
100 .....
101 .....
102}
103
104// Don't forget to unlock the source vertex array
105gim_buffer_array_unlock(&mytrimesh.m_source_vertex_buffer);
106
107// Notify that the state of the trimesh is changed
108gim_trimesh_post_update(&mytrimesh.m_source_vertex_buffer);
109
110\endcode
111For making trimeshes that allow to update their vertices, use \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 0.
112</ul>
113<ul>
114<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.
115</ul>
116<p> After updating vertices, you must call \ref gim_trimesh_update()</p>
117<p><strong>TRIMESHES COLLISION</strong></p>
118<p>Before collide trimeshes, you need to update them first.</p>
119<p>Then you must use \ref gim_trimesh_trimesh_collision().</p>
120
121*/
122//! @{
123
124//! Prototype for updating vertices
125typedef void * gim_update_trimesh_function(struct _GIM_TRIMESH *);
126
127//! Trimesh
128struct GIM_TRIMESH
129{
130 ///Original
131 //@{
132 GBUFFER_ARRAY m_source_vertex_buffer;//!< Buffer of vec3f coordinates
133
134 //! (GUINT) Indices of triangles,groups of three elements.
135 /*!
136 Array of GUINT. Triangle indices. Each triple contains indices of the vertices for each triangle.
137 \invariant must be aligned
138 */
139 GBUFFER_ARRAY m_tri_index_buffer;
140 //@}
141 ///Allocated
142 //@{
143 char m_mask;//!< Don't use directly
144
145 //! Allocated transformed vertices vec3f
146 /*!
147 Array of vec3f.If gim_trimesh_has_tranformed_reply(this) == 1 then it refers to the m_source_vertex_buffer
148 \invariant must be aligned
149 */
150 GBUFFER_ARRAY m_transformed_vertex_buffer;
151 //@}
152 ///Auxiliary data
153 //@{
154 GIM_AABB_SET m_aabbset;
155 GDYNAMIC_ARRAY m_planes_cache_buffer;//! Allocated GIM_TRIPLANES_CACHE
156 GDYNAMIC_ARRAY m_planes_cache_bitset;
157 gim_update_trimesh_function * m_update_callback;//! If null, then m_transform is applied.
158 mat4f m_transform;
159 //@}
160};
161//typedef struct _GIM_TRIMESH GIM_TRIMESH;
162
163/// Info about mesh
164//! Return the trimesh triangle count
165GUINT gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh);
166
167//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
168char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh);
169
170//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
171char gim_trimesh_needs_update(GIM_TRIMESH * trimesh);
172
173//! Change the state of the trimesh for force it to update
174/*!
175Call it after made changes to the trimesh.
176\post gim_trimesh_need_update(trimesh) will return 1
177\sa gim_trimesh_needs_update,gim_trimesh_has_tranformed_reply
178*/
179void gim_trimesh_post_update(GIM_TRIMESH * trimesh);
180
181//! Creates the aabb set and the triangles cache
182/*!
183
184\param trimesh
185\param vertex_array
186\param triindex_array
187\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
188\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
189*/
190void gim_trimesh_create_from_arrays(GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply);
191
192
193
194//! Create a trimesh from vertex array and an index array
195/*!
196\param trimesh An uninitialized GIM_TRIMESH structure
197\param vertex_array A buffer to a vec3f array
198\param vertex_count
199\param triindex_array
200\param index_count
201\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
202\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
203\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array. Use 1 if you will apply transformations to the trimesh. See \ref gim_trimesh_set_tranform().
204*/
205void gim_trimesh_create_from_data(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT index_count,char copy_indices,char transformed_reply);
206
207//! Clears auxiliary data and releases buffer arrays
208void gim_trimesh_destroy(GIM_TRIMESH * trimesh);
209
210//! Copies two meshes
211/*!
212\param source_trimesh
213\param dest_trimesh
214\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
215\param transformed_reply If 1, transformed vertices are reply of source vertives. 1 Is recommended
216*/
217void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,GIM_TRIMESH * dest_trimesh, char copy_by_reference, char transformed_reply);
218
219
220//! Locks the trimesh for working with it
221/*!
222\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
223\param trimesh
224*/
225void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh);
226
227
228//! unlocks the trimesh
229/*!
230\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
231\param trimesh
232*/
233void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh);
234
235//! Updates m_transformed_vertex_buffer
236/*!
237\pre m_transformed_vertex_buffer must be unlocked
238*/
239void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh);
240
241//! Updates m_aabbset and m_planes_cache_bitset
242/*!
243\pre gim_trimesh_locks_work_data must be called before
244*/
245void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh);
246
247//! Calls before perfom collisions. Updates the trimesh if needed
248/*!
249\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
250*/
251void gim_trimesh_update(GIM_TRIMESH * trimesh);
252
253//! Set the transform of a trimesh
254/*!
255\post This function calls to gim_trimesh_post_update
256*/
257void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform);
258
259//! Fetch triangle data
260/*!
261\pre gim_trimesh_locks_work_data must be called before
262*/
263void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data);
264
265//! Fetch triangle vertices
266/*!
267\pre gim_trimesh_locks_work_data must be called before
268*/
269void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3);
270
271//! Trimesh Trimesh Collisions
272/*!
273Before use this function you must update each trimesh:
274\code
275gim_trimesh_update(TriMesh1);
276gim_trimesh_update(TriMesh2);
277\endcode
278Then you must use the trimesh collision in this way:
279\code
280int collide_trimeshes(GIM_TRIMESH * TriMesh1, GIM_TRIMESH * TriMesh2)
281{
282 //Create contact list
283 GDYNAMIC_ARRAY trimeshcontacts;
284 GIM_CREATE_CONTACT_LIST(trimeshcontacts);
285
286 //Collide trimeshes
287 gim_trimesh_trimesh_collision(TriMesh1,TriMesh2,&trimeshcontacts);
288
289 if(trimeshcontacts.m_size == 0) //do nothing
290 {
291 GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
292 return 0;
293 }
294
295 //Getting a pointer to the contact array
296 GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
297
298 int contactcount = trimeshcontacts.m_size;
299 int i;
300 //Process contacts
301 for (i=0;i<contactcount ;i++)
302 {
303 //Do something with the contact (ptrimeshcontacts)
304 ......
305 ......
306 // Like creating joints or anything else
307 ......
308 ......
309 ptrimeshcontacts++;
310 }
311 GIM_DYNARRAY_DESTROY(trimeshcontacts);
312 return contactcount;
313}
314\endcode
315In each contact
316<ul>
317<li> m_handle1 points to trimesh1.
318<li> m_handle2 points to trimesh2.
319<li> m_feature1 Is a triangle index of trimesh1.
320<li> m_feature2 Is a triangle index of trimesh2.
321</ul>
322
323\param trimesh1 Collider
324\param trimesh2 Collidee
325\param contacts A GIM_CONTACT array. Must be initialized
326*/
327void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts);
328
329
330//! Trimesh Sphere Collisions
331/*!
332Before use this function you must update the trimesh:
333\code
334gim_trimesh_update(trimesh);
335\endcode
336Then you must use this function in this way:
337\code
338int collide_trimesh_sphere(GIM_TRIMESH * trimesh, vec3f center,GREAL radius)
339{
340 //Create contact list
341 GDYNAMIC_ARRAY trimeshcontacts;
342 GIM_CREATE_CONTACT_LIST(trimeshcontacts);
343
344 //Collide trimeshes
345 gim_trimesh_sphere_collision(trimesh,center,radius,&trimeshcontacts);
346
347 if(trimeshcontacts.m_size == 0) //do nothing
348 {
349 GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
350 return 0;
351 }
352
353 //Getting a pointer to the contact array
354 GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
355
356 int contactcount = trimeshcontacts.m_size;
357 int i;
358 //Process contacts
359 for (i=0;i<contactcount ;i++)
360 {
361 //Do something with the contact (ptrimeshcontacts)
362 ......
363 ......
364 // Like creating joints or anything else
365 ......
366 ......
367 ptrimeshcontacts++;
368 }
369 GIM_DYNARRAY_DESTROY(trimeshcontacts);
370 return contactcount;
371}
372\endcode
373
374In each contact
375<ul>
376<li> m_handle1 points to trimesh.
377<li> m_handle2 points to NULL.
378<li> m_feature1 Is a triangle index of trimesh.
379</ul>
380
381\param trimesh
382\param center
383\param radius
384\param contacts A GIM_CONTACT array. Must be initialized
385*/
386void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts);
387
388
389//! Trimesh Capsule collision
390/*!
391Find the closest primitive collided by the ray.
392
393Before use this function you must update the trimesh:
394\code
395gim_trimesh_update(trimesh);
396\endcode
397Then you must use this function in this way:
398\code
399int collide_trimesh_capsule(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule)
400{
401 //Create contact list
402 GDYNAMIC_ARRAY trimeshcontacts;
403 GIM_CREATE_CONTACT_LIST(trimeshcontacts);
404
405 //Collide trimeshes
406 gim_trimesh_capsule_collision(trimesh,capsule,&trimeshcontacts);
407
408 if(trimeshcontacts.m_size == 0) //do nothing
409 {
410 GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
411 return 0;
412 }
413
414 //Getting a pointer to the contact array
415 GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
416
417 int contactcount = trimeshcontacts.m_size;
418 int i;
419 //Process contacts
420 for (i=0;i<contactcount ;i++)
421 {
422 //Do something with the contact (ptrimeshcontacts)
423 ......
424 ......
425 // Like creating joints or anything else
426 ......
427 ......
428 ptrimeshcontacts++;
429 }
430 GIM_DYNARRAY_DESTROY(trimeshcontacts);
431 return contactcount;
432}
433\endcode
434
435In each contact
436<ul>
437<li> m_handle1 points to trimesh.
438<li> m_handle2 points to NULL.
439<li> m_feature1 Is a triangle index of trimesh.
440</ul>
441
442\param trimesh
443\param capsule
444\param contacts A GIM_CONTACT array. Must be initialized
445*/
446void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
447
448
449///Function for create Trimesh Plane collision result
450#define GIM_CREATE_TRIMESHPLANE_CONTACTS(dynarray) GIM_DYNARRAY_CREATE(vec4f,dynarray,G_ARRAY_GROW_SIZE)
451
452//! Trimesh Plane Collisions
453/*!
454
455Before use this function you must update the trimesh:
456\code
457gim_trimesh_update(trimesh);
458\endcode
459Then you must use this function in this way:
460\code
461int collide_trimesh_plane(GIM_TRIMESH * trimesh, vec4f plane)
462{
463 //Create contact list
464 GDYNAMIC_ARRAY tri_plane_contacts;
465 GIM_CREATE_TRIMESHPLANE_CONTACTS(tri_plane_contacts);
466
467 //Collide trimeshes
468 gim_trimesh_plane_collision(trimesh,plane,&tri_plane_contacts);
469
470 if(tri_plane_contacts.m_size == 0) //do nothing
471 {
472 GIM_DYNARRAY_DESTROY(tri_plane_contacts);//clean contact array
473 return 0;
474 }
475
476 //Getting a pointer to the contact array
477 vec4f * planecontacts = GIM_DYNARRAY_POINTER(vec4f,tri_plane_contacts);
478
479 int contactcount = tri_plane_contacts.m_size;
480 int i;
481 //Process contacts
482 for (i=0;i<contactcount ;i++)
483 {
484 vec3f contactpoint;
485 GREAL contactdis;
486
487 VEC_COPY(contactpoint,planecontacts[i]); //Get contact point
488 contactdis = planecontacts[i][3]; // Get distance depth
489
490 //Do something with the contact
491 ......
492 ......
493 // Like creating joints or anything else
494 ......
495 ......
496 }
497 GIM_DYNARRAY_DESTROY(tri_plane_contacts);
498 return contactcount;
499}
500\endcode
501
502In 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.
503
504\param trimesh
505\param plane vec4f plane
506\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.
507*/
508void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts);
509
510
511//! Trimesh Ray Collisions
512/*!
513\param trimesh
514\param origin
515\param dir
516\param tmax
517\param contact
518\return 1 if the ray collides, else 0
519*/
520int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
521
522
523//! Trimesh Ray Collisions closest
524/*!
525Find the closest primitive collided by the ray
526\param trimesh
527\param origin
528\param dir
529\param tmax
530\param contact
531\return 1 if the ray collides, else 0
532*/
533int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
534
535//! @}
536
537
538
539#endif // GIM_TRIMESH_H_INCLUDED
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gimpact.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gimpact.h
new file mode 100644
index 0000000..bcd22a1
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gimpact.h
@@ -0,0 +1,45 @@
1#ifndef GIMPACT_H_INCLUDED
2#define GIMPACT_H_INCLUDED
3
4/*! \file gimpact.h
5\author Francisco León
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18 (1) The GNU Lesser General Public License as published by the Free
19 Software Foundation; either version 2.1 of the License, or (at
20 your option) any later version. The text of the GNU Lesser
21 General Public License is included with this library in the
22 file GIMPACT-LICENSE-LGPL.TXT.
23 (2) The BSD-style license that is included with this library in
24 the file GIMPACT-LICENSE-BSD.TXT.
25
26 This library is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
29 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
30
31-----------------------------------------------------------------------------
32*/
33
34
35#include "GIMPACT/gim_trimesh.h"
36
37/*! \defgroup GIMPACT_INIT
38*/
39//! @{
40//! Call this for initialize GIMPACT system structures.
41void gimpact_init();
42//! Call this for clean GIMPACT system structures.
43void gimpact_terminate();
44//! @}
45#endif // GIMPACT_H_INCLUDED