Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h @ 216

Last change on this file since 216 was 216, checked in by mathiask, 16 years ago

[Physik] add ode-0.9

File size: 17.5 KB
Line 
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
Note: See TracBrowser for help on using the repository browser.