public OctreeNode Run(OctreeNode a, OctreeNode b) { if (a.State == NodeState.Empty && b.State == NodeState.Empty) { return EmptyEmpty(a, b); } if (a.State == NodeState.Empty && b.State == NodeState.Filled) { return EmptyFilled(a, b); } if (a.State == NodeState.Empty && b.State == NodeState.Partial) { return EmptyPartial(a, b); } if (a.State == NodeState.Filled && b.State == NodeState.Empty) { return FilledEmpty(a, b); } if (a.State == NodeState.Filled && b.State == NodeState.Filled) { return FilledFilled(a, b); } if (a.State == NodeState.Filled && b.State == NodeState.Partial) { return FilledPartial(a, b); } if (a.State == NodeState.Partial && b.State == NodeState.Empty) { return PartialEmpty(a, b); } if (a.State == NodeState.Partial && b.State == NodeState.Filled) { return PartialFilled(a, b); } if (a.State == NodeState.Partial && b.State == NodeState.Partial) { return PartialPartial(a, b); } throw new Exception(); }
public IModel Generate() { var s1 = new Sphere { Center = Vect3.Zero, Radius = 4 }; var s2 = new Sphere { Center = new Vect3(-3, -3, -3), Radius = 4 }; var b = new OctreeNode(Vect3.Zero, 16, 8); var t1 = b.Intersect(node => { if (node.AABB.Inside(s1)) return OctreeNode.NodeIntersectResult.Inside; if (s1.Intersects(node.AABB)) return OctreeNode.NodeIntersectResult.True; return OctreeNode.NodeIntersectResult.False; }); var t2 = b.Intersect(node => { if (node.AABB.Inside(s2)) return OctreeNode.NodeIntersectResult.Inside; if (s2.Intersects(node.AABB)) return OctreeNode.NodeIntersectResult.True; return OctreeNode.NodeIntersectResult.False; }); return new OctreeModel(t1.Subtract(t2), "Test Octree"); return new OctreeModel( new OctreeNode(Vect3.Zero, 16.0, 9).Intersect(s1), "Test Octree"); }
protected override OctreeNode PartialPartial(OctreeNode a, OctreeNode b) { return new OctreeNode(a.Center, a.Size, a.Children.Zip(b.Children, new SubtractOperation().Run).ToArray(), a.Level, a.MaxLevel); }
protected override OctreeNode PartialFilled(OctreeNode a, OctreeNode b) { return new OctreeNode(a.Center, a.Size, NodeState.Empty, a.Level, a.MaxLevel); }
public static OctreeNode Subtract(this OctreeNode a, OctreeNode b) { return new SubtractOperation().Run(a, b); }
protected abstract OctreeNode PartialFilled(OctreeNode a, OctreeNode b);
protected abstract OctreeNode FilledPartial(OctreeNode a, OctreeNode b);
protected abstract OctreeNode FilledEmpty(OctreeNode a, OctreeNode b);
protected abstract OctreeNode EmptyFilled(OctreeNode a, OctreeNode b);
protected override OctreeNode FilledPartial(OctreeNode a, OctreeNode b) { return a; }
protected override OctreeNode EmptyPartial(OctreeNode a, OctreeNode b) { return b; }
protected override OctreeNode EmptyFilled(OctreeNode a, OctreeNode b) { return b; }
/* * b * |E|F|P * E|a|b|b * a F|a|a|a * P|a|b|r */ protected override OctreeNode EmptyEmpty(OctreeNode a, OctreeNode b) { return a; }
public static OctreeNode Union(this OctreeNode a, OctreeNode b) { return new UnionOperation().Run(a, b); }
protected override OctreeNode PartialFilled(OctreeNode a, OctreeNode b) { return b; }
protected abstract OctreeNode EmptyEmpty(OctreeNode a, OctreeNode b);
protected override OctreeNode FilledPartial(OctreeNode a, OctreeNode b) { return new OctreeNode(a.Center, a.Size, new OctreeNode(a.Center, a.Size, a.CreateChildren(NodeState.Filled), a.Level, a.MaxLevel).Children.Zip(b.Children, new IntersectOperation().Run).ToArray(), a.Level, a.MaxLevel); }
protected abstract OctreeNode EmptyPartial(OctreeNode a, OctreeNode b);
protected override OctreeNode PartialFilled(OctreeNode a, OctreeNode b) { return FilledPartial(b, a); }
protected abstract OctreeNode FilledFilled(OctreeNode a, OctreeNode b);
protected override OctreeNode FilledEmpty(OctreeNode a, OctreeNode b) { return a; }
protected abstract OctreeNode PartialEmpty(OctreeNode a, OctreeNode b);
protected override OctreeNode PartialEmpty(OctreeNode a, OctreeNode b) { return a; }
protected abstract OctreeNode PartialPartial(OctreeNode a, OctreeNode b);
public static OctreeNode Intersect(this OctreeNode a, OctreeNode b) { return new IntersectOperation().Run(a, b); }