93 lines
2.5 KiB
Standard ML
93 lines
2.5 KiB
Standard ML
|
|
signature POINTER_QUAD_FOLDER =
|
||
|
|
sig
|
||
|
|
type env
|
||
|
|
type state
|
||
|
|
|
||
|
|
val fold: int * env * state -> state
|
||
|
|
end
|
||
|
|
|
||
|
|
signature MAKE_POINTER_QUAD_TREE_FOLD =
|
||
|
|
sig
|
||
|
|
structure Fn: POINTER_QUAD_FOLDER
|
||
|
|
|
||
|
|
val foldRegion: int * int * int * int *
|
||
|
|
Fn.env * Fn.state * {tree: PointerQuadTreeType.t, width: int, height: int}
|
||
|
|
-> Fn.state
|
||
|
|
end
|
||
|
|
|
||
|
|
functor MakePointerQuadTreeFold(Fn: POINTER_QUAD_FOLDER): MAKE_POINTER_QUAD_TREE_FOLD =
|
||
|
|
struct
|
||
|
|
structure Fn = Fn
|
||
|
|
|
||
|
|
open PointerQuadTreeType
|
||
|
|
|
||
|
|
fun foldRegionList (rx, ry, rw, rh, env, state, lst) =
|
||
|
|
case lst of
|
||
|
|
item :: tl =>
|
||
|
|
let
|
||
|
|
val state =
|
||
|
|
if isCollidingItem (rx, ry, rw, rh, ~1, item) then
|
||
|
|
Fn.fold (#itemID item, env, state)
|
||
|
|
else
|
||
|
|
state
|
||
|
|
in
|
||
|
|
foldRegionList (rx, ry, rw, rh, env, state, tl)
|
||
|
|
end
|
||
|
|
| [] => state
|
||
|
|
|
||
|
|
fun helpFoldRegion (rx, ry, rw, rh, env, state, qx, qy, qw, qh, tree) =
|
||
|
|
case tree of
|
||
|
|
NODE {tl, tr, bl, br} =>
|
||
|
|
let
|
||
|
|
val vtl = visitTopLeft (rx, ry, rw, rh, qx, qy, qw, qh)
|
||
|
|
val vtr = visitTopRight (rx, ry, rw, rh, qx, qy, qw, qh)
|
||
|
|
val vbl = visitBottomLeft (rx, ry, rw, rh, qx, qy, qw, qh)
|
||
|
|
val vbr = visitBottomRight (rx, ry, rw, rh, qx, qy, qw, qh)
|
||
|
|
|
||
|
|
val hw = qw div 2
|
||
|
|
val hh = qh div 2
|
||
|
|
|
||
|
|
val state =
|
||
|
|
if vtl then
|
||
|
|
helpFoldRegion
|
||
|
|
(rx, ry, rw, rh, env, state, qx, qy, hw, hh, tl)
|
||
|
|
else
|
||
|
|
state
|
||
|
|
|
||
|
|
val state =
|
||
|
|
if vtr then
|
||
|
|
helpFoldRegion
|
||
|
|
(rx, ry, rw, rh, env, state, qx + hw, qy, hw, hh, tr)
|
||
|
|
else
|
||
|
|
state
|
||
|
|
|
||
|
|
val state =
|
||
|
|
if vbl then
|
||
|
|
helpFoldRegion
|
||
|
|
(rx, ry, rw, rh, env, state, qx, qy + hh, hw, hh, bl)
|
||
|
|
else
|
||
|
|
state
|
||
|
|
in
|
||
|
|
if vbr then
|
||
|
|
helpFoldRegion
|
||
|
|
(rx, ry, rw, rh, env, state, qw + hw, qy + hh, hw, hh, br)
|
||
|
|
else
|
||
|
|
state
|
||
|
|
end
|
||
|
|
| LEAF item =>
|
||
|
|
if isCollidingItem (rx, ry, rw, rh, ~1, item) then
|
||
|
|
Fn.fold (#itemID item, env, state)
|
||
|
|
else
|
||
|
|
state
|
||
|
|
| EMPTY => state
|
||
|
|
| SHARE_LEAF items => foldRegionList (rx, ry, rw, rh, env, state, items)
|
||
|
|
|
||
|
|
fun foldRegion (rx, ry, rw, rh, env, state, tree) =
|
||
|
|
let
|
||
|
|
val {width, height, tree} = tree
|
||
|
|
in
|
||
|
|
helpFoldRegion (rx, ry, rw, rh, env, state, 0, 0, width, height, tree)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|