6061b1d0fe28 — Leonard Ritter 2 months ago
* initial work on interval/RAA arithmetic module
* sdf: made `sdBox` work for all fvec types
4 files changed, 210 insertions(+), 4 deletions(-)

M testing/test_compute.sc
A => testing/test_raa.sc
A => tukan/interval.sc
M tukan/sdf.sc
M testing/test_compute.sc +3 -0
@@ 24,4 24,7 @@ test ((gpucall findlsb 32768) == (findls
 test ((gpucall bitreverse 0b10010110) == (bitreverse 0b10010110))
 test (all? ((gpucall findmsb (vectorof i32 1 3 5 9)) == (vectorof i32 0 1 2 3)))
 test ((gpucall findmsb 6) == (findmsb 6))
+test ((gpucall findmsb 0) == (findmsb 0))
+test ((gpucall findlsb 0) == (findlsb 0))
 
+;
  No newline at end of file

          
A => testing/test_raa.sc +32 -0
@@ 0,0 1,32 @@ 
+
+import ..tukan.use
+
+using import glm
+using import tukan.interval
+
+print
+    (Interval -0.25 1.0) as Affine as Interval
+
+let x =
+    Affine.linear 0.0 1.0 0.0 0.0
+let y =
+    Affine.linear 0.0 0.0 1.0 0.0
+
+print
+    x + y
+print
+    - x
+
+print
+    x + 3.0
+
+print x
+    'radius x
+
+print
+    'radius
+        1.0 as Affine2
+
+;
+
+

          
A => tukan/interval.sc +170 -0
@@ 0,0 1,170 @@ 
+""""types and functions to help with performing
+    interval arithmetic and revised affine arithmetic
+
+using import glm
+using import struct
+
+typedef IntervalType < CStruct
+
+@@ memo
+inline IntervalType-type (element-type count)
+    struct (.. "<Interval " (tostring element-type) ">") < IntervalType
+        let ElementType = element-type
+        let VectorType = (vec-type element-type 2)
+        i : VectorType
+
+inline... IntervalType-type (element-type : type,)
+    IntervalType-type element-type
+
+# interval
+typedef+ IntervalType
+    inline __typecall (cls ...)
+        static-if (cls == this-type)
+            IntervalType-type ...
+        else
+            super-type.__typecall cls
+                cls.VectorType ...
+
+    fn __repr (self)
+        let cls = (typeof self)
+        .. "["
+            repr (self.i @ 0)
+            " .. "
+            repr (self.i @ 1)
+            "]"
+
+#   Revised Affine Arithmetic
+    based on the implementation guide contained in
+    Fast Reliable Interrogation of Procedurally Defined Implicit Surfaces
+    Using Extended Revised Affine Arithmetic
+    by Fryazinov, Pasko et al
+    and
+    VU X.-H., SAM-HAROUD D., FALTINGS B.: A Generic Scheme for Combining
+    Multiple Inclusion Representations in Numerical Constraint Propagation
+    (namely chapter 4.1)
+    and
+    An Introduction to Affine Arithmetic
+    by stolfi et al.
+
+    also see https://www.shadertoy.com/view/4sV3zm (Affine Arithmetic Joint Range)
+
+typedef AffineType < CStruct
+
+@@ memo
+inline AffineType-type (element-type count)
+    struct (.. "<Affine " (tostring element-type) "x" (tostring count) ">") < AffineType
+        let ElementType = element-type
+        let Count = count
+        let VectorType = (vector element-type (count + 1))
+        let IntervalType = (IntervalType ElementType)
+
+        x : VectorType # x @ 0 + x @ 1 + ... + x @ count
+        e : ElementType # error term
+
+inline... AffineType-type (element-type : type, count : i32)
+    AffineType-type element-type count
+
+# revised affine form of rank 1
+typedef+ AffineType
+    inline __typecall (cls ...)
+        static-if (cls == this-type)
+            AffineType-type ...
+        else
+            super-type.__typecall cls ...
+
+    fn __repr (self)
+        let cls = (typeof self)
+        .. "<"
+            ..
+                va-map
+                    inline (i)
+                        .. "x" (tostring i) "=" (repr (self.x @ i)) " "
+                    va-range (cls.Count + 1)
+            \ "e=" (repr self.e)
+            ">"
+
+    fn radius (self)
+        let cls = (typeof self)
+        + self.e
+            va-lfold (abs (self.x @ 1))
+                inline (k i result)
+                    i := i + 2
+                    max result
+                        abs (self.x @ i)
+                va-range (cls.Count - 1)
+
+    fn linear (x0 ...)
+        """"construct affine from linear combination
+            f(x, y, ...) = x0 + x1*x + x2*y + ...
+        let cls = (this-type (typeof x0) (va-countof ...))
+        let ET = cls.ElementType
+        cls
+            vectorof ET x0 ...
+            nullof ET
+
+    @@ memo
+    inline __+ (cls T)
+        static-if (cls == T)
+            fn (a b)
+                cls
+                    a.x + b.x
+                    a.e + b.e
+
+    @@ memo
+    inline __- (cls T)
+        static-if (cls == T)
+            fn (a b)
+                cls
+                    a.x - b.x
+                    a.e + b.e
+
+    fn __neg (self)
+        let cls = (typeof self)
+        cls
+            (vector.smear (nullof cls.ElementType) (countof cls.VectorType)) - self.x
+            self.e
+
+    @@ memo
+    inline __imply (cls T)
+        let IT = cls.IntervalType
+        static-if (T == IT)
+            inline (self)
+                let r = (radius self)
+                let c = (deref (self.x @ 0))
+                IT (c - r) (c + r)
+
+    @@ memo
+    inline __rimply (T cls)
+        let ET = cls.ElementType
+        let IT = cls.IntervalType
+        let NullElement = (nullof ET)
+        static-if (T == ET)
+            inline (self)
+                cls
+                    vectorof ET self
+                        va-map
+                            inline (i) NullElement
+                            va-range cls.Count
+        elseif (T == IT)
+            inline (self)
+                let i0 i1 =
+                    unpack self.i
+                cls
+                    vectorof ET ((i1 + i0) / 2)
+                        va-map
+                            inline (i) NullElement
+                            va-range cls.Count
+                    (i1 - i0) / 2
+
+
+
+
+do
+    let Interval = (IntervalType f32)
+
+    let Affine = (AffineType f32 1)
+    let Affine2 = (AffineType f32 2)
+    let Affine3 = (AffineType f32 3)
+
+    let AffineType IntervalType
+    locals;

          
M tukan/sdf.sc +5 -4
@@ 260,19 260,20 @@ fn sdTorus (p t)
     (length (vec2 ((length p.xz) - t.x) p.y)) - t.y
 
 fn sdSphere (p r)
-    """"f32 <- vec3 f32
+    """"f32 <- vec-type f32
     (length p) - r
 
 fn sdBox (p s)
-    """"f32 <- vec3 vec3
+    """"f32 <- vec-type vec-type
+    let T = (typeof p)
     let d =
         (abs p) - s
     +
         min
-            max d.x d.y d.z
+            max (unpack d)
             0.0
         length
-            max d (vec3 0.0)
+            max d (T 0.0)
 
 inline sdPlane (p v)
     dot (vec4 p 1.0) v