anchor.diff:          granularity : float
       }
   
  +    override x.GetHashCode() = x.id.GetHashCode()
  +    override x.Equals o =
  +        match o with
  +            | :? Node<'a> as o -> x.id.Equals(o.id)
  +            | _ -> false
  +
  +
   type IDataProvider<'a when 'a : equality> =
       abstract member BoundingBox : Box3d
       abstract member Traverse : (Node<'a> -> bool) -> unit
       abstract member GetData : node : 'a -> count : int -> Async<IndexedGeometry>
   
  -type DummyDataProvider(root : GridCell) =
  +
  +type DummyDataProvider(root : Box3d) =
       
  -    interface IDataProvider<GridCell> with
  -        member x.BoundingBox = root.Box
  +    interface IDataProvider<Box3d> with
  +        member x.BoundingBox = root
   
           member x.Traverse f =
  -            let rec traverse (b : GridCell) =
  -                let box = b.Box
  +            let rec traverse (level : int) (b : Box3d) =
  +                let box = b
                   let n = 100.0
                   let node = { id = b; bounds = box; inner = true; granularity = Fun.Cbrt(box.Volume / (n*n*n)) }
  +
                   if f node then
  -                    b.Children |> List.iter traverse
  +                    let center = b.Center
  +
  +                    let children =
  +                        let l = b.Min
  +                        let u = b.Max
  +                        let c = center
  +                        [
  +                            Box3d(V3d(l.X, l.Y, l.Z), V3d(c.X, c.Y, c.Z))
  +                            Box3d(V3d(c.X, l.Y, l.Z), V3d(u.X, c.Y, c.Z))
  +                            Box3d(V3d(l.X, c.Y, l.Z), V3d(c.X, u.Y, c.Z))
  +                            Box3d(V3d(c.X, c.Y, l.Z), V3d(u.X, u.Y, c.Z))
  +                            Box3d(V3d(l.X, l.Y, c.Z), V3d(c.X, c.Y, u.Z))
  +                            Box3d(V3d(c.X, l.Y, c.Z), V3d(u.X, c.Y, u.Z))
  +                            Box3d(V3d(l.X, c.Y, c.Z), V3d(c.X, u.Y, u.Z))
  +                            Box3d(V3d(c.X, c.Y, c.Z), V3d(u.X, u.Y, u.Z))
  +                        ]
  +
  +                    children |> List.iter (traverse (level + 1))
                   else
                       ()
  -            traverse root
  -
  -        member x.GetData (cell : GridCell) (count : int) =
  +            traverse 0 root
  +
  +        member x.GetData (cell : Box3d) (count : int) =
               async {
                   return IndexedGeometry()
               }
  
positive.code: // ===================================================================================
  // example usage
  // ===================================================================================
  let data = DummyDataProvider(GridCell(V3l.OOO, 4)) :> IDataProvider<_>
  
  [<AutoOpen>]
  module Camera =
  
negative.code:         )
  
      let randomColor() =
          C4b(128 + rand.Next(127) |> byte, 128 + rand.Next(127) |> byte, 128 + rand.Next(127) |> byte, 255uy)
      let randomColor2(alpha) =
          C4b(rand.Next(255) |> byte, rand.Next(255) |> byte, rand.Next(255) |> byte, alpha)
  
      let box (color : C4b) (box : Box3d) =
  
  