Added culling on normal projection.
authorAndre Susano Pinto <andresusanopinto@gmail.com>
Sat, 31 May 2008 01:25:24 +0000 (01:25 +0000)
committerAndre Susano Pinto <andresusanopinto@gmail.com>
Sat, 31 May 2008 01:25:24 +0000 (01:25 +0000)
Now renderdemon is happy ;)
and now shrinkwrap can be used for bulging :)

source/blender/blenkernel/intern/shrinkwrap.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/src/buttons_editing.c

index e54b7a8472f2eec71b94f753c2125baf919b1fc0..14ed29d058394d2da6ebffd782173b9a915cc6c2 100644 (file)
@@ -207,8 +207,8 @@ static void raytree_from_mesh_get_coords(RayFace *face, float **v1, float **v2,
        if(((int)face) & 1)     // we want the 2 triangle of the quad
        {
                *v1= raytree_from_mesh_verts[mface->v1].co;
-               *v2= raytree_from_mesh_verts[mface->v4].co;
-               *v3= raytree_from_mesh_verts[mface->v3].co;
+               *v2= raytree_from_mesh_verts[mface->v3].co;
+               *v3= raytree_from_mesh_verts[mface->v4].co;
                *v4= NULL;
        }
        else
@@ -280,10 +280,12 @@ static void free_raytree_from_mesh(RayTree *tree)
  * Cast a ray on the specified direction
  * Returns the distance the ray must travel until intersect something
  * Returns FLT_MAX in case of nothing intersection
+ * if facenormal is given, it will be overwritted with the normal of the face the ray collided with
  */
-static float raytree_cast_ray(RayTree *tree, const float *coord, const float *direction)
+static float raytree_cast_ray(RayTree *tree, const float *coord, const float *direction, float *facenormal)
 {
        Isect isec;
+       float *v1, *v2, *v3, *v4;
 
        /* Setup intersection */
        isec.mode               = RE_RAY_MIRROR; /* We want closest intersection */
@@ -299,6 +301,12 @@ static float raytree_cast_ray(RayTree *tree, const float *coord, const float *di
        if(!RE_ray_tree_intersect(tree, &isec))
                return FLT_MAX;
 
+       if(facenormal)
+       {
+               raytree_from_mesh_get_coords( isec.face, &v1, &v2, &v3, &v4);
+               CalcNormFloat(v1, v2, v3, facenormal);
+       }
+
        isec.labda = ABS(isec.labda);
        VECADDFAC(isec.end, isec.start, isec.vec, isec.labda);
        return VecLenf((float*)coord, (float*)isec.end);
@@ -958,6 +966,7 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
        {
                float dist = FLT_MAX;
                float weight = vertexgroup_get_weight(dvert, i, vgroup);
+               float face_normal[3];
                if(weight == 0.0f) continue;
 
                //Transform coordinates local->target
@@ -970,7 +979,12 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
 
                if(use_normal & MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL)
                {
-                       dist = raytree_cast_ray(target, tmp_co, tmp_no);
+                       dist = raytree_cast_ray(target, tmp_co, tmp_no, face_normal);
+
+                       if((calc->smd->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && INPR(tmp_no, face_normal) < 0)
+                               dist = FLT_MAX;
+                       if((calc->smd->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && INPR(tmp_no, face_normal) > 0)
+                               dist = FLT_MAX;
                }
 
                normal_short2float(vert[i].no, tmp_no);
@@ -986,7 +1000,12 @@ void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
                        inv[1] = -tmp_no[1];
                        inv[2] = -tmp_no[2];
 
-                       tdist = raytree_cast_ray(target, tmp_co, inv);
+                       tdist = raytree_cast_ray(target, tmp_co, inv, 0);
+
+                       if((calc->smd->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && INPR(tmp_no, face_normal) < 0)
+                               tdist = FLT_MAX;
+                       if((calc->smd->shrinkOpts & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && INPR(tmp_no, face_normal) > 0)
+                               tdist = FLT_MAX;
 
                        if(ABS(tdist) < ABS(dist))
                                dist = -tdist;
index 5178022ffad97c89ade7a3d0f92a33675ea9b8f7..40958f9c68f571bd1786e0ca97700801b91a0aa1 100644 (file)
@@ -509,4 +509,7 @@ typedef struct ShrinkwrapModifierData {
 #define MOD_SHRINKWRAP_ALLOW_INVERTED_NORMAL   (1<<1)
 #define MOD_SHRINKWRAP_REMOVE_UNPROJECTED_FACES        (1<<2)
 
+#define MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE   (1<<3)
+#define MOD_SHRINKWRAP_CULL_TARGET_BACKFACE            (1<<4)
+
 #endif
index b1d2d26bc4628a78fbdfc77f2521892201e733d2..e29588d7cb2954bd995509512c24e126c065744e 100644 (file)
@@ -1830,7 +1830,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                        ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
                        height = 86;
                        if (smd->shrinkType == MOD_SHRINKWRAP_NORMAL)
-                               height += 19*3;
+                               height += 19*5;
                }
                                                        /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
                uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, ""); 
@@ -2458,6 +2458,9 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                                uiDefButBitS(block, TOG, MOD_SHRINKWRAP_ALLOW_DEFAULT_NORMAL, B_MODIFIER_RECALC, "Default normal",      lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Allows vertices to move in the normal direction");
                                uiDefButBitS(block, TOG, MOD_SHRINKWRAP_ALLOW_INVERTED_NORMAL, B_MODIFIER_RECALC, "Invert normal",      lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Allows vertices to move in the inverse direction of their normal");
                                uiDefButBitS(block, TOG, MOD_SHRINKWRAP_REMOVE_UNPROJECTED_FACES, B_MODIFIER_RECALC, "Remove faces",    lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Remove faces where all vertices haven't been projected");
+
+                               uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE, B_MODIFIER_RECALC, "Cull frontfaces",    lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a front face on target");
+                               uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_BACKFACE,  B_MODIFIER_RECALC, "Cull backfaces",     lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a back face on target");
                        }
 
                        but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",         lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0.0, 31.0, 0, 0, "Vertex Group name");