/// <summary> /// 交运算 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static Bounds3 Intersect(Bounds3 a, Bounds3 b) { return(new Bounds3( new Vector3f(Math.Max(a.pMin.X, b.pMin.X), Math.Max(a.pMin.Y, b.pMin.Y), Math.Max(a.pMin.Z, b.pMin.Z)), new Vector3f(Math.Min(a.pMax.X, b.pMax.X), Math.Min(a.pMax.Y, b.pMax.Y), Math.Min(a.pMax.Z, b.pMax.Z)) )); }
/// <summary> /// 并运算 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static Bounds3 Union(Bounds3 a, Vector3f b) { Bounds3 ret = new Bounds3(); ret.pMin = Vector3f.Min(a.pMin, b); ret.pMax = Vector3f.Max(a.pMax, b); return(ret); }
public static BVH Build <T>(Span <T> objs) where T : RenderObject { Bounds3 boundbox = objs[0].BoundBox; foreach (var item in objs) { boundbox = Bounds3.Union(boundbox, item.BoundBox); } BVH re = new BVH() { BoundBox = boundbox }; if (objs.Length < 5) { re.Childs = objs.ToArray(); goto RTPoint; //return re; } int divideWay = 0; { Vector3f v = boundbox.pMax - boundbox.pMin; if (v.X < v.Y) { if (v.Y < v.Z) { divideWay = 2; } else { divideWay = 1; } } else { if (v.X < v.Z) { divideWay = 2; } else { divideWay = 0; } } } int dividePoint = -1; if (divideWay == 0) { dividePoint = QuickCoordationX(objs); } else if (divideWay == 1) { dividePoint = QuickCoordationY(objs); } else { dividePoint = QuickCoordationZ(objs); } BVH l = Build(objs.Slice(0, dividePoint)); BVH r = Build(objs.Slice(dividePoint)); re.Childs = new IRayCastAble[] { l, r }; RTPoint: return(re); }