3 -----------------------------------------------------------------------------
4 This source file is part of GIMPACT Library.
6 For the latest info, see http://gimpact.sourceforge.net/
8 Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9 email: projectileman@yahoo.com
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.
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.
26 -----------------------------------------------------------------------------
29 #include "GIMPACT/gim_trimesh.h"
32 //! Trimesh Ray Collisions
37 \return 1 if the ray collides, else 0
39 int gim_trimesh_ray_collision(GIM_TRIMESH
* trimesh
,vec3f origin
,vec3f dir
, GREAL tmax
, GIM_TRIANGLE_RAY_CONTACT_DATA
* contact
)
41 GDYNAMIC_ARRAY collision_result
;
42 GIM_CREATE_BOXQUERY_LIST(collision_result
);
44 gim_aabbset_ray_collision(origin
,dir
,tmax
,&trimesh
->m_aabbset
,&collision_result
);
46 if(collision_result
.m_size
==0)
48 GIM_DYNARRAY_DESTROY(collision_result
);
54 GUINT32
* boxesresult
= GIM_DYNARRAY_POINTER(GUINT32
,collision_result
);
55 GIM_TRIANGLE_DATA tridata
;
60 gim_trimesh_locks_work_data(trimesh
);
62 for(unsigned int i
=0;i
<collision_result
.m_size
;i
++)
64 gim_trimesh_get_triangle_data(trimesh
,boxesresult
[i
],&tridata
);
66 // flip plane for correct result in ODE
67 // for more info: martijn@bytehazard.com
69 VEC_SCALE_4(flippedPlane
, -1.0f
, tridata
.m_planes
.m_planes
[0]);
71 RAY_TRIANGLE_INTERSECTION(origin
,dir
,tridata
.m_vertices
[0],tridata
.m_vertices
[1],tridata
.m_vertices
[2],flippedPlane
,pout
,u
,v
,tparam
,tmax
,does_intersect
);
74 contact
->tparam
= tparam
;
77 contact
->m_face_id
= boxesresult
[i
];
78 VEC_COPY(contact
->m_point
,pout
);
79 VEC_COPY(contact
->m_normal
,flippedPlane
);
81 gim_trimesh_unlocks_work_data(trimesh
);
82 GIM_DYNARRAY_DESTROY(collision_result
);
87 gim_trimesh_unlocks_work_data(trimesh
);
88 GIM_DYNARRAY_DESTROY(collision_result
);
89 return 0;//no collisiion
93 //! Trimesh Ray Collisions closest
95 Finds the closest primitive collided by the ray
98 \return 1 if the ray collides, else 0
100 int gim_trimesh_ray_closest_collision(GIM_TRIMESH
* trimesh
,vec3f origin
,vec3f dir
, GREAL tmax
, GIM_TRIANGLE_RAY_CONTACT_DATA
* contact
)
102 GDYNAMIC_ARRAY collision_result
;
103 GIM_CREATE_BOXQUERY_LIST(collision_result
);
105 gim_aabbset_ray_collision(origin
,dir
,tmax
,&trimesh
->m_aabbset
,&collision_result
);
107 if(collision_result
.m_size
==0)
109 GIM_DYNARRAY_DESTROY(collision_result
);
115 GUINT32
* boxesresult
= GIM_DYNARRAY_POINTER(GUINT32
,collision_result
);
116 GIM_TRIANGLE_DATA tridata
;
120 contact
->tparam
= tmax
+ 0.1f
;
122 gim_trimesh_locks_work_data(trimesh
);
124 for(unsigned int i
=0;i
<collision_result
.m_size
;i
++)
126 gim_trimesh_get_triangle_data(trimesh
,boxesresult
[i
],&tridata
);
128 // flip plane for correct result in ODE
129 // for more info: martijn@bytehazard.com
131 VEC_SCALE_4(flippedPlane
, -1.0f
, tridata
.m_planes
.m_planes
[0]);
133 RAY_TRIANGLE_INTERSECTION(origin
,dir
,tridata
.m_vertices
[0],tridata
.m_vertices
[1],tridata
.m_vertices
[2],flippedPlane
,pout
,u
,v
,tparam
,tmax
,does_intersect
);
134 if(does_intersect
&& (tparam
< contact
->tparam
))
136 contact
->tparam
= tparam
;
139 contact
->m_face_id
= boxesresult
[i
];
140 VEC_COPY(contact
->m_point
,pout
);
141 VEC_COPY(contact
->m_normal
,flippedPlane
);
145 gim_trimesh_unlocks_work_data(trimesh
);
146 GIM_DYNARRAY_DESTROY(collision_result
);
147 if(contact
->tparam
> tmax
) return 0;