Example #1
0
static void FaceEdgeSplicer(Face & face,int vi0,BSPNode *n)
{
	// the face's edge starting from vertex vi0 is sliced by any incident hypeplane in the bsp
	if(n->isleaf) return;
	int vi1 = (vi0+1)%face.vertex.size();
	float3 v0 = face.vertex[vi0];
	float3 v1 = face.vertex[vi1];
	assert(magnitude(v0-v1) > QUANTIZEDCHECK );
	int f0 = PlaneTest(float4(n->xyz(), n->w), v0);
	int f1 = PlaneTest(float4(n->xyz(), n->w), v1);
	if(f0==COPLANAR && f1== COPLANAR)
	{
		// have to pass down both sides, but we have to make sure we do all subsegments generated by the first side
		int count = face.vertex.size();
		FaceEdgeSplicer(face,vi0,n->under.get());
		int k=vi0 + (face.vertex.size()-count);
		while(k>=vi0)
		{
			FaceEdgeSplicer(face,k,n->over.get());
			k--;
		}
	}
	else if((f0|f1) == UNDER)
	{
		FaceEdgeSplicer(face,vi0,n->under.get());
	}
	else if((f0|f1) == OVER)
	{
		FaceEdgeSplicer(face,vi0,n->over.get());
	}
	else
	{
		edgesplitcount++;
		assert(magnitude(v0-v1) > QUANTIZEDCHECK);
		assert((f0|f1) == SPLIT);
		float3 vmid = PlaneLineIntersection(*n,v0,v1);
		assert(magnitude(vmid-v1) > QUANTIZEDCHECK);
		assert(magnitude(v0-vmid) > QUANTIZEDCHECK);
		int fmid = PlaneTest(float4(n->xyz(), n->w), vmid);
		assert(fmid==0);
		face.vertex.insert(face.vertex.begin() + vi0 + 1, vmid); //  Insert(face.vertex, vmid, vi0 + 1);
		if(f0==UNDER)
		{
			FaceEdgeSplicer(face,vi0+1,n->over.get());
			FaceEdgeSplicer(face,vi0  ,n->under.get());
		}
		else
		{
			assert(f0==OVER);
			FaceEdgeSplicer(face,vi0+1,n->under.get());
			FaceEdgeSplicer(face,vi0  ,n->over.get());
		}
	}
	
}
Example #2
0
btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint, btVector3 *vpoint)
{
	static btVector3 cp;
	cp = cross(udir,vdir).normalized();

	btScalar distu = -dot(cp,ustart);
	btScalar distv = -dot(cp,vstart);
	btScalar dist = (btScalar)fabs(distu-distv);
	if(upoint) 
		{
		btPlane plane;
		plane.normal = cross(vdir,cp).normalized();
		plane.dist = -dot(plane.normal,vstart);
		*upoint = PlaneLineIntersection(plane,ustart,ustart+udir);
	}
	if(vpoint) 
		{
		btPlane plane;
		plane.normal = cross(udir,cp).normalized();
		plane.dist = -dot(plane.normal,ustart);
		*vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir);
	}
	return dist;
}
Example #3
0
void FaceSlice(Face & face,const float4 &clip) {
	int count=0;
	for(unsigned int i=0;i<face.vertex.size();i++) {
		unsigned int i2=(i+1)%face.vertex.size();
		int   vf0 = PlaneTest(clip, face.vertex[i]);
		int   vf2 = PlaneTest(clip, face.vertex[i2]);
		if((vf0==OVER  && vf2==UNDER)||
		   (vf0==UNDER && vf2==OVER )  )
		{
			float3 vmid;
			vmid = PlaneLineIntersection(clip,face.vertex[i],face.vertex[i2]);
			assert(!PlaneTest(clip, vmid));
			face.vertex.insert(face.vertex.begin() + i2, vmid); //  Insert(face.vertex, vmid, i2);
			i=0;	
			assert(count<2);
			count++;
		}
	}
}
Example #4
0
static void BSPClipFace(BSPNode *n,Face && face,const float3 &position,std::vector<Face> &under,std::vector<Face> &over)
{
	if(n->isleaf==UNDER)
	{
		under.push_back(face);
		return;
	}
	if(n->isleaf==OVER)
	{
		over.push_back(face);
		return;
	}
	float4 plane(n->xyz(), n->w + dot(position, n->xyz()));
	int flag = FaceSplitTest(face, plane);
	if(flag == UNDER) {
		return BSPClipFace(n->under.get(),std::move(face),position,under,over);
	}
	if(flag == OVER) {
		return BSPClipFace(n->over.get(),std::move(face),position,under,over);
	}
	if(flag==COPLANAR)
	{
		return BSPClipFace(dot(n->xyz(), face.xyz()) > 0 ? n->under.get() : n->over.get(), std::move(face), position, under, over);
	}
	assert(flag==SPLIT);
	
	Face funder, fover;
	fover.xyz() = funder.xyz() = face.xyz();
	fover.w  = funder.w = face.w;
	fover.gu   = funder.gu   = face.gu;
	fover.gv   = funder.gv   = face.gv;
	fover.ot   = funder.ot   = face.ot;
	fover.matid= funder.matid= face.matid;
	for(unsigned int i=0;i<face.vertex.size();i++){
		float3& vi = face.vertex[i];
		float3& vi1= face.vertex[(i+1)%face.vertex.size()];
		int vf  = PlaneTest(float4(plane.xyz(), plane.w), vi);
		int vf1 = PlaneTest(float4(plane.xyz(), plane.w), vi1);
		if(vf==COPLANAR) 
		{
			funder.vertex.push_back(vi);
			fover.vertex.push_back(vi);
			continue;   // possible loop optimization
		}
		else if(vf==UNDER)
		{
			funder.vertex.push_back(vi);
		}
		else 
		{
			assert(vf==OVER);
			fover.vertex.push_back(vi);
		}
		if(vf != vf1 && vf !=COPLANAR && vf1 != COPLANAR)
		{
			float3 vmid = PlaneLineIntersection(plane.xyz(), plane.w, vi, vi1);
			funder.vertex.push_back(vmid);
			fover.vertex.push_back(vmid);
		}
	}
	BSPClipFace(n->under.get(),std::move(funder),position,under,over);
	BSPClipFace(n->over.get() ,std::move(fover) ,position,under,over);
}