Beispiel #1
0
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;
	}
}