Skip to content

Commit 22c54b5

Browse files
committed
Temporarily readd media specific render commands
The more elaborate render commands defined in Aardvark.Rendering do not support picking at the moment.
1 parent 858cfa1 commit 22c54b5

File tree

1 file changed

+233
-0
lines changed

1 file changed

+233
-0
lines changed

src/Aardvark.UI/Core.fs

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,30 @@ module ChannelThings =
553553

554554
open Aardvark.Service
555555

556+
type RenderCommand<'msg> =
557+
| Clear of color : Option<aval<C4f>> * depth : Option<aval<float>> * stencil : Option<aval<int>>
558+
| SceneGraph of sg : ISg<'msg>
559+
560+
member x.Compile(values : ClientValues) =
561+
match x with
562+
| RenderCommand.Clear(color, depth, stencil) ->
563+
match color, depth, stencil with
564+
| Some c, Some d, Some s -> values.runtime.CompileClear(values.signature, c, d, s)
565+
| None, Some d, Some s -> values.runtime.CompileClearDepthStencil(values.signature, d, s)
566+
| Some c, None, Some s -> values.runtime.CompileClear(values.signature, (c, s) ||> AVal.map2 (fun c s -> clear { color c; stencil s }))
567+
| None, None, Some s -> values.runtime.CompileClearStencil(values.signature, s)
568+
| Some c, Some d, None -> values.runtime.CompileClear(values.signature, c, d)
569+
| None, Some d, None -> values.runtime.CompileClearDepth(values.signature, d)
570+
| Some c, None, None -> values.runtime.CompileClear(values.signature, c)
571+
| None, None, None -> RenderTask.empty
572+
| RenderCommand.SceneGraph sg ->
573+
let sg =
574+
sg
575+
|> Sg.viewTrafo values.viewTrafo
576+
|> Sg.projTrafo values.projTrafo
577+
|> Sg.uniform "ViewportSize" values.size
578+
values.runtime.CompileRender(values.signature, sg)
579+
556580
type IApp<'model, 'msg, 'outer> =
557581
abstract member ToOuter : 'model * 'msg -> seq<'outer>
558582
abstract member ToInner : 'model * 'outer -> seq<'msg>
@@ -1004,6 +1028,215 @@ and DomNode private() =
10041028
static member RenderControl(camera : aval<Camera>, scene : ClientValues -> ISg<'msg>, config : RenderControlConfig, ?htmlChildren : DomNode<_>) : DomNode<'msg> =
10051029
DomNode.RenderControl(AttributeMap.empty, camera, scene, config, htmlChildren)
10061030

1031+
static member RenderControl(attributes : AttributeMap<'msg>, camera : aval<Camera>, sgs : ClientValues -> alist<RenderCommand<'msg>>, htmlChildren : Option<DomNode<_>>) =
1032+
1033+
let getState(c : Aardvark.Service.ClientInfo) =
1034+
let cam = camera.GetValue(c.token)
1035+
let cam = { cam with frustum = cam.frustum |> Frustum.withAspect (float c.size.X / float c.size.Y) }
1036+
1037+
{
1038+
viewTrafo = CameraView.viewTrafo cam.cameraView
1039+
projTrafo = Frustum.projTrafo cam.frustum
1040+
}
1041+
1042+
let trees = AVal.init AList.empty
1043+
let globalPicks = AVal.init ASet.empty
1044+
1045+
let scene =
1046+
Scene.custom (fun values ->
1047+
1048+
let sgs = sgs values
1049+
1050+
let t =
1051+
sgs |> AList.choose (function RenderCommand.Clear _ -> None | SceneGraph sg -> PickTree.ofSg sg |> Some)
1052+
let g =
1053+
sgs |> AList.toASet |> ASet.choose (function RenderCommand.Clear _ -> None | SceneGraph sg -> sg.GlobalPicks(Ag.Scope.Root) |> Some)
1054+
1055+
transact (fun _ -> trees.Value <- t; globalPicks.Value <- g)
1056+
1057+
let mutable reader : IOpReader<IndexList<IRenderTask>, IndexListDelta<IRenderTask>> =
1058+
let mutable state = IndexList.empty
1059+
let input = sgs.GetReader()
1060+
{ new AbstractReader<IndexList<IRenderTask>, IndexListDelta<IRenderTask>>(IndexList.trace) with
1061+
member x.Compute(token) =
1062+
input.GetChanges token |> IndexListDelta.choose (fun index op ->
1063+
match op with
1064+
| Set v ->
1065+
match x.State.TryGet index with
1066+
| Some o -> o.Dispose()
1067+
| None -> ()
1068+
let task = v.Compile(values)
1069+
Some (Set task)
1070+
1071+
| Remove ->
1072+
match x.State.TryGet index with
1073+
| Some o ->
1074+
o.Dispose()
1075+
Some Remove
1076+
| None -> None
1077+
1078+
)
1079+
} :> _
1080+
//new AList.Readers.MapUseReader<_,_>(Ag.getContext(), sgs,invoke, (fun d -> d.Dispose()))
1081+
//let mutable state = IndexList.empty
1082+
1083+
let update (t : AdaptiveToken) =
1084+
let ops = reader.GetChanges t
1085+
()
1086+
1087+
{ new AbstractRenderTask() with
1088+
override x.PerformUpdate(t,rt) =
1089+
update t
1090+
override x.Perform(t,rt,o) =
1091+
update t
1092+
for task in reader.State do
1093+
task.Run(t,rt,o)
1094+
override x.Release() =
1095+
for task in reader.State do
1096+
task.Dispose()
1097+
reader <- Unchecked.defaultof<_>
1098+
1099+
override x.Use f = f ()
1100+
override x.FramebufferSignature = Some values.signature
1101+
override x.Runtime = Some values.runtime
1102+
} :> IRenderTask)
1103+
1104+
let globalNeeded = ASet.bind id globalPicks |> ASet.collect AMap.keys
1105+
let treeNeeded = AList.bind id trees |> AList.toASet |> ASet.collect (fun t -> t.Needed)
1106+
let needed = ASet.union globalNeeded treeNeeded
1107+
1108+
1109+
let rec pickTrees (trees : list<PickTree<'msg>>) (evt) =
1110+
match trees with
1111+
| [] -> false, Seq.empty
1112+
| x::xs ->
1113+
let consumed,msgs = pickTrees xs evt
1114+
if consumed then true,msgs
1115+
else
1116+
let consumed, other = x.Perform evt
1117+
consumed, Seq.append msgs other
1118+
1119+
let proc =
1120+
{ new SceneEventProcessor<'msg>() with
1121+
member x.NeededEvents = needed
1122+
member x.Process (source : Guid, evt : SceneEvent) =
1123+
let trees = trees |> AVal.force
1124+
let trees = trees.Content |> AVal.force |> IndexList.toList
1125+
let globalPicks = globalPicks |> AVal.force
1126+
1127+
seq {
1128+
for perScene in globalPicks.Content |> AVal.force do
1129+
let picks = perScene.Content |> AVal.force
1130+
match picks |> HashMap.tryFind evt.kind with
1131+
| Some cb ->
1132+
yield! cb evt
1133+
| None ->
1134+
()
1135+
}
1136+
}
1137+
1138+
DomNode.RenderControl(attributes, proc, getState, scene, htmlChildren)
1139+
1140+
static member RenderControl(attributes : AttributeMap<'msg>, camera : aval<Camera>, sgs : alist<RenderCommand<'msg>>, htmlChildren : Option<DomNode<_>>) =
1141+
let getState(c : Aardvark.Service.ClientInfo) =
1142+
let cam = camera.GetValue(c.token)
1143+
let cam = { cam with frustum = cam.frustum |> Frustum.withAspect (float c.size.X / float c.size.Y) }
1144+
1145+
{
1146+
viewTrafo = CameraView.viewTrafo cam.cameraView
1147+
projTrafo = Frustum.projTrafo cam.frustum
1148+
}
1149+
1150+
1151+
let scene =
1152+
Scene.custom (fun values ->
1153+
let mutable reader : IOpReader<IndexList<IRenderTask>, IndexListDelta<IRenderTask>> =
1154+
let mutable state = IndexList.empty
1155+
let input = sgs.GetReader()
1156+
{ new AbstractReader<IndexList<IRenderTask>, IndexListDelta<IRenderTask>>(IndexList.trace) with
1157+
member x.Compute(token) =
1158+
input.GetChanges token |> IndexListDelta.choose (fun index op ->
1159+
match op with
1160+
| Set v ->
1161+
match x.State.TryGet index with
1162+
| Some o -> o.Dispose()
1163+
| None -> ()
1164+
let task = v.Compile(values)
1165+
Some (Set task)
1166+
1167+
| Remove ->
1168+
match x.State.TryGet index with
1169+
| Some o ->
1170+
o.Dispose()
1171+
Some Remove
1172+
| None -> None
1173+
1174+
)
1175+
} :> _
1176+
1177+
let update (t : AdaptiveToken) =
1178+
let ops = reader.GetChanges t
1179+
()
1180+
1181+
{ new AbstractRenderTask() with
1182+
override x.PerformUpdate(t,rt) =
1183+
update t
1184+
override x.Perform(t,rt,o) =
1185+
update t
1186+
for task in reader.State do
1187+
task.Run(t,rt,o)
1188+
override x.Release() =
1189+
for t in reader.State do
1190+
t.Dispose()
1191+
reader <- Unchecked.defaultof<_>
1192+
1193+
1194+
override x.Use f = f ()
1195+
override x.FramebufferSignature = Some values.signature
1196+
override x.Runtime = Some values.runtime
1197+
} :> IRenderTask
1198+
1199+
)
1200+
1201+
let trees = sgs |> AList.choose (function Clear _ -> None | SceneGraph sg -> PickTree.ofSg sg |> Some)
1202+
let globalPicks = sgs |> AList.toASet |> ASet.choose (function Clear _ -> None | SceneGraph sg -> sg.GlobalPicks(Ag.Scope.Root) |> Some)
1203+
1204+
let globalNeeded = globalPicks |> ASet.collect AMap.keys
1205+
let treeNeeded = trees |> AList.toASet |> ASet.collect (fun t -> t.Needed)
1206+
let needed = ASet.union globalNeeded treeNeeded
1207+
1208+
1209+
let rec pickTrees (trees : list<PickTree<'msg>>) (evt) =
1210+
match trees with
1211+
| [] -> false, Seq.empty
1212+
| x::xs ->
1213+
let consumed,msgs = pickTrees xs evt
1214+
if consumed then true,msgs
1215+
else
1216+
let consumed, other = x.Perform evt
1217+
consumed, Seq.append msgs other
1218+
1219+
let proc =
1220+
{ new SceneEventProcessor<'msg>() with
1221+
member x.NeededEvents = needed
1222+
member x.Process (source : Guid, evt : SceneEvent) =
1223+
let trees = trees.Content |> AVal.force |> IndexList.toList
1224+
seq {
1225+
let consumed, msgs = pickTrees trees evt
1226+
yield! msgs
1227+
1228+
for perScene in globalPicks.Content |> AVal.force do
1229+
let picks = perScene.Content |> AVal.force
1230+
match picks |> HashMap.tryFind evt.kind with
1231+
| Some cb ->
1232+
yield! cb evt
1233+
| None ->
1234+
()
1235+
}
1236+
}
1237+
1238+
DomNode.RenderControl(attributes, proc, getState, scene, htmlChildren)
1239+
10071240

10081241
type Unpersist<'model, 'mmodel> =
10091242
{

0 commit comments

Comments
 (0)