aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp
diff options
context:
space:
mode:
authordan miller2007-10-19 05:20:48 +0000
committerdan miller2007-10-19 05:20:48 +0000
commitd48ea5bb797037069d641da41da0f195f0124491 (patch)
tree40ff433d94859d629aac933d5ec73b382f62ba1a /libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp
parentdont ask (diff)
downloadopensim-SC-d48ea5bb797037069d641da41da0f195f0124491.zip
opensim-SC-d48ea5bb797037069d641da41da0f195f0124491.tar.gz
opensim-SC-d48ea5bb797037069d641da41da0f195f0124491.tar.bz2
opensim-SC-d48ea5bb797037069d641da41da0f195f0124491.tar.xz
one more for the gipper
Diffstat (limited to 'libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp')
-rw-r--r--libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp364
1 files changed, 364 insertions, 0 deletions
diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp
new file mode 100644
index 0000000..1872592
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp
@@ -0,0 +1,364 @@
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
30#include <assert.h>
31#include "GIMPACT/gim_trimesh.h"
32
33GUINT gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh)
34{
35 return trimesh->m_tri_index_buffer.m_element_count/3;
36}
37
38//! Creates the aabb set and the triangles cache
39/*!
40
41\param trimesh
42\param vertex_array
43\param triindex_array
44\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.
45\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
46*/
47void gim_trimesh_create_from_arrays(GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply)
48{
49 assert(trimesh);
50 assert(vertex_array);
51 assert(triindex_array);
52 gim_buffer_array_copy_ref(vertex_array,&trimesh->m_source_vertex_buffer);
53 gim_buffer_array_copy_ref(triindex_array,&trimesh->m_tri_index_buffer);
54
55 trimesh->m_mask = GIM_TRIMESH_NEED_UPDATE;//needs update
56 //Create the transformed vertices
57 if(transformed_reply==1)
58 {
59 trimesh->m_mask |= GIM_TRIMESH_TRANSFORMED_REPLY;
60 gim_buffer_array_copy_value(vertex_array,&trimesh->m_transformed_vertex_buffer,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
61 }
62 else
63 {
64 gim_buffer_array_copy_ref(vertex_array,&trimesh->m_transformed_vertex_buffer);
65 }
66 //create the box set
67 GUINT facecount = gim_trimesh_get_triangle_count(trimesh);
68
69 gim_aabbset_alloc(&trimesh->m_aabbset,facecount);
70 //create the planes cache
71 GIM_DYNARRAY_CREATE_SIZED(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer,facecount);
72 //Create the bitset
73 GIM_BITSET_CREATE_SIZED(trimesh->m_planes_cache_bitset,facecount);
74 //Callback is 0
75 trimesh->m_update_callback = 0;
76 //set to identity
77 IDENTIFY_MATRIX_4X4(trimesh->m_transform);
78}
79
80
81
82//! Create a trimesh from vertex array and an index array
83/*!
84
85\param trimesh An uninitialized GIM_TRIMESH structure
86\param vertex_array A buffer to a vec3f array
87\param vertex_count
88\param triindex_array
89\param index_count
90\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
91\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
92\param transformed_reply If , then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
93*/
94void 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)
95{
96 GBUFFER_ARRAY buffer_vertex_array;
97 GBUFFER_ARRAY buffer_triindex_array;
98
99 //Create vertices
100 if(copy_vertices == 1)
101 {
102 gim_create_common_buffer_from_data(vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
103 }
104 else//Create a shared buffer
105 {
106 gim_create_shared_buffer_from_data(vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
107 }
108 GIM_BUFFER_ARRAY_INIT_TYPE(vec3f,buffer_vertex_array,buffer_vertex_array.m_buffer_id,vertex_count);
109
110
111 //Create vertices
112 if(copy_indices == 1)
113 {
114 gim_create_common_buffer_from_data(triindex_array, index_count*sizeof(GUINT), &buffer_triindex_array.m_buffer_id);
115 }
116 else//Create a shared buffer
117 {
118 gim_create_shared_buffer_from_data(triindex_array, index_count*sizeof(GUINT), &buffer_triindex_array.m_buffer_id);
119 }
120 GIM_BUFFER_ARRAY_INIT_TYPE(GUINT,buffer_triindex_array,buffer_triindex_array.m_buffer_id,index_count);
121
122 gim_trimesh_create_from_arrays(trimesh, &buffer_vertex_array, &buffer_triindex_array,transformed_reply);
123
124 ///always call this after create a buffer_array
125 GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
126 GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
127}
128
129//! Clears auxiliary data and releases buffer arrays
130void gim_trimesh_destroy(GIM_TRIMESH * trimesh)
131{
132 gim_aabbset_destroy(&trimesh->m_aabbset);
133
134 GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_buffer);
135 GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_bitset);
136
137 GIM_BUFFER_ARRAY_DESTROY(trimesh->m_transformed_vertex_buffer);
138 GIM_BUFFER_ARRAY_DESTROY(trimesh->m_source_vertex_buffer);
139 GIM_BUFFER_ARRAY_DESTROY(trimesh->m_tri_index_buffer);
140}
141
142//! Copies two meshes
143/*!
144\pre dest_trimesh shouldn't be created
145\post dest_trimesh will be created
146\param source_trimesh
147\param dest_trimesh
148\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
149\param transformed_reply IF 1, then it forces the m_trasnformed_vertices to be a reply of the source vertices
150*/
151void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,GIM_TRIMESH * dest_trimesh, char copy_by_reference, char transformed_reply)
152{
153 if(copy_by_reference==1)
154 {
155 gim_trimesh_create_from_arrays(dest_trimesh, &source_trimesh->m_source_vertex_buffer, &source_trimesh->m_tri_index_buffer,transformed_reply);
156 }
157 else
158 {
159 GBUFFER_ARRAY buffer_vertex_array;
160 GBUFFER_ARRAY buffer_triindex_array;
161
162 gim_buffer_array_copy_value(&source_trimesh->m_source_vertex_buffer,&buffer_vertex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
163
164 gim_buffer_array_copy_value(&source_trimesh->m_tri_index_buffer,&buffer_triindex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
165
166 gim_trimesh_create_from_arrays(dest_trimesh, &buffer_vertex_array, &buffer_triindex_array,transformed_reply);
167
168 ///always call this after create a buffer_array
169 GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
170 GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
171 }
172}
173
174//! Locks the trimesh for working with it
175/*!
176\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
177\param trimesh
178*/
179void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh)
180{
181 GINT res;
182 res=gim_buffer_array_lock(&trimesh->m_tri_index_buffer,G_MA_READ_ONLY);
183 assert(res==G_BUFFER_OP_SUCCESS);
184 res=gim_buffer_array_lock(&trimesh->m_transformed_vertex_buffer,G_MA_READ_ONLY);
185 assert(res==G_BUFFER_OP_SUCCESS);
186}
187
188//! unlocks the trimesh
189/*!
190\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
191\param trimesh
192*/
193void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh)
194{
195 gim_buffer_array_unlock(&trimesh->m_tri_index_buffer);
196 gim_buffer_array_unlock(&trimesh->m_transformed_vertex_buffer);
197}
198
199
200//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
201char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh)
202{
203 if(trimesh->m_mask&GIM_TRIMESH_TRANSFORMED_REPLY) return 1;
204 return 0;
205}
206
207//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
208char gim_trimesh_needs_update(GIM_TRIMESH * trimesh)
209{
210 if(trimesh->m_mask&GIM_TRIMESH_NEED_UPDATE) return 1;
211 return 0;
212}
213
214//! Change the state of the trimesh for force it to update
215/*!
216Call it after made changes to the trimesh.
217\post gim_trimesh_need_update(trimesh) will return 1
218*/
219void gim_trimesh_post_update(GIM_TRIMESH * trimesh)
220{
221 trimesh->m_mask |= GIM_TRIMESH_NEED_UPDATE;
222}
223
224//kernel
225#define MULT_MAT_VEC4_KERNEL(_mat,_src,_dst) MAT_DOT_VEC_3X4((_dst),(_mat),(_src))
226
227//! Updates m_transformed_vertex_buffer
228/*!
229\pre m_transformed_vertex_buffer must be unlocked
230*/
231void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh)
232{
233 if(gim_trimesh_has_tranformed_reply(trimesh) == 0) return; //Don't perform transformation
234
235 //Vertices
236 GBUFFER_ARRAY * psource_vertex_buffer = &trimesh->m_source_vertex_buffer;
237 GBUFFER_ARRAY * ptransformed_vertex_buffer = &trimesh->m_transformed_vertex_buffer;
238 //Temp transform
239 mat4f transform;
240 COPY_MATRIX_4X4(transform,trimesh->m_transform);
241
242 GIM_PROCESS_BUFFER_ARRAY(transform,(*psource_vertex_buffer),(*ptransformed_vertex_buffer),MULT_MAT_VEC4_KERNEL,vec3f,vec3f);
243}
244
245//! Updates m_aabbset and m_planes_cache_bitset
246/*!
247\pre gim_trimesh_locks_work_data must be called before
248*/
249void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh)
250{
251 vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
252 assert(transformed_vertices);
253
254 GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh->m_tri_index_buffer,0);
255 assert(triangle_indices);
256 // box set
257 aabb3f * paabb = trimesh->m_aabbset.m_boxes;
258 GUINT triangle_count = gim_trimesh_get_triangle_count(trimesh);
259 float * v1,*v2,*v3;
260 GUINT i;
261 for (i=0; i<triangle_count;i++)
262 {
263 v1 = &transformed_vertices[triangle_indices[0]][0];
264 v2 = &transformed_vertices[triangle_indices[1]][0];
265 v3 = &transformed_vertices[triangle_indices[2]][0];
266 COMPUTEAABB_FOR_TRIANGLE((*paabb),v1,v2,v3);
267 triangle_indices+=3;
268 paabb++;
269 }
270 //Clear planes cache
271 GIM_BITSET_CLEAR_ALL(trimesh->m_planes_cache_bitset);
272 //Sorts set
273 gim_aabbset_update(&trimesh->m_aabbset);
274}
275
276//! Updates the trimesh if needed
277/*!
278\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
279*/
280void gim_trimesh_update(GIM_TRIMESH * trimesh)
281{
282 if(gim_trimesh_needs_update(trimesh)==0) return;
283 gim_trimesh_update_vertices(trimesh);
284 gim_trimesh_locks_work_data(trimesh);
285 gim_trimesh_update_aabbset(trimesh);
286 gim_trimesh_unlocks_work_data(trimesh);
287
288 //Clear update flag
289 trimesh->m_mask &= ~GIM_TRIMESH_NEED_UPDATE;
290}
291
292void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform)
293{
294 GREAL diff = 0.0f;
295 float * originaltrans = &trimesh->m_transform[0][0];
296 float * newtrans = &transform[0][0];
297 GUINT i;
298 for (i=0;i<16;i++)
299 {
300 diff += fabs(originaltrans[i]-newtrans[i]);
301 }
302
303// if(IS_ZERO(diff)) return ;///don't need to update
304 if(diff< 0.00001f) return ;///don't need to update
305
306 COPY_MATRIX_4X4(trimesh->m_transform,transform);
307
308 gim_trimesh_post_update(trimesh);
309}
310
311void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data)
312{
313 vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
314
315 GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh->m_tri_index_buffer,triangle_index*3);
316
317
318 //Copy the vertices
319 VEC_COPY(tri_data->m_vertices[0],transformed_vertices[triangle_indices[0]]);
320 VEC_COPY(tri_data->m_vertices[1],transformed_vertices[triangle_indices[1]]);
321 VEC_COPY(tri_data->m_vertices[2],transformed_vertices[triangle_indices[2]]);
322
323 //Get the planes
324 GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer);
325 planes += triangle_index;
326
327 //verify planes cache
328 GUINT bit_eval;
329 GIM_BITSET_GET(trimesh->m_planes_cache_bitset,triangle_index,bit_eval);
330 if(bit_eval == 0)// Needs to calc the planes
331 {
332 //Calc the face plane
333 TRIANGLE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],tri_data->m_vertices[2],planes->m_planes[0]);
334 //Calc the edge 1
335 EDGE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],(planes->m_planes[0]),(planes->m_planes[1]));
336
337 //Calc the edge 2
338 EDGE_PLANE(tri_data->m_vertices[1],tri_data->m_vertices[2],(planes->m_planes[0]),(planes->m_planes[2]));
339
340 //Calc the edge 3
341 EDGE_PLANE(tri_data->m_vertices[2],tri_data->m_vertices[0],(planes->m_planes[0]), (planes->m_planes[3]));
342
343 //mark
344 GIM_BITSET_SET(trimesh->m_planes_cache_bitset,triangle_index);
345 }
346
347
348 VEC_COPY_4((tri_data->m_planes.m_planes[0]),(planes->m_planes[0]));//face plane
349 VEC_COPY_4((tri_data->m_planes.m_planes[1]),(planes->m_planes[1]));//edge1
350 VEC_COPY_4((tri_data->m_planes.m_planes[2]),(planes->m_planes[2]));//edge2
351 VEC_COPY_4((tri_data->m_planes.m_planes[3]),(planes->m_planes[3]));//edge3
352}
353
354void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3)
355{
356 vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
357
358 GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh->m_tri_index_buffer,triangle_index*3);
359
360 //Copy the vertices
361 VEC_COPY(v1,transformed_vertices[triangle_indices[0]]);
362 VEC_COPY(v2,transformed_vertices[triangle_indices[1]]);
363 VEC_COPY(v3,transformed_vertices[triangle_indices[2]]);
364}