From 1961b0c3789c8901f615a03a60b2c67a0bdc36a6 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 14 May 2024 14:47:24 +0200 Subject: [PATCH] Move common types to separate project The Aardvark.Rendering project contains some types that are used by projects that do not actually require a full blown Aardvark.Rendering dependency. This commit moves types such as IndexedGeometry and Camera to a separate project that can be referenced without pulling in a plethora of unrelated dependencies. --- paket.lock | 8 +- .../Aardvark.Rendering.Common.fsproj | 40 ++ .../ArrayVisitor.fs | 4 +- .../Camera/Camera.fs | 274 ++++++++ .../Camera/CameraView.fs | 151 +++++ .../Camera/Frustum.fs | 127 ++++ .../DefaultSemantic.fs | 47 ++ .../IndexedGeometry.fs | 81 ++- .../Modes/BlendMode.fs | 0 .../Modes/ColorMask.fs | 0 .../Modes}/ComparisonFunction.fs | 0 .../Modes/CullMode.fs | 0 .../Modes/DepthBias.fs | 0 .../Modes/DepthRange.fs | 0 .../Modes/DepthTest.fs | 0 .../Modes/FillMode.fs | 0 .../Modes/StencilMode.fs | 0 .../Modes/WindingOrder.fs | 0 .../Sampler/SamplerState.fs | 0 .../Sampler/TextureFilter.fs | 0 .../paket.references | 4 + src/Aardvark.Rendering.Common/paket.template | 11 + src/Aardvark.Rendering.sln | 6 + .../Aardvark.Rendering.fsproj | 20 +- .../Common/DefaultSemantic.fs | 47 -- src/Aardvark.Rendering/Pipeline/Camera.fs | 601 ------------------ .../Utilities/CameraExtensions.fs | 30 + 27 files changed, 746 insertions(+), 705 deletions(-) create mode 100644 src/Aardvark.Rendering.Common/Aardvark.Rendering.Common.fsproj rename src/{Aardvark.Rendering/Utilities => Aardvark.Rendering.Common}/ArrayVisitor.fs (97%) create mode 100644 src/Aardvark.Rendering.Common/Camera/Camera.fs create mode 100644 src/Aardvark.Rendering.Common/Camera/CameraView.fs create mode 100644 src/Aardvark.Rendering.Common/Camera/Frustum.fs create mode 100644 src/Aardvark.Rendering.Common/DefaultSemantic.fs rename src/{Aardvark.Rendering/Geometry => Aardvark.Rendering.Common}/IndexedGeometry.fs (84%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/BlendMode.fs (100%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/ColorMask.fs (100%) rename src/{Aardvark.Rendering/Common => Aardvark.Rendering.Common/Modes}/ComparisonFunction.fs (100%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/CullMode.fs (100%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/DepthBias.fs (100%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/DepthRange.fs (100%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/DepthTest.fs (100%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/FillMode.fs (100%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/StencilMode.fs (100%) rename src/{Aardvark.Rendering/Pipeline => Aardvark.Rendering.Common}/Modes/WindingOrder.fs (100%) rename src/{Aardvark.Rendering => Aardvark.Rendering.Common}/Sampler/SamplerState.fs (100%) rename src/{Aardvark.Rendering => Aardvark.Rendering.Common}/Sampler/TextureFilter.fs (100%) create mode 100644 src/Aardvark.Rendering.Common/paket.references create mode 100644 src/Aardvark.Rendering.Common/paket.template delete mode 100644 src/Aardvark.Rendering/Common/DefaultSemantic.fs delete mode 100644 src/Aardvark.Rendering/Pipeline/Camera.fs create mode 100644 src/Aardvark.Rendering/Utilities/CameraExtensions.fs diff --git a/paket.lock b/paket.lock index 139656846..a84934c2c 100644 --- a/paket.lock +++ b/paket.lock @@ -156,7 +156,7 @@ NUGET NETStandard.Library (>= 1.6.1) - restriction: || (&& (== net471) (< net40)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) SharpDX.Direct3D9 (4.0.1) Microsoft.NETCore.App (>= 1.0.5) - restriction: || (&& (== net471) (>= netcoreapp1.0)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp1.0)) - NETStandard.Library (>= 1.6.1) - restriction: || (&& (== net471) (< net40)) (&& (== net6.0) (< netcoreapp1.0)) (&& (== net6.0-windows7.0) (< netcoreapp1.0)) (== netstandard2.0) + NETStandard.Library (>= 1.6.1) - restriction: || (&& (== net471) (== net6.0)) (&& (== net471) (== net6.0-windows7.0)) (&& (== net471) (< net40)) (&& (== net6.0) (< netcoreapp1.0)) (&& (== net6.0-windows7.0) (< netcoreapp1.0)) (== netstandard2.0) SharpDX (>= 4.0.1) SharpZipLib (1.4.2) System.Memory (>= 4.5.4) - restriction: || (== net471) (&& (== net6.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< netstandard2.1)) (== netstandard2.0) @@ -241,7 +241,7 @@ NUGET System.Threading (>= 4.3) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) System.Memory (4.5.5) System.Buffers (>= 4.5.1) - restriction: || (== net471) (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= xamarinios)) (&& (== net6.0) (>= xamarinmac)) (&& (== net6.0) (>= xamarintvos)) (&& (== net6.0) (>= xamarinwatchos)) (&& (== net6.0-windows7.0) (>= monotouch)) (&& (== net6.0-windows7.0) (>= net461)) (&& (== net6.0-windows7.0) (< netcoreapp2.0)) (&& (== net6.0-windows7.0) (< netstandard1.1)) (&& (== net6.0-windows7.0) (< netstandard2.0)) (&& (== net6.0-windows7.0) (>= xamarinios)) (&& (== net6.0-windows7.0) (>= xamarinmac)) (&& (== net6.0-windows7.0) (>= xamarintvos)) (&& (== net6.0-windows7.0) (>= xamarinwatchos)) (== netstandard2.0) - System.Numerics.Vectors (>= 4.4) - restriction: || (&& (== net471) (< net45)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0-windows7.0) (< netcoreapp2.0)) (== netstandard2.0) + System.Numerics.Vectors (>= 4.4) - restriction: || (&& (== net471) (== net6.0)) (&& (== net471) (== net6.0-windows7.0)) (&& (== net471) (< net45)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0-windows7.0) (< netcoreapp2.0)) (== netstandard2.0) System.Numerics.Vectors (>= 4.5) - restriction: || (== net471) (&& (== net6.0) (>= net461)) (&& (== net6.0-windows7.0) (>= net461)) (&& (== netstandard2.0) (>= net461)) System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (== net471) (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= uap10.1)) (&& (== net6.0) (>= xamarinios)) (&& (== net6.0) (>= xamarinmac)) (&& (== net6.0) (>= xamarintvos)) (&& (== net6.0) (>= xamarinwatchos)) (&& (== net6.0-windows7.0) (>= monotouch)) (&& (== net6.0-windows7.0) (>= net461)) (&& (== net6.0-windows7.0) (< netcoreapp2.0)) (&& (== net6.0-windows7.0) (< netcoreapp2.1)) (&& (== net6.0-windows7.0) (< netstandard1.1)) (&& (== net6.0-windows7.0) (< netstandard2.0)) (&& (== net6.0-windows7.0) (>= uap10.1)) (&& (== net6.0-windows7.0) (>= xamarinios)) (&& (== net6.0-windows7.0) (>= xamarinmac)) (&& (== net6.0-windows7.0) (>= xamarintvos)) (&& (== net6.0-windows7.0) (>= xamarinwatchos)) (== netstandard2.0) System.Numerics.Vectors (4.5) @@ -258,10 +258,10 @@ NUGET System.Reflection.Primitives (>= 4.3) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) System.Runtime (>= 4.3) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) System.Reflection.Emit (4.7) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) - System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (== net471) (< net45)) (&& (== net471) (< netstandard1.1)) (&& (== net471) (< netstandard2.0) (>= wpa81)) (&& (== net471) (>= uap10.1)) (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= uap10.1)) (&& (== net6.0-windows7.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< netstandard1.1)) (&& (== net6.0-windows7.0) (< netstandard2.0)) (&& (== net6.0-windows7.0) (>= uap10.1)) (== netstandard2.0) + System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (== net471) (== net6.0)) (&& (== net471) (== net6.0-windows7.0)) (&& (== net471) (< net45)) (&& (== net471) (< netstandard1.1)) (&& (== net471) (< netstandard2.0) (>= wpa81)) (&& (== net471) (>= uap10.1)) (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= uap10.1)) (&& (== net6.0-windows7.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< netstandard1.1)) (&& (== net6.0-windows7.0) (< netstandard2.0)) (&& (== net6.0-windows7.0) (>= uap10.1)) (== netstandard2.0) System.Reflection.Emit.ILGeneration (4.7) - restriction: || (&& (== net471) (< net45)) (&& (== net471) (< netstandard2.0) (>= wpa81)) (&& (== net471) (< portable-net45+wp8)) (&& (== net471) (>= uap10.1)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) System.Reflection.Emit.Lightweight (4.7) - System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (== net471) (< net45)) (&& (== net471) (< netstandard2.0) (>= wpa81)) (&& (== net471) (< portable-net45+wp8)) (&& (== net471) (>= uap10.1)) (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< portable-net45+wp8)) (&& (== net6.0) (>= uap10.1)) (&& (== net6.0-windows7.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< netstandard2.0)) (&& (== net6.0-windows7.0) (< portable-net45+wp8)) (&& (== net6.0-windows7.0) (>= uap10.1)) (== netstandard2.0) + System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (== net471) (== net6.0)) (&& (== net471) (== net6.0-windows7.0)) (&& (== net471) (< net45)) (&& (== net471) (< netstandard2.0) (>= wpa81)) (&& (== net471) (< portable-net45+wp8)) (&& (== net471) (>= uap10.1)) (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< portable-net45+wp8)) (&& (== net6.0) (>= uap10.1)) (&& (== net6.0-windows7.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< netstandard2.0)) (&& (== net6.0-windows7.0) (< portable-net45+wp8)) (&& (== net6.0-windows7.0) (>= uap10.1)) (== netstandard2.0) System.Reflection.Extensions (4.3) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) Microsoft.NETCore.Platforms (>= 1.1) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) Microsoft.NETCore.Targets (>= 1.1) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) diff --git a/src/Aardvark.Rendering.Common/Aardvark.Rendering.Common.fsproj b/src/Aardvark.Rendering.Common/Aardvark.Rendering.Common.fsproj new file mode 100644 index 000000000..c389a0cf2 --- /dev/null +++ b/src/Aardvark.Rendering.Common/Aardvark.Rendering.Common.fsproj @@ -0,0 +1,40 @@ + + + + netstandard2.0 + Aardvark.Rendering.Common + Library + true + true + 3389;3390;3395 + + + ..\..\bin\Debug\ + DEBUG;TRACE + + + ..\..\bin\Release + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Aardvark.Rendering/Utilities/ArrayVisitor.fs b/src/Aardvark.Rendering.Common/ArrayVisitor.fs similarity index 97% rename from src/Aardvark.Rendering/Utilities/ArrayVisitor.fs rename to src/Aardvark.Rendering.Common/ArrayVisitor.fs index ceaf3ca96..2af22e919 100644 --- a/src/Aardvark.Rendering/Utilities/ArrayVisitor.fs +++ b/src/Aardvark.Rendering.Common/ArrayVisitor.fs @@ -16,7 +16,7 @@ type ArrayVisitor<'r>() = static let get (t : Type) = cache.GetOrAdd(t, Func<_,_>(fun t -> - let dMeth = + let dMeth = DynamicMethod( "ArrayVisitor", MethodAttributes.Static ||| MethodAttributes.Public, @@ -32,7 +32,7 @@ type ArrayVisitor<'r>() = il.Emit(OpCodes.Ldarg_1) il.EmitCall(OpCodes.Callvirt, mRun, null) il.Emit(OpCodes.Ret) - + let t = typeof, Array, 'r>> let del = dMeth.CreateDelegate(t) |> unbox, Array, 'r>> fun v a -> del.Invoke(v,a) diff --git a/src/Aardvark.Rendering.Common/Camera/Camera.fs b/src/Aardvark.Rendering.Common/Camera/Camera.fs new file mode 100644 index 000000000..075ae698e --- /dev/null +++ b/src/Aardvark.Rendering.Common/Camera/Camera.fs @@ -0,0 +1,274 @@ +namespace Aardvark.Rendering + +open System +open Aardvark.Base + +type Camera = + { + cameraView : CameraView + frustum : Frustum + } + +[] +module Camera = + + let inline create (view : CameraView) (frustum : Frustum) = { cameraView = view; frustum = frustum } + let inline viewTrafo (cam : Camera) = cam.cameraView |> CameraView.viewTrafo + let inline projTrafo (cam : Camera) = cam.frustum |> Frustum.projTrafo + let inline viewProjTrafo (cam : Camera) = (CameraView.viewTrafo cam.cameraView) * (Frustum.projTrafo cam.frustum) + let inline cameraView (cam : Camera) = cam.cameraView + let inline frustum (cam : Camera) = cam.frustum + + let inline location (cam : Camera) = cam.cameraView |> CameraView.location + let inline forward (cam : Camera) = cam.cameraView |> CameraView.forward + let inline up (cam : Camera) = cam.cameraView |> CameraView.up + let inline right (cam : Camera) = cam.cameraView |> CameraView.right + let inline backward (cam : Camera) = cam.cameraView |> CameraView.backward + let inline down (cam : Camera) = cam.cameraView |> CameraView.down + let inline left (cam : Camera) = cam.cameraView |> CameraView.left + let inline near (cam : Camera) = cam.frustum.near + let inline far (cam : Camera) = cam.frustum.far + +[] +module ViewProjection = + + [] + module private Helpers = + let inline toPlane (v : V4d) = + Plane3d(-v.XYZ, v.W) + + let inline maxDir (dir : V3d) (b : Box3d) = + V4d( + (if dir.X > 0.0 then b.Max.X else b.Min.X), + (if dir.Y > 0.0 then b.Max.Y else b.Min.Y), + (if dir.Z > 0.0 then b.Max.Z else b.Min.Z), + 1.0 + ) + + let inline height (plane : V4d) (b : Box3d) = + plane.Dot(maxDir plane.XYZ b) + + + let intersect (a : Plane3d) (b : Plane3d) (c : Plane3d) = + let mutable pt = V3d.Zero + if a.Intersects(b,c, &pt) then + pt + else + failwith "no plane intersection" + + + let inline proj (pt : V3d) = V3d(pt.XY / -pt.Z, -pt.Z) + + let containing (viewPos : V3d) (bounds : Box3d) = + let angularRange = + bounds.ComputeCorners() + |> Array.map (fun world -> + let dir = world - viewPos + dir.SphericalFromCartesian() + ) + |> Box2d + + let forward = angularRange.Center.CartesianFromSpherical() + + let mutable closest = V3d.Zero + let mutable farthest = V3d.Zero + bounds.GetMinMaxInDirection(forward, &closest, &farthest) + let near = Vec.Distance(viewPos, closest) + let far = Vec.Distance(viewPos, farthest) + + let halfAngularSize = angularRange.Size * 0.5 + let l = -near * Fun.Tan(halfAngularSize.X) + let r = -l + let t = near * Fun.Tan(halfAngularSize.Y) + let b = -t + + let sky = + if Fun.ApproximateEquals(abs forward.Z, 1.0, Constant.PositiveTinyValue) then V3d.OIO + else V3d.OOI + + let view = CameraView.lookAt viewPos (viewPos + forward) sky + let proj = + { + left = l + right = r + top = t + bottom = b + near = near + far = far + isOrtho = false + } + + view, proj + + let intersects (b : Box3d) (viewProj : Trafo3d) = + let fw = viewProj.Forward + let r0 = fw.R0 + let r1 = fw.R1 + let r2 = fw.R2 + let r3 = fw.R3 + + height (r3 + r0) b >= 0.0 && + height (r3 - r0) b >= 0.0 && + height (r3 + r1) b >= 0.0 && + height (r3 - r1) b >= 0.0 && + height (r3 + r2) b >= 0.0 && + height (r3 - r2) b >= 0.0 + + let contains (point : V3d) (viewProj : Trafo3d) = + let fw = viewProj.Forward + let r0 = fw.R0 + let r1 = fw.R1 + let r2 = fw.R2 + let r3 = fw.R3 + let p = V4d(point, 1.0) + + Vec.Dot((r3 + r0), p) >= 0.0 && + Vec.Dot((r3 - r0), p) >= 0.0 && + Vec.Dot((r3 + r1), p) >= 0.0 && + Vec.Dot((r3 - r1), p) >= 0.0 && + Vec.Dot((r3 + r2), p) >= 0.0 && + Vec.Dot((r3 - r2), p) >= 0.0 + + let private frustumCorners = + [| + V3d(-1.0, -1.0, -1.0) + V3d( 1.0, -1.0, -1.0) + V3d( 1.0, 1.0, -1.0) + V3d(-1.0, 1.0, -1.0) + V3d(-1.0, -1.0, 1.0) + V3d( 1.0, -1.0, 1.0) + V3d( 1.0, 1.0, 1.0) + V3d(-1.0, 1.0, 1.0) + |] + + let private cornerIndices = + [| + 1;2; 2;6; 6;5; 5;1; + 2;3; 3;7; 7;6; 4;5; + 7;4; 3;0; 0;4; 0;1; + |] + + let toIndexedGeometry (v : CameraView) (p : Frustum) (color : C4b) = + let invViewProj = (CameraView.viewTrafo v * Frustum.projTrafo p).Inverse + let positions = frustumCorners |> Array.map (invViewProj.Forward.TransformPosProj >> V3f) + + let attributes = SymbolDict() + attributes.[DefaultSemantic.Positions] <- cornerIndices |> Array.map (fun i -> positions.[i]) + attributes.[DefaultSemantic.Colors] <- Array.create cornerIndices.Length color + + IndexedGeometry( + Mode = IndexedGeometryMode.LineList, + IndexedAttributes = attributes + ) + + let leftPlane (viewProj : Trafo3d) = + let r0 = viewProj.Forward.R0 + let r3 = viewProj.Forward.R3 + r3 - r0 + + let rightPlane (viewProj : Trafo3d) = + let r0 = viewProj.Forward.R0 + let r3 = viewProj.Forward.R3 + r3 + r0 + + let toHull3d (viewProj : Trafo3d) = + let r0 = viewProj.Forward.R0 + let r1 = viewProj.Forward.R1 + let r2 = viewProj.Forward.R2 + let r3 = viewProj.Forward.R3 + + Hull3d [| + r3 - r0 |> toPlane // right + r3 + r0 |> toPlane // left + r3 + r1 |> toPlane // bottom + r3 - r1 |> toPlane // top + r3 + r2 |> toPlane // near + r3 - r2 |> toPlane // far + |] + + let inline toFastHull3d (viewProj : Trafo3d) = + FastHull3d(toHull3d viewProj) + + let intersectsDX (b : Box3d) (viewProj : Trafo3d) = + let fw = viewProj.Forward + let r0 = fw.R0 + let r1 = fw.R1 + let r2 = fw.R2 + let r3 = fw.R3 + + height (r3 + r0) b >= 0.0 && + height (r3 - r0) b >= 0.0 && + height (r3 + r1) b >= 0.0 && + height (r3 - r1) b >= 0.0 && + height ( r2) b >= 0.0 && + height (r3 - r2) b >= 0.0 + + let containsDX (point : V3d) (viewProj : Trafo3d) = + let fw = viewProj.Forward + let r0 = fw.R0 + let r1 = fw.R1 + let r2 = fw.R2 + let r3 = fw.R3 + let p = V4d(point, 1.0) + + Vec.Dot((r3 + r0), p) >= 0.0 && + Vec.Dot((r3 - r0), p) >= 0.0 && + Vec.Dot((r3 + r1), p) >= 0.0 && + Vec.Dot((r3 - r1), p) >= 0.0 && + Vec.Dot(( r2), p) >= 0.0 && + Vec.Dot((r3 - r2), p) >= 0.0 + + let toHull3dDX (viewProj : Trafo3d) = + let r0 = viewProj.Forward.R0 + let r1 = viewProj.Forward.R1 + let r2 = viewProj.Forward.R2 + let r3 = viewProj.Forward.R3 + + Hull3d [| + r3 + r0 |> toPlane + r3 - r0 |> toPlane + r3 + r1 |> toPlane + r3 - r1 |> toPlane + r2 |> toPlane + r3 - r2 |> toPlane + |] + + let inline toFastHull3dDX (viewProj : Trafo3d) = + FastHull3d(toHull3dDX viewProj) + + let mergeStereo (lProj : Trafo3d) (rProj : Trafo3d) = + let p (v : V4d) = Plane3d(v.XYZ, -v.W) + + let lPlane = rightPlane lProj |> p + let rPlane = leftPlane rProj |> p + + let location = intersect lPlane rPlane Plane3d.YPlane + let view = Trafo3d.Translation(-location) + + let points = + Array.concat [| + frustumCorners |> Array.map lProj.Backward.TransformPosProj + frustumCorners |> Array.map rProj.Backward.TransformPosProj + |] + + let projected = + points |> Array.map (view.Forward.TransformPos >> proj) + + let bounds = Box3d(projected) + + let near = bounds.Min.Z + let far = bounds.Max.Z + + let frustum = + { + left = bounds.Min.X * near + right = bounds.Max.X * near + top = bounds.Max.Y * near + bottom = bounds.Min.Y * near + near = near + far = far + isOrtho = false + } + + let proj = Frustum.projTrafo frustum + view * proj \ No newline at end of file diff --git a/src/Aardvark.Rendering.Common/Camera/CameraView.fs b/src/Aardvark.Rendering.Common/Camera/CameraView.fs new file mode 100644 index 000000000..6208656ae --- /dev/null +++ b/src/Aardvark.Rendering.Common/Camera/CameraView.fs @@ -0,0 +1,151 @@ +namespace Aardvark.Rendering + +open System +open Aardvark.Base + +type CameraView(sky : V3d, location : V3d, forward : V3d, up : V3d, right : V3d) = + let viewTrafo = + lazy ( Trafo3d.ViewTrafo(location, right, up, -forward) ) + + let orientation = + lazy ( + let frame = M33d.FromCols(right, forward, up) |> Mat.Orthonormalized + Rot3d.FromM33d frame + ) + + member x.Sky = sky + member x.Location = location + member x.Forward = forward + member x.Up = up + member x.Right = right + member x.Backward = -forward + member x.Down = -up + member x.Left = -right + + member x.ViewTrafo = viewTrafo.Value + member x.Orientation = orientation.Value + + override x.ToString() = + sprintf "CameraView(sky=%A, location=%A, forward=%A, up=%A, right=%A)" sky location forward up right + + static member LookAt(location : V3d, center : V3d, sky : V3d) = + let fw = center - location |> Vec.Normalized + let right = Vec.Cross(fw, sky) |> Vec.Normalized + let up = Vec.Cross(right, fw) |> Vec.Normalized + CameraView(sky, location, fw, up, right) + + static member LookAt(location : V3d, center : V3d) = + CameraView.LookAt(location, center, V3d.OOI) + + static member Look(location : V3d, forward : V3d, sky : V3d) = + let right = Vec.Cross(forward, sky) |> Vec.Normalized + let up = Vec.Cross(right, forward) |> Vec.Normalized + CameraView(sky, location, forward, up, right) + + static member Look(location : V3d, forward : V3d) = + CameraView.Look(location, forward, V3d.OOI) + + static member Orient(location : V3d, orientation : Rot3d, sky : V3d) = + let frame = M33d.Rotation orientation + CameraView(sky, location, frame.C1, frame.C2, frame.C0) + + static member Orient(location : V3d, orientation : Rot3d) = + CameraView.Orient(location, orientation, V3d.OOI) + + member x.WithLocation(l : V3d) = + CameraView(sky, l, forward, up, right) + + member x.WithForward(fw : V3d) = + CameraView.Look(location, fw, sky) + + member x.WithRight(right : V3d) = + let forward = Vec.Cross(sky, right) |> Vec.Normalized + let up = Vec.Cross(right, forward) |> Vec.Normalized + CameraView(sky, location, forward, up, right) + + member x.WithUp(up : V3d) = + let forward = Vec.Cross(up, right) |> Vec.Normalized + let right = Vec.Cross(forward, up) |> Vec.Normalized + CameraView(sky, location, forward, up, right) + + member x.WithBackward(bw : V3d) = + x.WithForward (-bw) + + member x.WithLeft(left : V3d) = + x.WithRight(-left) + + member x.WithDown(down : V3d) = + x.WithUp(-down) + + member x.WithOrientation(orientation : Rot3d) = + CameraView.Orient(location, orientation, sky) + + +[] +module CameraView = + + let lookAt (location : V3d) (center : V3d) (sky : V3d) = + CameraView.LookAt(location, center, sky) + + let look (location : V3d) (forward : V3d) (sky : V3d) = + CameraView.Look(location, forward, sky) + + let orient (location : V3d) (orientation : Rot3d) (sky : V3d) = + CameraView.Orient(location, orientation, sky) + + let withLocation (location : V3d) (c : CameraView) = + c.WithLocation location + + let withForward (forward : V3d) (c : CameraView) = + c.WithForward forward + + let withRight (right : V3d) (c : CameraView) = + c.WithRight right + + let withUp (up : V3d) (c : CameraView) = + c.WithUp up + + let withBackward (backward : V3d) (c : CameraView) = + c.WithBackward backward + + let withLeft (left : V3d) (c : CameraView) = + c.WithLeft left + + let withDown (down : V3d) (c : CameraView) = + c.WithDown down + + let withOrientation (orientation : Rot3d) (c : CameraView) = + c.WithOrientation orientation + + let viewTrafo (c : CameraView) = + c.ViewTrafo + + let orientation (c : CameraView) = + c.Orientation + + let ofTrafo (t : Trafo3d) = + let bw = t.Backward + + let right = bw.C0.XYZ // bw.TransformDir(V3d.IOO) + let up = bw.C1.XYZ // bw.TransformDir(V3d.OIO) + let forward = -bw.C2.XYZ // bw.TransformDir(-V3d.OOI) + let location = bw.C3.XYZ // bw.TransformPos(V3d.OOO) + + CameraView(up, location, forward, up, right) + + let tryGetCenterOn (p : Plane3d) (c : CameraView) = + let r = Ray3d(c.Location, c.Forward) + + let mutable t = Double.PositiveInfinity + if r.Intersects(p, &t) && t >= 0.0 then + Some (r.GetPointOnRay t) + else + None + + let inline location (c : CameraView) = c.Location + let inline forward (c : CameraView) = c.Forward + let inline right (c : CameraView) = c.Right + let inline up (c : CameraView) = c.Up + let inline backward (c : CameraView) = c.Backward + let inline left (c : CameraView) = c.Left + let inline down (c : CameraView) = c.Down \ No newline at end of file diff --git a/src/Aardvark.Rendering.Common/Camera/Frustum.fs b/src/Aardvark.Rendering.Common/Camera/Frustum.fs new file mode 100644 index 000000000..2a0d9d21a --- /dev/null +++ b/src/Aardvark.Rendering.Common/Camera/Frustum.fs @@ -0,0 +1,127 @@ +namespace Aardvark.Rendering + +open Aardvark.Base +open System.Runtime.CompilerServices + +type Frustum = + { + left : float + right : float + bottom : float + top : float + near : float + far : float + isOrtho : bool + } + +[] +module Frustum = + let perspective (horizontalFieldOfViewInDegrees : float) (near : float) (far : float) (aspect : float) = + let d = tan (0.5 * Conversion.RadiansFromDegrees horizontalFieldOfViewInDegrees) * near + { left = -d; right = +d; bottom = -d / aspect; top = +d / aspect; near = near; far = far; isOrtho = false } + + let ortho (b : Box3d) = + { + left = b.Min.X + right = b.Max.X + bottom = b.Min.Y + top = b.Max.Y + near = b.Min.Z + far = b.Max.Z + isOrtho = true + } + + let projTrafo {left = l; right = r; top = t; bottom = b; near = n; far = f; isOrtho = isOrtho } : Trafo3d = + if isOrtho then + Trafo3d.OrthoProjectionGL(l, r, b, t, n, f) + else + Trafo3d.PerspectiveProjectionGL(l, r, b, t, n, f) + + let private isTrafoOrtho (t : Trafo3d) = + t.Forward.M30.IsTiny() && t.Forward.M31.IsTiny() && t.Forward.M32.IsTiny() + + let ofTrafo (t : Trafo3d) = + let isOrtho = isTrafoOrtho t + let m = t.Forward + if not isOrtho then + let r = (1.0 + m.M22) / (m.M22 - 1.0) + let far = (r - 1.0) * m.M23 / (2.0 * r) + let near = r * far + let top = (1.0 + m.M12) * near / m.M11 + let bottom = (m.M12 - 1.0) * near / m.M11 + let left = (m.M02 - 1.0) * near / m.M00 + let right = (1.0 + m.M02) * near / m.M00 + + { + isOrtho = false + left = left + right = right + top = top + bottom = bottom + near = near + far = far + } + else + let left = -(1.0 + m.M03) / m.M00 + let right = (1.0 - m.M03) / m.M00 + let bottom = -(1.0 + m.M13) / m.M11 + let top = (1.0 - m.M13) / m.M11 + let far = -(1.0 + m.M23) / m.M22 + let near = (1.0 - m.M23) / m.M22 + { + isOrtho = true + left = left + right = right + top = top + bottom = bottom + near = near + far = far + } + + let withNear (near : float) (f : Frustum) = + if f.isOrtho then + { f with near = near } + else + let factor = near / f.near + { + isOrtho = false + near = near + far = f.far + left = factor * f.left + right = factor * f.right + top = factor * f.top + bottom = factor * f.bottom + } + + let withFar (far : float) (f : Frustum) = + { f with far = far } + + let aspect { left = l; right = r; top = t; bottom = b } = + (r - l) / (t - b) + + let withAspect (newAspect : float) ( { left = l; right = r; top = t; bottom = b } as f ) = + let factor = aspect f / newAspect + { f with top = factor * t; bottom = factor * b } + + let withHorizontalFieldOfViewInDegrees (angleInDegrees : float) (frustum : Frustum) = + if frustum.isOrtho then + frustum + else + let aspect = aspect frustum + perspective angleInDegrees frustum.near frustum.far aspect + + let horizontalFieldOfViewInDegrees { left = l; right = r; near = near } = + let l,r = atan2 l near, atan2 r near + Conversion.DegreesFromRadians(-l + r) + + let inline near (f : Frustum) = f.near + let inline far (f : Frustum) = f.far + let inline left (f : Frustum) = f.left + let inline right (f : Frustum) = f.right + let inline bottom (f : Frustum) = f.bottom + let inline top (f : Frustum) = f.top + +[] +type CameraCSharpExtensions() = + [] + static member ProjTrafo(f : Frustum) = Frustum.projTrafo f \ No newline at end of file diff --git a/src/Aardvark.Rendering.Common/DefaultSemantic.fs b/src/Aardvark.Rendering.Common/DefaultSemantic.fs new file mode 100644 index 000000000..0f7f45260 --- /dev/null +++ b/src/Aardvark.Rendering.Common/DefaultSemantic.fs @@ -0,0 +1,47 @@ +namespace Aardvark.Rendering + +open System +open Aardvark.Base + +module DefaultSemantic = + + let Positions = Symbol.Create "Positions" + let Normals = Symbol.Create "Normals" + let Colors = Symbol.Create "Colors" + let DiffuseColorCoordinates = Symbol.Create "DiffuseColorCoordinates" + let LightMapCoordinates = Symbol.Create "LightMapCoordinates" + let NormalMapCoordinates = Symbol.Create "NormalMapCoordinates" + let DiffuseColorUTangents = Symbol.Create "DiffuseColorUTangents" + let DiffuseColorVTangents = Symbol.Create "DiffuseColorVTangents" + + // Single Attributes + let DiffuseColorTexture = Symbol.Create "DiffuseColorTexture" + let AmbientColorTexture = Symbol.Create "AmbientColorTexture" + let EmissiveColorTexture = Symbol.Create "EmissiveColorTexture" + let SpecularColorTexture = Symbol.Create "SpecularColorTexture" + let ShininessTexture = Symbol.Create "ShininessTexture" + + let LightMapTexture = Symbol.Create "LightMapTexture" + let NormalMapTexture = Symbol.Create "NormalMapTexture" + + let Trafo3d = Symbol.Create "Trafo3d" + let DiffuseColorTrafo2d = Symbol.Create "DiffuseColorTrafo2d" + let Name = Symbol.Create "Name" + let Material = Symbol.Create "Material" + let CreaseAngle = Symbol.Create "CreaseAngle" + let WindingOrder = Symbol.Create "WindingOrder" + let AreaSum = Symbol.Create "AreaSum" + + // Various + let DepthStencil = Symbol.Create "DepthStencil" + + [] + let Depth = DepthStencil + + [] + let Stencil = DepthStencil + + let ImageOutput = Symbol.Create "ImageOutput" + let InstanceTrafo = Symbol.Create "InstanceTrafo" + let InstanceTrafoInv = Symbol.Create "InstanceTrafoInv" + let SamplerStateModifier = Symbol.Create "SamplerStateModifier" \ No newline at end of file diff --git a/src/Aardvark.Rendering/Geometry/IndexedGeometry.fs b/src/Aardvark.Rendering.Common/IndexedGeometry.fs similarity index 84% rename from src/Aardvark.Rendering/Geometry/IndexedGeometry.fs rename to src/Aardvark.Rendering.Common/IndexedGeometry.fs index 2822c3c38..8bcc8f46f 100644 --- a/src/Aardvark.Rendering/Geometry/IndexedGeometry.fs +++ b/src/Aardvark.Rendering.Common/IndexedGeometry.fs @@ -15,17 +15,25 @@ module private IndexHelpers = | :? array as x -> x |> Array.map ((+) (uint32 offset)) :> Array | :? array as x -> x |> Array.map ((+) (uint16 offset)) :> Array | _ -> - raise <| ArgumentException($"Unsupported type {index.GetType()}.") + raise <| ArgumentException($"Unsupported index type {index.GetType()}.") - let applyIndex (index : Array) (data : Array) = + let inline private getIntConverter<'T>() : 'T -> int32 = + if typeof<'T> = typeof then unbox + elif typeof<'T> = typeof then unbox >> int + elif typeof<'T> = typeof then unbox >> int + elif typeof<'T> = typeof then unbox >> int + else + raise <| ArgumentException($"Unsupported index type {typeof<'T>}.") + + let applyIndex (index : Array) (data : Array) = if isNull index || isNull data then null else - index.Visit + index.Visit { new ArrayVisitor() with member x.Run(index : 'i[]) = - let toInt = PrimitiveValueConverter.converter<'i, int> - data.Visit + let toInt = getIntConverter<'i>() + data.Visit { new ArrayVisitor() with member x.Run(data : 'a[]) = let l = data.Length @@ -53,7 +61,7 @@ module private IndexHelpers = oi <- oi + 2 res :> Array - } + } let triangleStripToList (data : Array) = if isNull data then @@ -83,7 +91,7 @@ module private IndexHelpers = res :> Array } - + module private ArrayHelpers = let concat (a : Array) (b : Array) = @@ -101,7 +109,7 @@ module private ArrayHelpers = else Array.concat [a; unbox<'T[]> b] } - ) + ) } ) @@ -116,7 +124,7 @@ type IndexedGeometryMode = | LineAdjacencyList = 6 | QuadList = 7 -[] +[] module IndexedGeometryMode = let faceCount (m : IndexedGeometryMode) (fvc : int) = match m with @@ -200,16 +208,15 @@ type IndexedGeometry = let res = IndexedGeometry(Mode = x.Mode) if not (isNull x.IndexedAttributes) then - res.IndexedAttributes <- - x.IndexedAttributes |> SymDict.map (fun name att -> - IndexHelpers.applyIndex index att - ) - - if not (isNull x.SingleAttributes) then + res.IndexedAttributes <- SymbolDict(initialCapacity = x.IndexedAttributes.Count) + for (KeyValue(sem, att)) in x.IndexedAttributes do + res.IndexedAttributes.[sem] <- IndexHelpers.applyIndex index att + + if not (isNull x.SingleAttributes) then res.SingleAttributes <- x.SingleAttributes.Copy() res - + member x.ToNonStripped() = match x.Mode with | IndexedGeometryMode.LineStrip -> @@ -259,24 +266,28 @@ type IndexedGeometry = let singleAttributes = if isNull x.SingleAttributes then y.SingleAttributes elif isNull y.SingleAttributes then x.SingleAttributes - else SymDict.union [x.SingleAttributes; y.SingleAttributes] + else + let r = SymbolDict() + for (KeyValue(sem, att)) in x.SingleAttributes do r.[sem] <- att + for (KeyValue(sem, att)) in y.SingleAttributes do r.[sem] <- att + r let indexedAttributes = if isNull x.IndexedAttributes then y.IndexedAttributes elif isNull y.IndexedAttributes then x.IndexedAttributes else - let r = SymDict.empty + let r = SymbolDict() for KeyValue(sem, a) in x.IndexedAttributes do - match y.IndexedAttributes |> SymDict.tryFind sem with - | Some b -> + match y.IndexedAttributes.TryGetValue(sem) with + | (true, b) -> try r.[sem] <- ArrayHelpers.concat a b with | exn -> raise <| ArgumentException($"Invalid {sem} attributes: {exn.Message}") | _ -> () - + r IndexedGeometry ( @@ -285,30 +296,30 @@ type IndexedGeometry = SingleAttributes = singleAttributes, IndexedAttributes = indexedAttributes ) - - new() = - { Mode = IndexedGeometryMode.TriangleList; - IndexArray = null; - IndexedAttributes = null; + + new() = + { Mode = IndexedGeometryMode.TriangleList; + IndexArray = null; + IndexedAttributes = null; SingleAttributes = null } - new(indexArray, indexedAttributes, singleAttributes) = - { Mode = IndexedGeometryMode.TriangleList; - IndexArray = indexArray; - IndexedAttributes = indexedAttributes; + new(indexArray, indexedAttributes, singleAttributes) = + { Mode = IndexedGeometryMode.TriangleList; + IndexArray = indexArray; + IndexedAttributes = indexedAttributes; SingleAttributes = singleAttributes } - new(mode, indexArray, indexedAttributes, singleAttributes) = + new(mode, indexArray, indexedAttributes, singleAttributes) = { Mode = mode - IndexArray = indexArray; - IndexedAttributes = indexedAttributes; + IndexArray = indexArray; + IndexedAttributes = indexedAttributes; SingleAttributes = singleAttributes } end -[] +[] module IndexedGeometry = - + let inline mode (g : IndexedGeometry) = g.Mode let inline indexArray (g : IndexedGeometry) = g.IndexArray let inline indexedAttributes (g : IndexedGeometry) = g.IndexedAttributes diff --git a/src/Aardvark.Rendering/Pipeline/Modes/BlendMode.fs b/src/Aardvark.Rendering.Common/Modes/BlendMode.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/BlendMode.fs rename to src/Aardvark.Rendering.Common/Modes/BlendMode.fs diff --git a/src/Aardvark.Rendering/Pipeline/Modes/ColorMask.fs b/src/Aardvark.Rendering.Common/Modes/ColorMask.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/ColorMask.fs rename to src/Aardvark.Rendering.Common/Modes/ColorMask.fs diff --git a/src/Aardvark.Rendering/Common/ComparisonFunction.fs b/src/Aardvark.Rendering.Common/Modes/ComparisonFunction.fs similarity index 100% rename from src/Aardvark.Rendering/Common/ComparisonFunction.fs rename to src/Aardvark.Rendering.Common/Modes/ComparisonFunction.fs diff --git a/src/Aardvark.Rendering/Pipeline/Modes/CullMode.fs b/src/Aardvark.Rendering.Common/Modes/CullMode.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/CullMode.fs rename to src/Aardvark.Rendering.Common/Modes/CullMode.fs diff --git a/src/Aardvark.Rendering/Pipeline/Modes/DepthBias.fs b/src/Aardvark.Rendering.Common/Modes/DepthBias.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/DepthBias.fs rename to src/Aardvark.Rendering.Common/Modes/DepthBias.fs diff --git a/src/Aardvark.Rendering/Pipeline/Modes/DepthRange.fs b/src/Aardvark.Rendering.Common/Modes/DepthRange.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/DepthRange.fs rename to src/Aardvark.Rendering.Common/Modes/DepthRange.fs diff --git a/src/Aardvark.Rendering/Pipeline/Modes/DepthTest.fs b/src/Aardvark.Rendering.Common/Modes/DepthTest.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/DepthTest.fs rename to src/Aardvark.Rendering.Common/Modes/DepthTest.fs diff --git a/src/Aardvark.Rendering/Pipeline/Modes/FillMode.fs b/src/Aardvark.Rendering.Common/Modes/FillMode.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/FillMode.fs rename to src/Aardvark.Rendering.Common/Modes/FillMode.fs diff --git a/src/Aardvark.Rendering/Pipeline/Modes/StencilMode.fs b/src/Aardvark.Rendering.Common/Modes/StencilMode.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/StencilMode.fs rename to src/Aardvark.Rendering.Common/Modes/StencilMode.fs diff --git a/src/Aardvark.Rendering/Pipeline/Modes/WindingOrder.fs b/src/Aardvark.Rendering.Common/Modes/WindingOrder.fs similarity index 100% rename from src/Aardvark.Rendering/Pipeline/Modes/WindingOrder.fs rename to src/Aardvark.Rendering.Common/Modes/WindingOrder.fs diff --git a/src/Aardvark.Rendering/Sampler/SamplerState.fs b/src/Aardvark.Rendering.Common/Sampler/SamplerState.fs similarity index 100% rename from src/Aardvark.Rendering/Sampler/SamplerState.fs rename to src/Aardvark.Rendering.Common/Sampler/SamplerState.fs diff --git a/src/Aardvark.Rendering/Sampler/TextureFilter.fs b/src/Aardvark.Rendering.Common/Sampler/TextureFilter.fs similarity index 100% rename from src/Aardvark.Rendering/Sampler/TextureFilter.fs rename to src/Aardvark.Rendering.Common/Sampler/TextureFilter.fs diff --git a/src/Aardvark.Rendering.Common/paket.references b/src/Aardvark.Rendering.Common/paket.references new file mode 100644 index 000000000..a5969b7e4 --- /dev/null +++ b/src/Aardvark.Rendering.Common/paket.references @@ -0,0 +1,4 @@ +FSharp.Core +Aardvark.Build +Aardvark.Base +System.Reflection.Emit.Lightweight \ No newline at end of file diff --git a/src/Aardvark.Rendering.Common/paket.template b/src/Aardvark.Rendering.Common/paket.template new file mode 100644 index 000000000..dcdcc0d9f --- /dev/null +++ b/src/Aardvark.Rendering.Common/paket.template @@ -0,0 +1,11 @@ +type project +id Aardvark.Rendering.Common +authors Aardvark Platform Team +owners Aardvark Platform Team +projectUrl http://github.com/aardvark-platform +licenseUrl http://www.apache.org/licenses/LICENSE-2.0.txt +repositoryType git +repositoryUrl https://github.com/aardvark-platform/aardvark.rendering +description + Aardvark is an open-source platform for visual computing, real-time graphics and visualization. +include-pdbs true \ No newline at end of file diff --git a/src/Aardvark.Rendering.sln b/src/Aardvark.Rendering.sln index c42688dab..01e04a139 100644 --- a/src/Aardvark.Rendering.sln +++ b/src/Aardvark.Rendering.sln @@ -222,6 +222,8 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "22 - MemoryLeak", "Scratch EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "23 - NativeMemoryLeak", "Scratch (netcore)\23 - NativeMemoryLeak\23 - NativeMemoryLeak.fsproj", "{DD9808AD-AEB3-4E90-A70C-E398CADE55FF}" EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Aardvark.Rendering.Common", "Aardvark.Rendering.Common\Aardvark.Rendering.Common.fsproj", "{FBFF12BC-5292-4154-B985-31130061F3D6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -612,6 +614,10 @@ Global {DD9808AD-AEB3-4E90-A70C-E398CADE55FF}.Debug|Any CPU.Build.0 = Debug|Any CPU {DD9808AD-AEB3-4E90-A70C-E398CADE55FF}.Release|Any CPU.ActiveCfg = Release|Any CPU {DD9808AD-AEB3-4E90-A70C-E398CADE55FF}.Release|Any CPU.Build.0 = Release|Any CPU + {FBFF12BC-5292-4154-B985-31130061F3D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FBFF12BC-5292-4154-B985-31130061F3D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FBFF12BC-5292-4154-B985-31130061F3D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FBFF12BC-5292-4154-B985-31130061F3D6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Aardvark.Rendering/Aardvark.Rendering.fsproj b/src/Aardvark.Rendering/Aardvark.Rendering.fsproj index 76971be01..37cc8a8bd 100644 --- a/src/Aardvark.Rendering/Aardvark.Rendering.fsproj +++ b/src/Aardvark.Rendering/Aardvark.Rendering.fsproj @@ -21,8 +21,6 @@ - - @@ -31,7 +29,6 @@ - @@ -40,6 +37,7 @@ + @@ -81,7 +79,6 @@ - @@ -92,18 +89,6 @@ - - - - - - - - - - - - @@ -163,5 +148,8 @@ + + + \ No newline at end of file diff --git a/src/Aardvark.Rendering/Common/DefaultSemantic.fs b/src/Aardvark.Rendering/Common/DefaultSemantic.fs deleted file mode 100644 index 182c23bbc..000000000 --- a/src/Aardvark.Rendering/Common/DefaultSemantic.fs +++ /dev/null @@ -1,47 +0,0 @@ -namespace Aardvark.Rendering - -open System -open Aardvark.Base - -module DefaultSemantic = - - let Positions = Sym.ofString "Positions" - let Normals = Sym.ofString "Normals" - let Colors = Sym.ofString "Colors" - let DiffuseColorCoordinates = Sym.ofString "DiffuseColorCoordinates" - let LightMapCoordinates = Sym.ofString "LightMapCoordinates" - let NormalMapCoordinates = Sym.ofString "NormalMapCoordinates" - let DiffuseColorUTangents = Sym.ofString "DiffuseColorUTangents" - let DiffuseColorVTangents = Sym.ofString "DiffuseColorVTangents" - - // Single Attributes - let DiffuseColorTexture = Sym.ofString "DiffuseColorTexture" - let AmbientColorTexture = Sym.ofString "AmbientColorTexture" - let EmissiveColorTexture = Sym.ofString "EmissiveColorTexture" - let SpecularColorTexture = Sym.ofString "SpecularColorTexture" - let ShininessTexture = Sym.ofString "ShininessTexture" - - let LightMapTexture = Sym.ofString "LightMapTexture" - let NormalMapTexture = Sym.ofString "NormalMapTexture" - - let Trafo3d = Sym.ofString "Trafo3d" - let DiffuseColorTrafo2d = Sym.ofString "DiffuseColorTrafo2d" - let Name = Sym.ofString "Name" - let Material = Sym.ofString "Material" - let CreaseAngle = Sym.ofString "CreaseAngle" - let WindingOrder = Sym.ofString "WindingOrder" - let AreaSum = Sym.ofString "AreaSum" - - // Various - let DepthStencil = Sym.ofString "DepthStencil" - - [] - let Depth = DepthStencil - - [] - let Stencil = DepthStencil - - let ImageOutput = Sym.ofString "ImageOutput" - let InstanceTrafo = Sym.ofString "InstanceTrafo" - let InstanceTrafoInv = Sym.ofString "InstanceTrafoInv" - let SamplerStateModifier = Sym.ofString "SamplerStateModifier" \ No newline at end of file diff --git a/src/Aardvark.Rendering/Pipeline/Camera.fs b/src/Aardvark.Rendering/Pipeline/Camera.fs deleted file mode 100644 index f97cca101..000000000 --- a/src/Aardvark.Rendering/Pipeline/Camera.fs +++ /dev/null @@ -1,601 +0,0 @@ -namespace Aardvark.Rendering - -open System -open Aardvark.Base -open System.Runtime.CompilerServices - -type CameraView(sky : V3d, location : V3d, forward : V3d, up : V3d, right : V3d) = - let viewTrafo = - lazy ( Trafo3d.ViewTrafo(location, right, up, -forward) ) - - let orientation = - lazy ( - let frame = M33d.FromCols(right, forward, up) |> Mat.Orthonormalized - Rot3d.FromM33d frame - ) - - member x.Sky = sky - member x.Location = location - member x.Forward = forward - member x.Up = up - member x.Right = right - member x.Backward = -forward - member x.Down = -up - member x.Left = -right - - member x.ViewTrafo = viewTrafo.Value - member x.Orientation = orientation.Value - - override x.ToString() = - sprintf "CameraView(sky=%A, location=%A, forward=%A, up=%A, right=%A)" sky location forward up right - - static member LookAt (location : V3d, center : V3d, sky : V3d) = - let fw = center - location |> Vec.normalize - let right = Vec.cross fw sky |> Vec.normalize - let up = Vec.cross right fw |> Vec.normalize - CameraView(sky, location, fw, up, right) - - static member LookAt (location : V3d, center : V3d) = - CameraView.LookAt(location, center, V3d.OOI) - - static member Look (location : V3d, forward : V3d, sky : V3d) = - let right = Vec.cross forward sky |> Vec.normalize - let up = Vec.cross right forward |> Vec.normalize - CameraView(sky, location, forward, up, right) - - static member Look (location : V3d, forward : V3d) = - CameraView.Look(location, forward, V3d.OOI) - - static member Orient (location : V3d, orientation : Rot3d, sky : V3d) = - let frame = M33d.Rotation orientation - CameraView(sky, location, frame.C1, frame.C2, frame.C0) - - static member Orient (location : V3d, orientation : Rot3d) = - CameraView.Orient(location, orientation, V3d.OOI) - - - member x.WithLocation(l : V3d) = - CameraView(sky, l, forward, up, right) - - member x.WithForward(fw : V3d) = - CameraView.Look(location, fw, sky) - - member x.WithRight(right : V3d) = - let forward = Vec.cross sky right |> Vec.normalize - let up = Vec.cross right forward |> Vec.normalize - CameraView(sky, location, forward, up, right) - - member x.WithUp(up : V3d) = - let forward = Vec.cross up right |> Vec.normalize - let right = Vec.cross forward up |> Vec.normalize - CameraView(sky, location, forward, up, right) - - member x.WithBackward(bw : V3d) = - x.WithForward (-bw) - - member x.WithLeft (left : V3d) = - x.WithRight(-left) - - member x.WithDown(down : V3d) = - x.WithUp(-down) - - member x.WithOrientation(orientation : Rot3d) = - CameraView.Orient(location, orientation, sky) - - -[] -module CameraView = - - let lookAt (location : V3d) (center : V3d) (sky : V3d) = - CameraView.LookAt(location, center, sky) - - let look (location : V3d) (forward : V3d) (sky : V3d) = - CameraView.Look(location, forward, sky) - - let orient (location : V3d) (orientation : Rot3d) (sky : V3d) = - CameraView.Orient(location, orientation, sky) - - - let withLocation (location : V3d) (c : CameraView) = - c.WithLocation location - - let withForward (forward : V3d) (c : CameraView) = - c.WithForward forward - - let withRight (right : V3d) (c : CameraView) = - c.WithRight right - - let withUp (up : V3d) (c : CameraView) = - c.WithUp up - - let withBackward (backward : V3d) (c : CameraView) = - c.WithBackward backward - - let withLeft (left : V3d) (c : CameraView) = - c.WithLeft left - - let withDown (down : V3d) (c : CameraView) = - c.WithDown down - - let withOrientation (orientation : Rot3d) (c : CameraView) = - c.WithOrientation orientation - - - let viewTrafo (c : CameraView) = - c.ViewTrafo - - let orientation (c : CameraView) = - c.Orientation - - let ofTrafo (t : Trafo3d) = - let bw = t.Backward - - let right = bw.C0.XYZ // bw.TransformDir(V3d.IOO) - let up = bw.C1.XYZ // bw.TransformDir(V3d.OIO) - let forward = -bw.C2.XYZ // bw.TransformDir(-V3d.OOI) - let location = bw.C3.XYZ // bw.TransformPos(V3d.OOO) - - CameraView(up, location, forward, up, right) - - let tryGetCenterOn (p : Plane3d) (c : CameraView) = - let r = Ray3d(c.Location, c.Forward) - - let mutable t = Double.PositiveInfinity - if r.Intersects(p, &t) && t >= 0.0 then - Some (r.GetPointOnRay t) - else - None - - - - let inline location (c : CameraView) = c.Location - let inline forward (c : CameraView) = c.Forward - let inline right (c : CameraView) = c.Right - let inline up (c : CameraView) = c.Up - let inline backward (c : CameraView) = c.Backward - let inline left (c : CameraView) = c.Left - let inline down (c : CameraView) = c.Down - - - - - -type Frustum = - { - left : float - right : float - bottom : float - top : float - near : float - far : float - isOrtho : bool - } - -[] -module Frustum = - let perspective (horizontalFieldOfViewInDegrees : float) (near : float) (far : float) (aspect : float) = - let d = tan (0.5 * Conversion.RadiansFromDegrees horizontalFieldOfViewInDegrees) * near - { left = -d; right = +d; bottom = -d / aspect; top = +d / aspect; near = near; far = far; isOrtho = false } - - let ortho (b : Box3d) = - { - left = b.Min.X - right = b.Max.X - bottom = b.Min.Y - top = b.Max.Y - near = b.Min.Z - far = b.Max.Z - isOrtho = true - } - - let projTrafo {left = l; right = r; top = t; bottom = b; near = n; far = f; isOrtho = isOrtho } : Trafo3d = - if isOrtho then - Trafo3d.OrthoProjectionGL(l, r, b, t, n, f) - else - Trafo3d.PerspectiveProjectionGL(l, r, b, t, n, f) - - let private isTrafoOrtho (t : Trafo3d) = - t.Forward.M30.IsTiny() && t.Forward.M31.IsTiny() && t.Forward.M32.IsTiny() - - let ofTrafo (t : Trafo3d) = - let isOrtho = isTrafoOrtho t - let m = t.Forward - if not isOrtho then - - let r = (1.0 + m.M22) / (m.M22 - 1.0) - let far = (r - 1.0) * m.M23 / (2.0 * r) - let near = r * far - let top = (1.0 + m.M12) * near / m.M11 - let bottom = (m.M12 - 1.0) * near / m.M11 - let left = (m.M02 - 1.0) * near / m.M00 - let right = (1.0 + m.M02) * near / m.M00 - - - { - isOrtho = false - left = left - right = right - top = top - bottom = bottom - near = near - far = far - } - else - let left = -(1.0 + m.M03) / m.M00 - let right = (1.0 - m.M03) / m.M00 - let bottom = -(1.0 + m.M13) / m.M11 - let top = (1.0 - m.M13) / m.M11 - let far = -(1.0 + m.M23) / m.M22 - let near = (1.0 - m.M23) / m.M22 - { - isOrtho = true - left = left - right = right - top = top - bottom = bottom - near = near - far = far - } - - let withNear (near : float) (f : Frustum) = - if f.isOrtho then - { f with near = near } - else - let factor = near / f.near - { - isOrtho = false - near = near - far = f.far - left = factor * f.left - right = factor * f.right - top = factor * f.top - bottom = factor * f.bottom - } - - let withFar (far : float) (f : Frustum) = - { f with far = far } - - let aspect { left = l; right = r; top = t; bottom = b } = - (r - l) / (t - b) - - let withAspect (newAspect : float) ( { left = l; right = r; top = t; bottom = b } as f ) = - let factor = aspect f / newAspect - { f with top = factor * t; bottom = factor * b } - - let withHorizontalFieldOfViewInDegrees (angleInDegrees : float) (frustum : Frustum) = - if frustum.isOrtho then - frustum - else - let aspect = aspect frustum - perspective angleInDegrees frustum.near frustum.far aspect - - let horizontalFieldOfViewInDegrees { left = l; right = r; near = near } = - let l,r = atan2 l near, atan2 r near - Conversion.DegreesFromRadians(-l + r) - - let inline near (f : Frustum) = f.near - let inline far (f : Frustum) = f.far - let inline left (f : Frustum) = f.left - let inline right (f : Frustum) = f.right - let inline bottom (f : Frustum) = f.bottom - let inline top (f : Frustum) = f.top - - let pickRayDirection (pp : PixelPosition) (f : Frustum) = - let n = pp.NormalizedPosition - let ndc = V3d(2.0 * n.X - 1.0, 1.0 - 2.0 * n.Y, 0.0) - let trafo = projTrafo f - let dir = trafo.Backward.TransformPosProj ndc |> Vec.normalize - dir - - -type Camera = - { - cameraView : CameraView - frustum : Frustum - } - -[] -module Camera = - - let create (view : CameraView) (f : Frustum) = - { cameraView = view; frustum = f } - - let pickRay (cam : Camera) (pp : PixelPosition) = - let dir = cam.frustum |> Frustum.pickRayDirection pp - let worldDir = cam.cameraView.ViewTrafo.Backward.TransformDir dir - Ray3d(cam.cameraView.Location, Vec.normalize worldDir) - - let tryGetPickPointOnPlane (cam : Camera) (plane : Plane3d) (pp : PixelPosition) = - let r = pickRay cam pp - - let mutable t = Double.PositiveInfinity - if r.Intersects(plane, &t) && t >= 0.0 then - Some (r.GetPointOnRay t) - else - None - - - let inline viewTrafo (cam : Camera) = cam.cameraView |> CameraView.viewTrafo - - let inline projTrafo (cam : Camera) = cam.frustum |> Frustum.projTrafo - - let viewProjTrafo (cam : Camera) = (CameraView.viewTrafo cam.cameraView) * (Frustum.projTrafo cam.frustum) - - let inline cameraView (cam : Camera) = cam.cameraView - let inline frustum (cam : Camera) = cam.frustum - - - - let inline location (cam : Camera) = cam.cameraView |> CameraView.location - let inline forward (cam : Camera) = cam.cameraView |> CameraView.forward - let inline up (cam : Camera) = cam.cameraView |> CameraView.up - let inline right (cam : Camera) = cam.cameraView |> CameraView.right - let inline backward (cam : Camera) = cam.cameraView |> CameraView.backward - let inline down (cam : Camera) = cam.cameraView |> CameraView.down - let inline left (cam : Camera) = cam.cameraView |> CameraView.left - let inline near (cam : Camera) = cam.frustum.near - let inline far (cam : Camera) = cam.frustum.far - - - -[] -module ViewProjection = - - [] - module private Helpers = - let inline toPlane (v : V4d) = - Plane3d(-v.XYZ, v.W) - - let inline maxDir (dir : V3d) (b : Box3d) = - V4d( - (if dir.X > 0.0 then b.Max.X else b.Min.X), - (if dir.Y > 0.0 then b.Max.Y else b.Min.Y), - (if dir.Z > 0.0 then b.Max.Z else b.Min.Z), - 1.0 - ) - - let inline height (plane : V4d) (b : Box3d) = - plane.Dot(maxDir plane.XYZ b) - - - let intersect (a : Plane3d) (b : Plane3d) (c : Plane3d) = - let mutable pt = V3d.Zero - if a.Intersects(b,c, &pt) then - pt - else - failwith "no plane intersection" - - - let inline proj (pt : V3d) = V3d(pt.XY / -pt.Z, -pt.Z) - - - let containing (viewPos : V3d) (bounds : Box3d) = - let angularRange = - bounds.ComputeCorners() - |> Array.map (fun world -> - let dir = world - viewPos - dir.SphericalFromCartesian() - ) - |> Box2d - - let forward = angularRange.Center.CartesianFromSpherical() - - let mutable closest = V3d.Zero - let mutable farthest = V3d.Zero - bounds.GetMinMaxInDirection(forward, &closest, &farthest) - let near = Vec.distance viewPos closest - let far = Vec.distance viewPos farthest - - - - let halfAngularSize = angularRange.Size * 0.5 - let l = -near * Fun.Tan(halfAngularSize.X) - let r = -l - let t = near * Fun.Tan(halfAngularSize.Y) - let b = -t - - - let sky = - if Fun.ApproximateEquals(abs forward.Z, 1.0, Constant.PositiveTinyValue) then V3d.OIO - else V3d.OOI - - let view = CameraView.lookAt viewPos (viewPos + forward) sky - let proj = - { - left = l - right = r - top = t - bottom = b - near = near - far = far - isOrtho = false - } - - view, proj - - - - let intersects (b : Box3d) (viewProj : Trafo3d) = - let fw = viewProj.Forward - let r0 = fw.R0 - let r1 = fw.R1 - let r2 = fw.R2 - let r3 = fw.R3 - - height (r3 + r0) b >= 0.0 && - height (r3 - r0) b >= 0.0 && - height (r3 + r1) b >= 0.0 && - height (r3 - r1) b >= 0.0 && - height (r3 + r2) b >= 0.0 && - height (r3 - r2) b >= 0.0 - - let contains (point : V3d) (viewProj : Trafo3d) = - let fw = viewProj.Forward - let r0 = fw.R0 - let r1 = fw.R1 - let r2 = fw.R2 - let r3 = fw.R3 - let p = V4d(point, 1.0) - - Vec.dot (r3 + r0) p >= 0.0 && - Vec.dot (r3 - r0) p >= 0.0 && - Vec.dot (r3 + r1) p >= 0.0 && - Vec.dot (r3 - r1) p >= 0.0 && - Vec.dot (r3 + r2) p >= 0.0 && - Vec.dot (r3 - r2) p >= 0.0 - - let private frustumCorners = - [| - V3d(-1.0, -1.0, -1.0) - V3d( 1.0, -1.0, -1.0) - V3d( 1.0, 1.0, -1.0) - V3d(-1.0, 1.0, -1.0) - V3d(-1.0, -1.0, 1.0) - V3d( 1.0, -1.0, 1.0) - V3d( 1.0, 1.0, 1.0) - V3d(-1.0, 1.0, 1.0) - |] - - let private cornerIndices = - [| - 1;2; 2;6; 6;5; 5;1; - 2;3; 3;7; 7;6; 4;5; - 7;4; 3;0; 0;4; 0;1; - |] - - let toIndexedGeometry (v : CameraView) (p : Frustum) (color : C4b) = - let invViewProj = (CameraView.viewTrafo v * Frustum.projTrafo p).Inverse - - let positions = frustumCorners |> Array.map (invViewProj.Forward.TransformPosProj) - - IndexedGeometry( - Mode = IndexedGeometryMode.LineList, - IndexedAttributes = - SymDict.ofList [ - DefaultSemantic.Positions, cornerIndices |> Array.map (fun i -> positions.[i].ToV3f()) :> Array - DefaultSemantic.Colors, Array.create cornerIndices.Length color :> Array - ] - ) - - let leftPlane (viewProj : Trafo3d) = - let r0 = viewProj.Forward.R0 - let r3 = viewProj.Forward.R3 - r3 - r0 - - let rightPlane (viewProj : Trafo3d) = - let r0 = viewProj.Forward.R0 - let r3 = viewProj.Forward.R3 - r3 + r0 - - let toHull3d (viewProj : Trafo3d) = - let r0 = viewProj.Forward.R0 - let r1 = viewProj.Forward.R1 - let r2 = viewProj.Forward.R2 - let r3 = viewProj.Forward.R3 - - - Hull3d [| - r3 - r0 |> toPlane // right - r3 + r0 |> toPlane // left - r3 + r1 |> toPlane // bottom - r3 - r1 |> toPlane // top - r3 + r2 |> toPlane // near - r3 - r2 |> toPlane // far - |] - - let inline toFastHull3d (viewProj : Trafo3d) = - FastHull3d(toHull3d viewProj) - - - let intersectsDX (b : Box3d) (viewProj : Trafo3d) = - let fw = viewProj.Forward - let r0 = fw.R0 - let r1 = fw.R1 - let r2 = fw.R2 - let r3 = fw.R3 - - height (r3 + r0) b >= 0.0 && - height (r3 - r0) b >= 0.0 && - height (r3 + r1) b >= 0.0 && - height (r3 - r1) b >= 0.0 && - height ( r2) b >= 0.0 && - height (r3 - r2) b >= 0.0 - - let containsDX (point : V3d) (viewProj : Trafo3d) = - let fw = viewProj.Forward - let r0 = fw.R0 - let r1 = fw.R1 - let r2 = fw.R2 - let r3 = fw.R3 - let p = V4d(point, 1.0) - - Vec.dot (r3 + r0) p >= 0.0 && - Vec.dot (r3 - r0) p >= 0.0 && - Vec.dot (r3 + r1) p >= 0.0 && - Vec.dot (r3 - r1) p >= 0.0 && - Vec.dot ( r2) p >= 0.0 && - Vec.dot (r3 - r2) p >= 0.0 - - let toHull3dDX (viewProj : Trafo3d) = - let r0 = viewProj.Forward.R0 - let r1 = viewProj.Forward.R1 - let r2 = viewProj.Forward.R2 - let r3 = viewProj.Forward.R3 - - - Hull3d [| - r3 + r0 |> toPlane - r3 - r0 |> toPlane - r3 + r1 |> toPlane - r3 - r1 |> toPlane - r2 |> toPlane - r3 - r2 |> toPlane - |] - - let inline toFastHull3dDX (viewProj : Trafo3d) = - FastHull3d(toHull3dDX viewProj) - - let mergeStereo (lProj : Trafo3d) (rProj : Trafo3d) = - let p (v : V4d) = Plane3d(v.XYZ, -v.W) - - - let lPlane = rightPlane lProj |> p - let rPlane = leftPlane rProj |> p - - let location = intersect lPlane rPlane Plane3d.YPlane - let view = Trafo3d.Translation(-location) - - let points = - Array.concat [| - frustumCorners |> Array.map lProj.Backward.TransformPosProj - frustumCorners |> Array.map rProj.Backward.TransformPosProj - |] - - let projected = - points |> Array.map (view.Forward.TransformPos >> proj) - - let bounds = Box3d(projected) - - let near = bounds.Min.Z - let far = bounds.Max.Z - - let frustum = - { - left = bounds.Min.X * near - right = bounds.Max.X * near - top = bounds.Max.Y * near - bottom = bounds.Min.Y * near - near = near - far = far - isOrtho = false - } - - let proj = Frustum.projTrafo frustum - view * proj - - - -[] -type CameraCSharpExtensions() = - [] - static member ProjTrafo(f : Frustum) = Frustum.projTrafo f diff --git a/src/Aardvark.Rendering/Utilities/CameraExtensions.fs b/src/Aardvark.Rendering/Utilities/CameraExtensions.fs new file mode 100644 index 000000000..6860bc073 --- /dev/null +++ b/src/Aardvark.Rendering/Utilities/CameraExtensions.fs @@ -0,0 +1,30 @@ +namespace Aardvark.Rendering + +open System +open Aardvark.Base + +[] +module CameraExtensions = + + module Frustum = + let pickRayDirection (pp : PixelPosition) (f : Frustum) = + let n = pp.NormalizedPosition + let ndc = V3d(2.0 * n.X - 1.0, 1.0 - 2.0 * n.Y, 0.0) + let trafo = Frustum.projTrafo f + let dir = trafo.Backward.TransformPosProj ndc |> Vec.Normalized + dir + + module Camera = + let pickRay (cam : Camera) (pp : PixelPosition) = + let dir = cam.frustum |> Frustum.pickRayDirection pp + let worldDir = cam.cameraView.ViewTrafo.Backward.TransformDir dir + Ray3d(cam.cameraView.Location, Vec.Normalized worldDir) + + let tryGetPickPointOnPlane (cam : Camera) (plane : Plane3d) (pp : PixelPosition) = + let r = pickRay cam pp + + let mutable t = Double.PositiveInfinity + if r.Intersects(plane, &t) && t >= 0.0 then + Some (r.GetPointOnRay t) + else + None \ No newline at end of file