static int heat_ray_source_visible(LaplacianSystem *sys, int vertex, int source)
{
	BVHTreeRayHit hit;
	BVHCallbackUserData data;
	const MLoopTri *lt;
	float end[3];
	int visible;

	lt = sys->heat.vltree[vertex];
	if (lt == NULL)
		return 1;

	data.sys = sys;
	copy_v3_v3(data.start, sys->heat.verts[vertex]);

	closest_to_line_segment_v3(end, data.start, sys->heat.root[source], sys->heat.tip[source]);

	sub_v3_v3v3(data.vec, end, data.start);
	madd_v3_v3v3fl(data.start, data.start, data.vec, 1e-5);
	mul_v3_fl(data.vec, 1.0f - 2e-5f);

	/* pass normalized vec + distance to bvh */
	hit.index = -1;
	hit.dist = normalize_v3(data.vec);

	visible = BLI_bvhtree_ray_cast(sys->heat.bvhtree, data.start, data.vec, 0.0f, &hit, bvh_callback, (void *)&data) == -1;

	return visible;
}
static float heat_source_distance(LaplacianSystem *sys, int vertex, int source)
{
	float closest[3], d[3], dist, cosine;
	
	/* compute euclidian distance */
	closest_to_line_segment_v3(closest, sys->heat.verts[vertex], sys->heat.root[source], sys->heat.tip[source]);

	sub_v3_v3v3(d, sys->heat.verts[vertex], closest);
	dist = normalize_v3(d);

	/* if the vertex normal does not point along the bone, increase distance */
	cosine = dot_v3v3(d, sys->heat.vnors[vertex]);

	return dist / (0.5f * (cosine + 1.001f));
}
Example #3
0
/* Helper, does all the point-spherecast work actually. */
static void mesh_verts_spherecast_do(
	const BVHTreeFromMesh *UNUSED(data), int index, const float v[3], const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
	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);
	}
}
Example #4
0
/* Callback to bvh tree nearest point. The tree must 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_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
{
	const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata;
	const MVert *vert = data->vert;
	const MEdge *edge = data->edge + index;
	float nearest_tmp[3], dist_sq;

	const float *t0, *t1;
	t0 = vert[edge->v1].co;
	t1 = vert[edge->v2].co;

	closest_to_line_segment_v3(nearest_tmp, co, t0, t1);
	dist_sq = len_squared_v3v3(nearest_tmp, co);
	
	if (dist_sq < nearest->dist_sq) {
		nearest->index = index;
		nearest->dist_sq = dist_sq;
		copy_v3_v3(nearest->co, nearest_tmp);
		sub_v3_v3v3(nearest->no, t0, t1);
		normalize_v3(nearest->no);
	}
}
Example #5
0
// Callback to bvh tree nearest point. 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_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest)
{
	const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
	MVert *vert	= data->vert;
	MEdge *edge = data->edge + index;
	float nearest_tmp[3], dist;

	float *t0, *t1;
	t0 = vert[ edge->v1 ].co;
	t1 = vert[ edge->v2 ].co;
	
	// NOTE: casts to "float*" here are due to co being "const float*"
	closest_to_line_segment_v3(nearest_tmp, (float*)co, t0, t1);
	dist = len_squared_v3v3(nearest_tmp, (float*)co);
	
	if(dist < nearest->dist)
	{
		nearest->index = index;
		nearest->dist = dist;
		VECCOPY(nearest->co, nearest_tmp);
		sub_v3_v3v3(nearest->no, t0, t1);
		normalize_v3(nearest->no);
	}
}