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
Face *NeighboringEdge(BSPNode *root,Face *face,int eid)
{
	float3 &v0 = face->vertex[eid];
	float3 &v1 = face->vertex[(eid+1)%face->vertex.size()];
	assert(v0 != v1);
	float3 s = (v0+v1)/2.0f;
	float3 fnxe = cross((v1 - v0), face->xyz());  // points away from face's interior
	float4 p0 = *face;
	int f;
	while ((f = PlaneTest(float4(root->xyz(), root->w), s)))
	{
		root=(f==OVER)?root->over.get():root->under.get();
		assert(!root->isleaf);
	}
	std::vector<BSPNode *> stack;
	stack.push_back(root);
	while(stack.size())
	{
		BSPNode *n=Pop(stack);
		if(n->isleaf==OVER) continue;
		if(n->isleaf==UNDER)
		{
			for(unsigned int i=0;i<n->brep.size();i++)
			{
				Face *f = &n->brep[i];
				if(f==face) continue;
				for(unsigned int j=0;j<f->vertex.size();j++)
				{
					int j1 = (j+1)%f->vertex.size();
					if(magnitude(f->vertex[j]-v1)<0.001f && magnitude(f->vertex[j1]-v0)<0.001f)
					{
						NeighboringEdgeNode=n;
						NeighboringEdgeId=j;
						NeighboringEdgeFace=f;
						return f;
					}
				}
			}
			continue;
		}
		assert(!n->isleaf);
		f = PlaneTest(float4(n->xyz(), n->w), s);
		if(!(f&OVER))  stack.push_back(n->under.get());
		if(!(f&UNDER)) stack.push_back(n->over.get());
	}
	assert(0);
	return NULL;
}
Example #3
0
int SplitTest(ConvexH &convex,const btPlane &plane) {
	int flag=0;
	for(int i=0;i<convex.vertices.size();i++) {
		flag |= PlaneTest(plane,convex.vertices[i]);
	}
	return flag;
}
Example #4
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 #5
0
Face FaceNewQuad(const float3 &v0,const float3 &v1,const float3 &v2,const float3 &v3)
{
	Face f;
    f.vertex = {v0,v1,v2,v3};
	f.xyz() = normalize(cross(v1 - v0, v2 - v1) + cross(v3 - v2, v0 - v3));
	f.w = -dot(f.xyz(), (v0 + v1 + v2 + v3) / 4.0f);
    for(auto & v : f.vertex) assert(!PlaneTest(f.plane(), v, PAPERWIDTH)); // must be coplanar
	FaceExtractMatVals(&f,v0,v1,v3,float2(0,0),float2(1,0),float2(0,1));
	f.gu = normalize(f.gu);
	f.gv = normalize(f.gv);
	f.ot = float3(0,0,0);
	return f;
}
Example #6
0
Face FaceClip(Face && face,const float4 &clip) {
	assert(FaceSplitTest(face, clip) == SPLIT);
	FaceSlice(face,clip);
	std::vector<float3> tmp;
	for(unsigned int i=0;i<face.vertex.size();i++){
		if (PlaneTest(clip, face.vertex[i]) != OVER) {
			tmp.push_back(face.vertex[i]);
		}
	}
	face.vertex.clear();
	for (unsigned int i = 0; i<tmp.size(); i++){
		face.vertex.push_back(tmp[i]);
	}
	return face;
}
Example #7
0
void Test() {
	TimerTest().ExecuteTest();
	FoldTest().ExecuteTest();
	SolidUnionTest().ExecuteTest();
	BoundingSolidTest().ExecuteTest();
	SolidIntersectionTest().ExecuteTest();
	MaybeTest().ExecuteTest();
	PlaneTest().ExecuteTest();
	TransformationAdapterTest().ExecuteTest();
	SphereTest().ExecuteTest();
	InheritableTest().ExecuteTest();
	AutoTest().ExecuteTest();
	UtilitiesTest().ExecuteTest();
	PolynomialTest().ExecuteTest();
	ProjectionPlaneTest().ExecuteTest();
	Vector3dTest().ExecuteTest();
	ColorTest().ExecuteTest();
}
Example #8
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);
}
Example #9
0
int FaceSplitTest(const Face & face, const float4 &splitplane,float epsilon)
{
	int flag = COPLANAR;  // 0
	for (const auto & v : face.vertex) flag |= PlaneTest(splitplane, v, epsilon);
	return flag;
}