[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15551] branches/soc-2008-jaguarandi/ source/blender/blenkernel/intern/shrinkwrap.c: Adding the Cullface option on normal projection of shrinkwrap when using bvhtrees
André Pinto
andresusanopinto at gmail.com
Sun Jul 13 03:49:54 CEST 2008
Revision: 15551
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15551
Author: jaguarandi
Date: 2008-07-13 03:49:53 +0200 (Sun, 13 Jul 2008)
Log Message:
-----------
Adding the Cullface option on normal projection of shrinkwrap when using bvhtrees
Modified Paths:
--------------
branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c 2008-07-12 22:11:26 UTC (rev 15550)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c 2008-07-13 01:49:53 UTC (rev 15551)
@@ -106,17 +106,14 @@
static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, const float m_dist, const float *v0, const float *v1, const float *v2)
{
- float dist, idist;
- float p0[3], p1[3];
+ float idist;
+ float p1[3];
float plane_normal[3], hit_point[3];
CalcNormFloat((float*)v0, (float*)v1, (float*)v2, plane_normal);
- dist = ray_intersect_plane(ray->origin, ray->direction, v0, plane_normal);
-
- VECADDFAC( p0, ray->origin, ray->direction, /*dist-radius*/ 0);
VECADDFAC( p1, ray->origin, ray->direction, m_dist);
- if(SweepingSphereIntersectsTriangleUV(p0, p1, radius, v0, v1, v2, &idist, &hit_point))
+ if(SweepingSphereIntersectsTriangleUV(ray->origin, p1, radius, v0, v1, v2, &idist, &hit_point))
{
return idist * m_dist;
}
@@ -149,6 +146,9 @@
data->sphere_radius = cast_radius;
}
+/*
+ * Builds a bvh tree.. where nodes are the vertexs of the given mesh
+ */
static BVHTree* bvhtree_from_mesh_verts(DerivedMesh *mesh, float epsilon)
{
int i;
@@ -167,6 +167,9 @@
return tree;
}
+/*
+ * Builds a bvh tree.. where nodes are the faces of the given mesh. Quads are splitted in 2 triangles
+ */
static BVHTree* bvhtree_from_mesh_tri(DerivedMesh *mesh, float epsilon)
{
int i;
@@ -206,36 +209,46 @@
return tree;
}
-
-static float mesh_tri_nearest_point(void *userdata, int index, const float *co, float *nearest)
+/*
+ * Loads the coordinates of the requested tri
+ */
+static void bvhtree_from_mesh_get_tri(BVHMeshCallbackUserdata* userdata, int index, float **v0, float **v1, float **v2)
{
const BVHMeshCallbackUserdata *data = (BVHMeshCallbackUserdata*) userdata;
MVert *vert = data->vert;
MFace *face = data->face + index / 2;
if(index & 1)
- return nearest_point_in_tri_surface(co, vert[ face->v1 ].co, vert[ face->v3 ].co, vert[ face->v4 ].co, nearest);
+ *v0 = vert[ face->v1 ].co, *v1 = vert[ face->v3 ].co, *v2 = vert[ face->v4 ].co;
else
- return nearest_point_in_tri_surface(co, vert[ face->v1 ].co, vert[ face->v2 ].co, vert[ face->v3 ].co, nearest);
+ *v0 = vert[ face->v1 ].co, *v1 = vert[ face->v2 ].co, *v2 = vert[ face->v3 ].co;
}
+/*
+ * Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_tri.
+ * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
+ */
+static float mesh_tri_nearest_point(void *userdata, int index, const float *co, float *nearest)
+{
+ float *t0, *t1, *t2;
+ bvhtree_from_mesh_get_tri( (BVHMeshCallbackUserdata*)userdata, index, &t0, &t1, &t2);
+ return nearest_point_in_tri_surface(co,t0, t1, t2, nearest);
+}
+
+/*
+ * Callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_tri.
+ * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
+ */
static float mesh_tri_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
- const BVHMeshCallbackUserdata *data = (BVHMeshCallbackUserdata*) userdata;
- MVert *vert = data->vert;
- MFace *face = data->face + index / 2;
-
- const float *t0, *t1, *t2;
float dist;
+ float *t0, *t1, *t2;
- if(index & 1)
- t0 = &vert[ face->v1 ].co, t1 = &vert[ face->v3 ].co, t2 = &vert[ face->v4 ].co;
- else
- t0 = &vert[ face->v1 ].co, t1 = &vert[ face->v2 ].co, t2 = &vert[ face->v3 ].co;
+ bvhtree_from_mesh_get_tri( (BVHMeshCallbackUserdata*)userdata, index, &t0, &t1, &t2);
- dist = sphereray_tri_intersection(ray, data->sphere_radius, hit->dist, t0, t1, t2);
+ dist = sphereray_tri_intersection(ray, ((BVHMeshCallbackUserdata*)userdata)->sphere_radius, hit->dist, t0, t1, t2);
if(dist >= 0 && dist < hit->dist)
{
hit->index = index;
@@ -245,20 +258,18 @@
return dist;
}
+/*
+ * Callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_tri.
+ * Rays are projected as a sphere with the radius configured on userdata.
+ * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
+ */
static float mesh_tri_raycast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
- const BVHMeshCallbackUserdata *data = (BVHMeshCallbackUserdata*) userdata;
- MVert *vert = data->vert;
- MFace *face = data->face + index/2;
-
- const float *t0, *t1, *t2;
float dist;
+ float *t0, *t1, *t2;
- if(index & 1)
- t0 = &vert[ face->v1 ].co, t1 = &vert[ face->v3 ].co, t2 = &vert[ face->v4 ].co;
- else
- t0 = &vert[ face->v1 ].co, t1 = &vert[ face->v2 ].co, t2 = &vert[ face->v3 ].co;
-
+ bvhtree_from_mesh_get_tri( (BVHMeshCallbackUserdata*)userdata, index, &t0, &t1, &t2);
+
dist = ray_tri_intersection(ray, hit->dist, t0, t1, t2);
if(dist >= 0 && dist < hit->dist)
{
@@ -268,6 +279,8 @@
}
return dist;
}
+
+
/*
* Raytree from mesh
*/
@@ -1378,17 +1391,51 @@
Normalize(tmp_no); //(TODO: do we really needed a unit-len normal? and we could know the scale factor before hand?)
hit.index = -1;
- hit.dist = 1000;
+ hit.dist = 1000; //TODO: we should use FLT_MAX here
if(use_normal & MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL)
{
BLI_bvhtree_ray_cast(tree, tmp_co, tmp_no, &hit, callback, &userdata);
+
+ if(hit.index != -1)
+ {
+ float *v0, *v1, *v2;
+ float facenormal[3], dot;
+
+ bvhtree_from_mesh_get_tri(&userdata, hit.index, &v0, &v1, &v2);
+ CalcNormFloat(v0, v1, v2, facenormal);
+ dot = INPR( facenormal, tmp_no);
+
+ if(((calc->smd->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot < 0)
+ || ((calc->smd->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot > 0))
+ {
+ hit.index = -1;
+ hit.dist = 1000; //TODO: we should use FLT_MAX here
+ }
+ }
}
if(use_normal & MOD_SHRINKWRAP_ALLOW_INVERTED_NORMAL)
{
float inv[3] = { -tmp_no[0], -tmp_no[1], -tmp_no[2] };
BLI_bvhtree_ray_cast(tree, tmp_co, inv, &hit, callback, &userdata);
+
+ if(hit.index != -1)
+ {
+ float *v0, *v1, *v2;
+ float facenormal[3], dot;
+
+ bvhtree_from_mesh_get_tri(&userdata, hit.index, &v0, &v1, &v2);
+ CalcNormFloat(v0, v1, v2, facenormal);
+ dot = INPR( facenormal, inv);
+
+ if(((calc->smd->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot < 0)
+ || ((calc->smd->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot > 0))
+ {
+ hit.index = -1;
+ hit.dist = 1000; //TODO: we should use FLT_MAX here
+ }
+ }
}
if(hit.index != -1)
More information about the Bf-blender-cvs
mailing list