fluff
[vg.git] / vg_m.h
diff --git a/vg_m.h b/vg_m.h
index c07f38984e07ada336ffe5c8328fef6649a3243a..0ded4e127302bfd0d396f14416c12710eeb3fb84 100644 (file)
--- a/vg_m.h
+++ b/vg_m.h
@@ -18,6 +18,7 @@
  *    5.c Closest points
  *    5.d Raycast & Spherecasts
  *    5.e Curves
+ *    5.f Volumes
  *  6. Statistics
  *    6.a Random numbers
  **/
@@ -62,6 +63,12 @@ static int vg_validf( f32 a )
    return ((vg_ftu32(a)) & 0x7F800000U) != 0x7F800000U;
 }
 
+static int v3_valid( v3f a ){
+   for( u32 i=0; i<3; i++ )
+      if( !vg_validf(a[i]) ) return 0;
+   return 1;
+}
+
 /*
  * -----------------------------------------------------------------------------
  * Section 1.                   Scalar Operations
@@ -392,8 +399,7 @@ static inline void v3_normalize( v3f a )
    v3_muls( a, 1.f / v3_length( a ), a );
 }
 
-static inline f32 vg_lerpf( f32 a, f32 b, f32 t )
-{
+static inline f32 vg_lerpf( f32 a, f32 b, f32 t ){
    return a + t*(b-a);
 }
 
@@ -402,6 +408,17 @@ static inline f64 vg_lerp( f64 a, f64 b, f64 t )
    return a + t*(b-a);
 }
 
+static inline void vg_slewf( f32 *a, f32 b, f32 speed ){
+   f32 d = vg_signf( b-*a ),
+       c = *a + d*speed;
+   *a = vg_minf( b*d, c*d ) * d;
+}
+
+static inline f32 vg_smoothstepf( f32 x ){
+   return x*x*(3.0f - 2.0f*x);
+}
+
+
 /* correctly lerp around circular period -pi -> pi */
 static f32 vg_alerpf( f32 a, f32 b, f32 t )
 {
@@ -480,6 +497,24 @@ static inline void v3_rotate( v3f v, f32 angle, v3f axis, v3f d )
   v3_add( v1, v2, d );
 }
 
+static void v3_tangent_basis( v3f n, v3f tx, v3f ty ){
+   /* Compute tangent basis (box2d) */
+   if( fabsf( n[0] ) >= 0.57735027f ){
+      tx[0] =  n[1];
+      tx[1] = -n[0];
+      tx[2] =  0.0f;
+   }
+   else{
+      tx[0] =  0.0f;
+      tx[1] =  n[2];
+      tx[2] = -n[1];
+   }
+
+   v3_normalize( tx );
+   v3_cross( n, tx, ty );
+}
+
+
 /*
  * -----------------------------------------------------------------------------
  * Section 2.c                   4D Vectors
@@ -573,11 +608,15 @@ static inline void q_mul( v4f q, v4f q1, v4f d )
 
 static inline void q_normalize( v4f q )
 {
-   f32 s = 1.0f/ sqrtf(v4_dot(q,q));
-   q[0] *= s;
-   q[1] *= s;
-   q[2] *= s;
-   q[3] *= s;
+   f32 l2 = v4_dot(q,q);
+   if( l2 < 0.00001f ) q_identity( q );
+   else {
+      f32 s = 1.0f/sqrtf(l2);
+      q[0] *= s;
+      q[1] *= s;
+      q[2] *= s;
+      q[3] *= s;
+   }
 }
 
 static inline void q_inv( v4f q, v4f d )
@@ -2120,6 +2159,17 @@ static void eval_bezier3( v3f p0, v3f p1, v3f p2, f32 t, v3f p )
    v3_muladds( p, p2, t*t, p );
 }
 
+/*
+ * -----------------------------------------------------------------------------
+ * Section 5.f                      Volumes
+ * -----------------------------------------------------------------------------
+ */
+
+static float vg_sphere_volume( float radius ){
+   float r3 = radius*radius*radius;
+   return (4.0f/3.0f) * VG_PIf * r3;
+}
+
 /*
  * -----------------------------------------------------------------------------
  * Section 6.a            PSRNG and some distributions
@@ -2160,7 +2210,7 @@ static void vg_rand_seed( unsigned long seed )
     * Programming," Vol. 2 (2nd Ed.) pp.102.
     */
    vg_rand.mt[0] = seed & 0xffffffff;
-   for( vg_rand.index=1; vg_rand.index<MT_STATE_VECTOR_LENGTH; vg_rand.index++ ){
+   for( vg_rand.index=1; vg_rand.index<MT_STATE_VECTOR_LENGTH; vg_rand.index++){
       vg_rand.mt[vg_rand.index] = 
          (6069 * vg_rand.mt[vg_rand.index-1]) & 0xffffffff;
    }