aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp')
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp348
1 files changed, 0 insertions, 348 deletions
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp
deleted file mode 100644
index c9c5305..0000000
--- a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_trimesh_collision.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
1
2/*
3-----------------------------------------------------------------------------
4This source file is part of GIMPACT Library.
5
6For the latest info, see http://gimpact.sourceforge.net/
7
8Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9email: projectileman@yahoo.com
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
25
26-----------------------------------------------------------------------------
27*/
28
29#include "GIMPACT/gim_trimesh.h"
30
31#define CLASSIFY_TRI_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
32{ \
33 _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
34 _distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
35 _distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
36 if(_distances[1]>0.0f && _distances[2]>0.0f)\
37 {\
38 out_of_face = 1;\
39 }\
40 else\
41 {\
42 out_of_face = 0;\
43 }\
44}\
45
46
47//! Receives the 3 edge planes
48#define MOST_DEEP_POINTS(plane,points,point_count,deep_points,deep_points_count,maxdeep)\
49{\
50 maxdeep=-1000.0f;\
51 GUINT _k;\
52 GREAL _dist;\
53 deep_points_count = 0;\
54 for(_k=0;_k<point_count;_k++)\
55 {\
56 _dist = -DISTANCE_PLANE_POINT(plane,points[_k]);\
57 if(_dist>maxdeep)\
58 {\
59 maxdeep = _dist;\
60 _max_candidates[0] = _k;\
61 deep_points_count=1;\
62 }\
63 else if((_dist+G_EPSILON)>=maxdeep)\
64 {\
65 _max_candidates[deep_points_count] = _k;\
66 deep_points_count++;\
67 }\
68 }\
69 if(maxdeep<0.0f)\
70 {\
71 deep_points_count = 0;\
72 }\
73 else\
74 {\
75 for(_k=0;_k<deep_points_count;_k++)\
76 {\
77 VEC_COPY(deep_points[_k],points[_max_candidates[_k]]);\
78 }\
79 }\
80}\
81
82//! Receives the 3 edge planes
83#define CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri_points,tri_edge_planes, clipped_points, clipped_point_count)\
84{\
85 clipped_point_count = 0; \
86 _temp_clip_count = 0;\
87 PLANE_CLIP_POLYGON(tri_edge_planes[0],tri_points,3,_temp_clip,_temp_clip_count,MAX_TRI_CLIPPING);\
88 if(_temp_clip_count>0)\
89 {\
90 _temp_clip_count2 = 0;\
91 PLANE_CLIP_POLYGON(tri_edge_planes[1],_temp_clip,_temp_clip_count,_temp_clip2,_temp_clip_count2,MAX_TRI_CLIPPING);\
92 if(_temp_clip_count2>0)\
93 {\
94 PLANE_CLIP_POLYGON(tri_edge_planes[2],_temp_clip2,_temp_clip_count2,clipped_points,clipped_point_count,MAX_TRI_CLIPPING);\
95 }\
96 }\
97}\
98
99
100
101int _gim_triangle_triangle_collision(
102 GIM_TRIANGLE_DATA *tri1,
103 GIM_TRIANGLE_DATA *tri2,
104 GIM_TRIANGLE_CONTACT_DATA * contact_data)
105{
106 //Cache variables for triangle intersection
107 GUINT _max_candidates[MAX_TRI_CLIPPING];
108 vec3f _temp_clip[MAX_TRI_CLIPPING];
109 GUINT _temp_clip_count = 0;
110 vec3f _temp_clip2[MAX_TRI_CLIPPING];
111 GUINT _temp_clip_count2 = 0;
112 vec3f clipped_points2[MAX_TRI_CLIPPING];
113 vec3f deep_points2[MAX_TRI_CLIPPING];
114 vec3f clipped_points1[MAX_TRI_CLIPPING];
115 vec3f deep_points1[MAX_TRI_CLIPPING];
116
117
118
119 //State variabnles
120 GUINT mostdir=0;
121 GUINT clipped2_count=0;
122
123 //Clip tri2 by tri1 edges
124
125 CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri2->m_vertices,(&tri1->m_planes.m_planes[1]), clipped_points2, clipped2_count);
126
127 if(clipped2_count == 0 )
128 {
129 return 0;//Reject
130 }
131
132 //find most deep interval face1
133 GUINT deep2_count=0;
134
135 GREAL maxdeep;
136
137 MOST_DEEP_POINTS((tri1->m_planes.m_planes[0]), clipped_points2, clipped2_count, deep_points2, deep2_count, maxdeep);
138 if(deep2_count==0)
139 {
140// *perror = 0.0f;
141 return 0;//Reject
142 }
143
144 //Normal pointing to triangle1
145 VEC_SCALE(contact_data->m_separating_normal,-1.0f,(tri1->m_planes.m_planes[0]));
146
147
148 //Clip tri1 by tri2 edges
149
150 GUINT clipped1_count=0;
151
152 CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri1->m_vertices,(&tri2->m_planes.m_planes[1]), clipped_points1, clipped1_count);
153
154 if(clipped2_count == 0 )
155 {
156// *perror = 0.0f;
157 return 0;//Reject
158 }
159
160
161 //find interval face2
162 GUINT deep1_count=0;
163
164 GREAL dist;
165
166 MOST_DEEP_POINTS((tri2->m_planes.m_planes[0]), clipped_points1, clipped1_count, deep_points1, deep1_count, dist);
167
168 if(deep1_count==0)
169 {
170// *perror = 0.0f;
171 return 0;
172 }
173
174 if(dist<maxdeep)
175 {
176 maxdeep = dist;
177 mostdir = 1;
178 VEC_COPY(contact_data->m_separating_normal,(tri2->m_planes.m_planes[0]));
179 }
180 //set deep
181 contact_data->m_penetration_depth = maxdeep;
182
183 ////check most dir for contacts
184 if(mostdir==0)
185 {
186 contact_data->m_point_count = deep2_count;
187 for(mostdir=0;mostdir<deep2_count;mostdir++)
188 {
189 VEC_COPY(contact_data->m_points[mostdir] ,deep_points2[mostdir]);
190 }
191 }
192 else
193 {
194 contact_data->m_point_count = deep1_count;
195 for(mostdir=0;mostdir<deep1_count;mostdir++)
196 {
197 VEC_COPY(contact_data->m_points[mostdir] ,deep_points1[mostdir]);
198 }
199 }
200 return 1;
201}
202
203
204
205//! Finds the contact points from a collision of two triangles
206/*!
207Returns the contact points, the penetration depth and the separating normal of the collision
208between two triangles. The normal is pointing toward triangle 1 from triangle 2
209*/
210int gim_triangle_triangle_collision(
211 GIM_TRIANGLE_DATA *tri1,
212 GIM_TRIANGLE_DATA *tri2,
213 GIM_TRIANGLE_CONTACT_DATA * contact_data)
214{
215 vec3f _distances;
216 char out_of_face=0;
217
218 CLASSIFY_TRI_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face);
219 if(out_of_face==1) return 0;
220
221 CLASSIFY_TRI_BY_FACE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face);
222 if(out_of_face==1) return 0;
223
224 return _gim_triangle_triangle_collision(tri1,tri2,contact_data);
225}
226
227//! Trimesh Trimesh Collisions
228/*!
229
230In each contact
231<ul>
232<li> m_handle1 points to trimesh1.
233<li> m_handle2 points to trimesh2.
234<li> m_feature1 Is a triangle index of trimesh1.
235<li> m_feature2 Is a triangle index of trimesh2.
236</ul>
237
238\param trimesh1 Collider
239\param trimesh2 Collidee
240\param contacts A GIM_CONTACT array. Must be initialized
241*/
242void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts)
243{
244 contacts->m_size = 0;
245 GDYNAMIC_ARRAY collision_pairs;
246 GIM_CREATE_PAIR_SET(collision_pairs)
247
248 gim_aabbset_bipartite_intersections(&trimesh1->m_aabbset,&trimesh2->m_aabbset,&collision_pairs);
249
250 if(collision_pairs.m_size==0)
251 {
252 GIM_DYNARRAY_DESTROY(collision_pairs);
253 return; //no collisioin
254 }
255
256 //Locks meshes
257 gim_trimesh_locks_work_data(trimesh1);
258 gim_trimesh_locks_work_data(trimesh2);
259
260
261 //pair pointer
262 GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
263 //dummy contacts
264 GDYNAMIC_ARRAY dummycontacts;
265 GIM_CREATE_CONTACT_LIST(dummycontacts);
266
267 //Auxiliary triangle data
268 GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
269 GIM_TRIANGLE_DATA tri1data,tri2data;
270
271
272 GUINT i, ti1,ti2,ci;
273 int colresult;
274 for (i=0;i<collision_pairs.m_size; i++)
275 {
276 ti1 = pairs[i].m_index1;
277 ti2 = pairs[i].m_index2;
278 //Get triangles data
279 gim_trimesh_get_triangle_data(trimesh1,ti1,&tri1data);
280 gim_trimesh_get_triangle_data(trimesh2,ti2,&tri2data);
281
282 //collide triangles
283 colresult = gim_triangle_triangle_collision(&tri1data,&tri2data,&tri_contact_data);
284 if(colresult == 1)
285 {
286 //Add contacts
287 for (ci=0;ci<tri_contact_data.m_point_count ;ci++ )
288 {
289 GIM_PUSH_CONTACT(dummycontacts, tri_contact_data.m_points[ci],tri_contact_data.m_separating_normal ,tri_contact_data.m_penetration_depth,trimesh1, trimesh2, ti1, ti2);
290 }
291 }
292 }
293
294 if(dummycontacts.m_size == 0) //reject
295 {
296 GIM_DYNARRAY_DESTROY(dummycontacts);
297 GIM_DYNARRAY_DESTROY(collision_pairs);
298 return;
299 }
300 //merge contacts
301 gim_merge_contacts(&dummycontacts,contacts);
302
303 //Terminate
304 GIM_DYNARRAY_DESTROY(dummycontacts);
305 GIM_DYNARRAY_DESTROY(collision_pairs);
306
307 //Unlocks meshes
308 gim_trimesh_unlocks_work_data(trimesh1);
309 gim_trimesh_unlocks_work_data(trimesh2);
310}
311
312
313//! Trimesh Plane Collisions
314/*!
315
316\param trimesh
317\param plane vec4f plane
318\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.
319*/
320void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts)
321{
322 contacts->m_size = 0;
323 char classify;
324 PLANE_CLASSIFY_BOX(plane,trimesh->m_aabbset.m_global_bound,classify);
325 if(classify>1) return; // in front of plane
326
327 //Locks mesh
328 gim_trimesh_locks_work_data(trimesh);
329 //Get vertices
330 GUINT i, vertcount = trimesh->m_transformed_vertex_buffer.m_element_count;
331 vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
332
333 GREAL dist;
334 vec4f * result_contact;
335
336 for (i=0;i<vertcount;i++)
337 {
338 dist = DISTANCE_PLANE_POINT(plane,vertices[i]);
339 if(dist<=0.0f)
340 {
341 GIM_DYNARRAY_PUSH_EMPTY(vec4f,(*contacts));
342 result_contact = GIM_DYNARRAY_POINTER_LAST(vec4f,(*contacts));
343 VEC_COPY((*result_contact),vertices[i]);
344 (*result_contact)[3] = -dist;
345 }
346 }
347 gim_trimesh_unlocks_work_data(trimesh);
348}