static int meshdeform_intersect(MeshDeformBind *mdb, MeshDeformIsect *isec) { MFace *mface; float face[4][3], co[3], uvw[3], len, nor[3], end[3]; int f, hit, is= 0, totface; isec->labda= 1e10; mface= mdb->cagedm->getFaceArray(mdb->cagedm); totface= mdb->cagedm->getNumFaces(mdb->cagedm); add_v3_v3v3(end, isec->start, isec->vec); for(f=0; f<totface; f++, mface++) { copy_v3_v3(face[0], mdb->cagecos[mface->v1]); copy_v3_v3(face[1], mdb->cagecos[mface->v2]); copy_v3_v3(face[2], mdb->cagecos[mface->v3]); if(mface->v4) { copy_v3_v3(face[3], mdb->cagecos[mface->v4]); hit = meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw); if(hit) { normal_tri_v3( nor,face[0], face[1], face[2]); } else { hit= meshdeform_tri_intersect(isec->start, end, face[0], face[2], face[3], co, uvw); normal_tri_v3( nor,face[0], face[2], face[3]); } } else { hit= meshdeform_tri_intersect(isec->start, end, face[0], face[1], face[2], co, uvw); normal_tri_v3( nor,face[0], face[1], face[2]); } if(hit) { len= len_v3v3(isec->start, co)/len_v3v3(isec->start, end); if(len < isec->labda) { isec->labda= len; isec->face = mface; isec->isect= (INPR(isec->vec, nor) <= 0.0f); is= 1; } } } return is; }
static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { struct MeshRayCallbackData *data = userdata; MeshDeformBind *mdb = data->mdb; const MLoop *mloop = mdb->cagedm_cache.mloop; const MLoopTri *looptri = mdb->cagedm_cache.looptri, *lt; const float (*poly_nors)[3] = mdb->cagedm_cache.poly_nors; MeshDeformIsect *isec = data->isec; float no[3], co[3], end[3], uvw[3], dist; float *face[3]; lt = &looptri[index]; face[0] = mdb->cagecos[mloop[lt->tri[0]].v]; face[1] = mdb->cagecos[mloop[lt->tri[1]].v]; face[2] = mdb->cagecos[mloop[lt->tri[2]].v]; add_v3_v3v3(end, isec->start, isec->vec); if (!meshdeform_tri_intersect(ray->origin, end, UNPACK3(face), co, uvw)) return; if (poly_nors) { copy_v3_v3(no, poly_nors[lt->poly]); } else { normal_tri_v3(no, UNPACK3(face)); } dist = len_v3v3(ray->origin, co) / isec->vec_length; if (dist < hit->dist) { hit->index = index; hit->dist = dist; copy_v3_v3(hit->co, co); isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f); isec->lambda = dist; } }