From 91322da5b1b940a7f6e620b388aec5d5d7a0e670 Mon Sep 17 00:00:00 2001 From: tali Date: Mon, 15 Jan 2024 17:39:09 -0500 Subject: [PATCH] ECS WIP: transform tree --- src/adam/adam.ml | 2 +- src/dune | 1 + src/main.ml | 50 ++++++++++++++++++++++-- src/n2/dune | 7 ++++ src/n2/n2.ml | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 src/n2/dune create mode 100644 src/n2/n2.ml diff --git a/src/adam/adam.ml b/src/adam/adam.ml index 0a8cb58..dd43851 100644 --- a/src/adam/adam.ml +++ b/src/adam/adam.ml @@ -109,7 +109,6 @@ module Mat2A = struct dst.a5 <- src.a5; end - (* let[@inline] mul (lhs : t) (rhs : t) : unit = let { a0; a1; a2; a3; a4; a5 } = lhs in begin @@ -121,6 +120,7 @@ module Mat2A = struct lhs.a5 <- (a3 * rhs.a2) + (a4 * rhs.a5) + a5; end + (* let[@inline] tra (dst : t) ~(tx : float) ~(ty : float) = begin dst.a2 <- (dst.a0 * tx) + (dst.a1 * ty) + dst.a2; diff --git a/src/dune b/src/dune index 0f23324..fde31ef 100644 --- a/src/dune +++ b/src/dune @@ -5,5 +5,6 @@ (libraries adam s2 + n2 ohlog)) diff --git a/src/main.ml b/src/main.ml index f6dfef1..fd06135 100644 --- a/src/main.ml +++ b/src/main.ml @@ -1,8 +1,24 @@ -open S2 open Adam +open S2 +open N2 + include (val Ohlog.logs "Main") let main () = + let tfs = Transform.make () in + + let a = Transform.add tfs in + let b = Transform.add tfs ~parent:a in + let c = Transform.add tfs ~parent:a in + + let square = aabb (-50.0) (-50.0) 50.0 50.0 in + + Mat2A.set (Transform.model b) + ~tx:(-5.0) ~ty:(-5.0) ~sx:1.0 ~sy:1.0; + + Mat2A.set (Transform.model c) + ~tx:(+5.0) ~ty:(+5.0) ~sx:1.0 ~sy:1.0; + debug (fun m -> m "initializing"); let window = Window.make ~title:"GEOMETRA" in info (fun m -> m "window initialized"); @@ -10,14 +26,40 @@ let main () = info (fun m -> m "renderer initialized"); let render () = begin - (* let time = Sdl.get_ticks () |> Int32.to_int in *) + (* Update *) + + let time = Sdl.get_ticks () |> Int32.to_int in + let tx = + Float_infix.( + Float.sin (flt time / 1000.0 * 2.0) * 300.0 + + 512.0 + ) + in + let ty = 400.0 in + + Mat2A.set (Transform.model a) + ~tx ~ty ~sx:1.0 ~sy:1.0; + + Transform.update tfs; + + (* Render *) + Renderer.pre_draw ren; Renderer.clear ren (rgb24 0x000000); + Renderer.draw_rect ren - ~tf:(mat2a 100.0 50.0 1.0 1.0) - ~bb:(aabb (-5.0) (-10.0) 50.0 200.0) + ~tf:(Transform.world b) + ~bb:square ~fill:(rgb24 0xff0000); + + Renderer.draw_rect ren + ~tf:(Transform.world c) + ~bb:square + ~fill:(rgb24 0x0055ff); + Renderer.post_draw ren; + + Gc.major (); end in Window.event_loop window ~render; diff --git a/src/n2/dune b/src/n2/dune new file mode 100644 index 0000000..29133e3 --- /dev/null +++ b/src/n2/dune @@ -0,0 +1,7 @@ +(library + (name n2) + (package geometra) + (libraries + adam + s2 + ohlog)) diff --git a/src/n2/n2.ml b/src/n2/n2.ml new file mode 100644 index 0000000..fb2cb39 --- /dev/null +++ b/src/n2/n2.ml @@ -0,0 +1,98 @@ +open Adam + +include (val Ohlog.logs "N2") + +module Transform = struct + type t = { + mutable buffer : node array; + mutable size : int; + } + + and node = + | Null + | Node of { + idx : int; + parent : node; + model_tf : mat2a; + world_tf : mat2a; + } + + let make () = { + buffer = Array.make 64 Null; + size = 0; + } + + let push t n = + let buf = t.buffer in + let cap = Array.length buf in + if t.size >= cap then + t.buffer <- + Array.init (cap * 2) + (fun i -> if i < cap then buf.(i) else Null); + t.buffer.(t.size) <- n; + t.size <- t.size + 1 + + let add ?(parent = Null) t = + let model_tf = mat2a 0.0 0.0 1.0 1.0 in + let world_tf = mat2a 0.0 0.0 1.0 1.0 in + let node = + Node { + idx = t.size; + parent; + model_tf; + world_tf; + } + in + push t node; + node + + let update t = + let buf = t.buffer in + for i = 0 to t.size - 1 do + match buf.(i) with + | Null -> () + | Node n -> + match n.parent with + | Null -> + Mat2A.copy n.world_tf ~src:n.model_tf + | Node p -> + Mat2A.copy n.world_tf ~src:p.world_tf; + Mat2A.mul n.world_tf n.model_tf; + done + + let world = function + | Null -> invalid_arg "null" + | Node n -> n.world_tf + + let model = function + | Null -> invalid_arg "null" + | Node n -> n.model_tf +end + +(* +module Entity = struct + include (val Ohlog.sublogs logger "Entity") + + type t = { + name : string option; + id : int; + } + + let _next_id = ref (-1) + + let make ?name () = { + name; + id = (incr _next_id; !_next_id); + } + + let pp ppf t = + Format.fprintf ppf "<%s@%d>" + (Option.value t.name ~default:"") + t.id + + let make ?name () = + let ent = make ?name () in + trace (fun m -> m "new entity %a" pp ent); + ent +end +*)