diff options
author | dan miller | 2007-10-19 05:20:48 +0000 |
---|---|---|
committer | dan miller | 2007-10-19 05:20:48 +0000 |
commit | d48ea5bb797037069d641da41da0f195f0124491 (patch) | |
tree | 40ff433d94859d629aac933d5ec73b382f62ba1a /libraries/ode-0.9/GIMPACT/src/gim_trimesh.cpp | |
parent | dont ask (diff) | |
download | opensim-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.cpp | 364 |
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 | ----------------------------------------------------------------------------- | ||
4 | This source file is part of GIMPACT Library. | ||
5 | |||
6 | For the latest info, see http://gimpact.sourceforge.net/ | ||
7 | |||
8 | Copyright (c) 2006 Francisco Leon. C.C. 80087371. | ||
9 | email: 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 | |||
33 | GUINT 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 | */ | ||
47 | void 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 | */ | ||
94 | void 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 | ||
130 | void 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 | */ | ||
151 | void 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 | */ | ||
179 | void 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 | */ | ||
193 | void 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 | ||
201 | char 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. | ||
208 | char 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 | /*! | ||
216 | Call it after made changes to the trimesh. | ||
217 | \post gim_trimesh_need_update(trimesh) will return 1 | ||
218 | */ | ||
219 | void 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 | */ | ||
231 | void 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 | */ | ||
249 | void 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 | */ | ||
280 | void 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 | |||
292 | void 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 | |||
311 | void 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 | |||
354 | void 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 | } | ||