* converted raytrace visibility test on meshlaplacian.c to new raytrace API
authorAndre Susano Pinto <andresusanopinto@gmail.com>
Thu, 17 Sep 2009 12:56:16 +0000 (12:56 +0000)
committerAndre Susano Pinto <andresusanopinto@gmail.com>
Thu, 17 Sep 2009 12:56:16 +0000 (12:56 +0000)
I need test scenes and test instructions to make sure this is ok, since i have no idea how to test this feature.

source/blender/editors/armature/meshlaplacian.c
source/blender/render/extern/include/RE_raytrace.h
source/blender/render/intern/include/rayobject.h
source/blender/render/intern/source/rayobject.c

index 7f95fb47d6177eb7cc51a1ba8c493d98c6625711..c994f7789a008139ad42d3c2cad3435e776a5317 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <math.h>
 #include <string.h>
-#include <assert.h>
 
 #include "MEM_guardedalloc.h"
 
@@ -107,7 +106,8 @@ struct LaplacianSystem {
                float *mindist;         /* minimum distance to a bone for all vertices */
                
                RayObject *raytree;     /* ray tracing acceleration structure */
-               MFace **vface;          /* a face that the vertex belongs to */
+               RayFace   *faces;       /* faces to add to the ray tracing struture */
+               MFace     **vface;      /* a face that the vertex belongs to */
        } heat;
 
 #ifdef RIGID_DEFORM
@@ -398,14 +398,25 @@ float laplacian_system_get_solution(int v)
 static void heat_ray_tree_create(LaplacianSystem *sys)
 {
        Mesh *me = sys->heat.mesh;
-       MFace *mface;
        int a;
 
-       assert(0); //TODO
-       //sys->heat.raytree = RE_rayobject_mesh_create(me, me);
-
+       sys->heat.raytree = RE_rayobject_vbvh_create(me->totface);
+       sys->heat.faces = MEM_callocN(sizeof(RayFace)*me->totface, "Heat RayFaces");
        sys->heat.vface = MEM_callocN(sizeof(MFace*)*me->totvert, "HeatVFaces");
-       for(a=0, mface=me->mface; a<me->totface; a++, mface++) {
+
+       for(a=0; a<me->totface; a++) {
+       
+               MFace *mface = me->mface+a;
+               RayFace *rayface = sys->heat.faces+a;
+
+               RayObject *obj = RE_rayface_from_coords(
+                                                       rayface, me, mface,
+                                                       sys->heat.verts[mface->v1], sys->heat.verts[mface->v2],
+                                                       sys->heat.verts[mface->v3], mface->v4 ? sys->heat.verts[mface->v4] : 0
+                                               );
+               RE_rayobject_add(sys->heat.raytree, obj); 
+               
+               //Setup inverse pointers to use on isect.orig
                sys->heat.vface[mface->v1]= mface;
                sys->heat.vface[mface->v2]= mface;
                sys->heat.vface[mface->v3]= mface;
@@ -420,7 +431,6 @@ static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone)
        float end[3];
        int visible;
 
-       assert( 0 );
        mface= sys->heat.vface[vertex];
        if(!mface)
                return 1;
@@ -429,23 +439,18 @@ static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone)
        memset(&isec, 0, sizeof(isec));
        isec.mode= RE_RAY_SHADOW;
        isec.lay= -1;
+       isec.orig.ob = sys->heat.mesh;
        isec.orig.face = mface;
        isec.skip = RE_SKIP_CULLFACE;
+       
 
        VECCOPY(isec.start, sys->heat.verts[vertex]);
        PclosestVL3Dfl(end, isec.start, sys->heat.root[bone], sys->heat.tip[bone]);
 
        VECSUB(isec.vec, end, isec.start);
-       isec.labda = 1.0f;
+       isec.labda = 1.0f - 1e-5;
+       VECADDFAC( isec.start, isec.start, isec.vec, 1e-5);
 
-#if 0
-       TODO
-       /* add an extra offset to the start position to avoid self intersection */
-       VECCOPY(dir, isec.vec);
-       Normalize(dir);
-       VecMulf(dir, 1e-5);
-       VecAddf(isec.start, isec.start, dir);
-#endif 
        visible= !RE_rayobject_raycast(sys->heat.raytree, &isec);
 
        return visible;
@@ -712,6 +717,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones,
 
        RE_rayobject_free(sys->heat.raytree);
        MEM_freeN(sys->heat.vface);
+       MEM_freeN(sys->heat.faces);
 
        MEM_freeN(sys->heat.mindist);
        MEM_freeN(sys->heat.H);
index af3ea8e2ac0973b06b1534b4283b3e1f5820ef29..fe490461da0713792d610d4c16f65154674fe836 100644 (file)
@@ -79,6 +79,28 @@ RayObject* RE_rayobject_svbvh_create(int size);              /* raytrace/rayobject_svbvh.c *
 RayObject* RE_rayobject_bih_create(int size);          /* rayobject_bih.c */
 
 
+/*
+ * This ray object represents a triangle or a quad face.
+ * All data needed to realize intersection is "localy" available.
+ */
+typedef struct RayFace
+{
+       float v1[4], v2[4], v3[4], v4[3];
+       int quad;
+       void *ob;
+       void *face;
+       
+} RayFace;
+
+#define RE_rayface_isQuad(a) ((a)->quad)
+struct VlakRen;
+struct ObjectInstanceRen;
+
+RayObject* RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr);
+RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *co1, float *co2, float *co3, float *co4);
+
+
+
 typedef struct LCTSHint LCTSHint;
 struct LCTSHint
 {
index 19608fba262432a7feb88d57efa14fa01d04045f..dbd68fe8b8b2a9bba816fa809d3f48e6cd9fe3e0 100644 (file)
@@ -102,25 +102,6 @@ typedef struct RayVlak
 } RayVlak;
  */
 
-/*
- * This ray object represents a triangle or a quad face.
- * All data needed to realize intersection is "localy" available.
- */
-typedef struct RayFace
-{
-       float v1[4], v2[4], v3[4], v4[3];
-       int quad;
-       void *ob;
-       void *face;
-       
-} RayFace;
-
-#define RE_rayface_isQuad(a) ((a)->quad)
-/* Loads a VlakRen on a RayFace */
-void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr);
-
-
-
 /*
  * This rayobject represents a generic object. With it's own callbacks for raytrace operations.
  * It's suitable to implement things like LOD.
index 4bd8a12aa01d0b0a15bc2d0d82383fe661b62f39..df457a371238a45af241e79cd9734b8601fbea01 100644 (file)
@@ -165,6 +165,17 @@ static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen
                return 0;
 }
 
+static int rayface_check_cullface(RayFace *face, Isect *is)
+{
+       float nor[3];
+       
+       /* don't intersect if the ray faces along the face normal */
+       if(face->quad) CalcNormFloat4(face->v1, face->v2, face->v3, face->v4, nor);
+       else CalcNormFloat(face->v1, face->v2, face->v3, nor);
+
+       return (INPR(nor, is->vec) < 0);
+}
+
 /* ray - triangle or quad intersection */
 /* this function shall only modify Isect if it detects an hit */
 static int intersect_rayface(RayFace *face, Isect *is)
@@ -188,6 +199,11 @@ static int intersect_rayface(RayFace *face, Isect *is)
                if(vlr_check_intersect_solid(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0)
                        return 0;
        }
+       if(is->skip & RE_SKIP_CULLFACE)
+       {
+               if(rayface_check_cullface(face, is) == 0)
+                       return 0;
+       }
 
        RE_RC_COUNT(is->raycounter->faces.test);
 
@@ -319,26 +335,32 @@ static int intersect_rayface(RayFace *face, Isect *is)
        return 0;
 }
 
-void RE_rayface_from_vlak(RayFace *face, ObjectInstanceRen *obi, VlakRen *vlr)
+RayObject* RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
+{
+       return RE_rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0 );
+}
+
+RayObject* RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
 {
-       VECCOPY(face->v1, vlr->v1->co);
-       VECCOPY(face->v2, vlr->v2->co);
-       VECCOPY(face->v3, vlr->v3->co);
-       if(vlr->v4)
+       rayface->ob = ob;
+       rayface->face = face;
+
+       VECCOPY(rayface->v1, v1);
+       VECCOPY(rayface->v2, v2);
+       VECCOPY(rayface->v3, v3);
+       if(v4)
        {
-               VECCOPY(face->v4, vlr->v4->co);
-               face->quad = 1;
+               VECCOPY(rayface->v4, v4);
+               rayface->quad = 1;
        }
        else
        {
-               face->quad = 0;
+               rayface->quad = 0;
        }
 
-       face->ob   = obi;
-       face->face = vlr;
+       return RE_rayobject_unalignRayFace(rayface);
 }
 
-
 int RE_rayobject_raycast(RayObject *r, Isect *isec)
 {
        int i;