//从“列表”中构建一个BSP树。当调用现有树时,新多边形被过滤到树的底部,
// 并在那里成为新的节点
public void Build(List<CSG_Polygon> list)//建BSP树
{
if (list.Count < 1)//判断是否有图形
return;
if (this.plane == null || !this.plane.Valid())
{
this.plane = new CSG_Plane();
this.plane.normal = list[0].plane.normal;
this.plane.w = list[0].plane.w;
}
if(this.polygons == null)
this.polygons = new List<CSG_Polygon>();
List<CSG_Polygon> list_front = new List<CSG_Polygon>();//正面
List<CSG_Polygon> list_back = new List<CSG_Polygon>();//背面
for (int i = 0; i < list.Count; i++)
{
this.plane.SplitPolygon(list[i], this.polygons, this.polygons, list_front, list_back);
}
if (list_front.Count > 0)
{
if (this.front == null)
this.front = new CSG_Node();
this.front.Build(list_front);//从正面做一个BSP树
}
if (list_back.Count > 0)
{
if (this.back == null)
this.back = new CSG_Node();
this.back.Build(list_back);//从背面做一棵树
}
}
public bool Valid()
{
return normal.magnitude > 0f;
}
/*如果需要的话,按这个平面分割“多边形”,然后将多边形或多边形片段放入适当的列表中。
根据共面多边形相对于这个平面的方向,它们可以分为“共面前”或“共面后”*/
public void SplitPolygon(CSG_Polygon polygon, List<CSG_Polygon> coplanarFront, List<CSG_Polygon> coplanarBack, List<CSG_Polygon> front, List<CSG_Polygon> back)
{
EPolygonType polygonType = 0;
List<EPolygonType> types = new List<EPolygonType>();//节点类型数组
for (int i = 0; i < polygon.vertices.Count; i++)
{
float t = Vector3.Dot(this.normal, polygon.vertices[i].position) - this.w;
/*
enum EPolygonType
{
Coplanar = 0,//共面
Front = 1,//前面
Back = 2,//后面
Spanning = 3 /// 3 is Front | Back - not a separate entry
};
*/
EPolygonType type = (t < -CSG.EPSILON) ? EPolygonType.Back : ((t > CSG.EPSILON) ? EPolygonType.Front : EPolygonType.Coplanar);//判断这个节点的类型
polygonType |= type;
types.Add(type);
}
// 将多边形放入正确的列表中,必要时将其分割。
switch (polygonType)
{
case EPolygonType.Coplanar:
{
if ( Vector3.Dot(this.normal, polygon.plane.normal) > 0)
coplanarFront.Add(polygon);
else
coplanarBack.Add(polygon);
}
break;
case EPolygonType.Front:
{
front.Add(polygon);
}
break;
case EPolygonType.Back:
{
back.Add(polygon);
}
break;
//再次分类
case EPolygonType.Spanning:
{
List<CSG_Vertex> f = new List<CSG_Vertex>();//前面
List<CSG_Vertex> b = new List<CSG_Vertex>();//背面
for (int i = 0; i < polygon.vertices.Count; i++)
{
int j = (i + 1) % polygon.vertices.Count;
EPolygonType ti = types[i], tj = types[j];
CSG_Vertex vi = polygon.vertices[i], vj = polygon.vertices[j];
if (ti != EPolygonType.Back)
{
f.Add(vi);
}
if (ti != EPolygonType.Front)
{
b.Add(vi);
}
if ((ti | tj) == EPolygonType.Spanning)
{
float t = (this.w - Vector3.Dot(this.normal, vi.position)) / Vector3.Dot(this.normal, vj.position - vi.position);
CSG_Vertex v = CSG_Vertex.Interpolate(vi, vj, t);
f.Add(v);
b.Add(v);
}
}
//三点构成一个面
if (f.Count >= 3)
{
front.Add( new CSG_Polygon(f) );
}
if (b.Count >= 3)
{
back.Add( new CSG_Polygon(b) );
}
}
break;
}
}
建BSP 树分割图形
最新推荐文章于 2022-09-03 16:03:45 发布