* converted raytrace visibility test on meshlaplacian.c to new raytrace API
I need test scenes and test instructions to make sure this is ok, since i have no idea how to test this feature.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
VECCOPY(face->v1, vlr->v1->co);
|
||||
VECCOPY(face->v2, vlr->v2->co);
|
||||
VECCOPY(face->v3, vlr->v3->co);
|
||||
if(vlr->v4)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user