[Bf-blender-cvs] [64ee027] mesh-transfer-data: BVHTree Mesh helpers: Add support for raycasting against verts/edges.

Bastien Montagne noreply at git.blender.org
Wed Oct 15 21:37:19 CEST 2014


Commit: 64ee027fb9150291d66c570c8400f4b112c88ae8
Author: Bastien Montagne
Date:   Wed Oct 15 16:36:39 2014 +0200
Branches: mesh-transfer-data
https://developer.blender.org/rB64ee027fb9150291d66c570c8400f4b112c88ae8

BVHTree Mesh helpers: Add support for raycasting against verts/edges.

iNote: pure theoritical code, not tested at all yet!

===================================================================

M	source/blender/blenkernel/intern/bvhutils.c

===================================================================

diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 3cc3eed..6053ae3 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -239,6 +239,84 @@ static void mesh_edges_nearest_point(void *userdata, int index, const float co[3
 	}
 }
 
+/* XXX To be moved to BLI most likely? */
+static float dot_v3v3v3(const float p[3], const float a[3], const float b[3])
+{
+	float vec1[3], vec2[3];
+
+	sub_v3_v3v3(vec1, a, p);
+	sub_v3_v3v3(vec2, b, p);
+	if (is_zero_v3(vec1) || is_zero_v3(vec2)) {
+		return 0.0f;
+	}
+	return dot_v3v3(vec1, vec2);
+}
+
+/* Helper, does all the point-spherecast work actually. */
+static void mesh_verts_spherecast_do(
+	const BVHTreeFromMesh *data, int index, const float v[3], const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+	const float radius_sq = SQUARE(data->sphere_radius);
+	float dist;
+	const float *r1;
+	float r2[3], i1[3];
+	r1 = ray->origin;
+	add_v3_v3v3(r2, r1, ray->direction);
+
+	closest_to_line_segment_v3(i1, v, r1, r2);
+
+	/* No hit if closest point is 'behind' the origin of the ray, or too far away from it. */
+	if ((dot_v3v3v3(r1, i1, r2) >= 0.0f) && ((dist = len_v3v3(r1, i1)) < hit->dist)) {
+		hit->index = index;
+		hit->dist = dist;
+		copy_v3_v3(hit->co, i1);
+	}
+}
+
+/* Callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_verts.
+ * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
+static void mesh_verts_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+	const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
+	float *v = data->vert[index].co;
+
+	mesh_verts_spherecast_do(data, index, v, ray, hit);
+}
+
+/* Callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_edges.
+ * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
+static void mesh_edges_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+	const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
+	MVert *vert = data->vert;
+	MEdge *edge = &data->edge[index];
+
+	const float radius_sq = SQUARE(data->sphere_radius);
+	float dist;
+	const float *v1, *v2, *r1;
+	float r2[3], i1[3], i2[3];
+	v1 = vert[edge->v1].co;
+	v2 = vert[edge->v2].co;
+
+	/* In case we get a zero-length edge, handle it as a point! */
+	if (equals_v3v3(v1, v2)) {
+		mesh_verts_spherecast_do(data, index, v1, ray, hit);
+		return;
+	}
+
+	r1 = ray->origin;
+	add_v3_v3v3(r2, r1, ray->direction);
+
+	if (isect_line_line_v3(v1, v2, r1, r2, i1, i2)) {
+		/* No hit if intersection point is 'behind' the origin of the ray, or too far away from it. */
+		if ((dot_v3v3v3(r1, i2, r2) >= 0.0f) && ((dist = len_v3v3(r1, i2)) < hit->dist)) {
+			hit->index = index;
+			hit->dist = dist;
+			copy_v3_v3(hit->co, i2);
+		}
+	}
+}
+
 /*
  * BVH builders
  */
@@ -294,7 +372,7 @@ static void bvhtree_from_mesh_verts_setup_data(BVHTreeFromMesh *data, BVHTree *t
 		/* a NULL nearest callback works fine
 		 * remember the min distance to point is the same as the min distance to BV of point */
 		data->nearest_callback = NULL;
-		data->raycast_callback = NULL;
+		data->raycast_callback = mesh_verts_spherecast;
 
 		data->vert = vert;
 		data->vert_allocated = vert_allocated;
@@ -423,7 +501,7 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *dm, float e
 		data->cached = true;
 
 		data->nearest_callback = mesh_edges_nearest_point;
-		data->raycast_callback = NULL;
+		data->raycast_callback = mesh_edges_spherecast;
 
 		data->vert = vert;
 		data->vert_allocated = vert_allocated;




More information about the Bf-blender-cvs mailing list