Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/GIMPACT/src/gim_trimesh.cpp @ 216

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

[Physik] add ode-0.9

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