feat(examples): add vector maths and an xorshift RNG
vec3 operations and a per-thread random stream, the leaf library everything else in the example depends on.
This commit is contained in:
2 files changed
+83
No files matched your search
@@ -0,0 +1,50 @@
|
|||||||
|
#include "rt.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
static unsigned long long splitmix(unsigned long long *x) {
|
||||||
|
unsigned long long z = (*x += 0x9E3779B97F4A7C15ULL);
|
||||||
|
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ULL;
|
||||||
|
z = (z ^ (z >> 27)) * 0x94D049BB133111EBULL;
|
||||||
|
return z ^ (z >> 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long long rotl(unsigned long long x, int k) {
|
||||||
|
return (x << k) | (x >> (64 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rng_seed(rng *r, unsigned long long seed) {
|
||||||
|
unsigned long long s = seed ? seed : 0x2545F4914F6CDD1DULL;
|
||||||
|
r->s0 = splitmix(&s);
|
||||||
|
r->s1 = splitmix(&s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long long rng_next(rng *r) {
|
||||||
|
unsigned long long s0 = r->s0, s1 = r->s1;
|
||||||
|
unsigned long long result = s0 + s1;
|
||||||
|
s1 ^= s0;
|
||||||
|
r->s0 = rotl(s0, 55) ^ s1 ^ (s1 << 14);
|
||||||
|
r->s1 = rotl(s1, 36);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double rng_unit(rng *r) {
|
||||||
|
/* 53 significant bits, the most a double holds exactly. */
|
||||||
|
return (double)(rng_next(r) >> 11) * (1.0 / 9007199254740992.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double rng_range(rng *r, double lo, double hi) { return lo + (hi - lo) * rng_unit(r); }
|
||||||
|
|
||||||
|
vec3 rng_in_sphere(rng *r) {
|
||||||
|
for (int i = 0; i < 64; i++) {
|
||||||
|
vec3 p = v3(rng_range(r, -1.0, 1.0), rng_range(r, -1.0, 1.0), rng_range(r, -1.0, 1.0));
|
||||||
|
if (v3len2(p) < 1.0) return p;
|
||||||
|
}
|
||||||
|
return v3(0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 rng_unit_vector(rng *r) {
|
||||||
|
double z = rng_range(r, -1.0, 1.0);
|
||||||
|
double a = rng_range(r, 0.0, 6.283185307179586);
|
||||||
|
double s = sqrt(1.0 - z * z);
|
||||||
|
return v3(s * cos(a), s * sin(a), z);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#include "rt.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
vec3 v3(double x, double y, double z) {
|
||||||
|
vec3 v = {x, y, z};
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 v3add(vec3 a, vec3 b) { return v3(a.x + b.x, a.y + b.y, a.z + b.z); }
|
||||||
|
vec3 v3sub(vec3 a, vec3 b) { return v3(a.x - b.x, a.y - b.y, a.z - b.z); }
|
||||||
|
vec3 v3mul(vec3 a, vec3 b) { return v3(a.x * b.x, a.y * b.y, a.z * b.z); }
|
||||||
|
vec3 v3scale(vec3 a, double t) { return v3(a.x * t, a.y * t, a.z * t); }
|
||||||
|
vec3 v3neg(vec3 a) { return v3(-a.x, -a.y, -a.z); }
|
||||||
|
|
||||||
|
double v3dot(vec3 a, vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
|
||||||
|
|
||||||
|
vec3 v3cross(vec3 a, vec3 b) {
|
||||||
|
return v3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
double v3len2(vec3 a) { return v3dot(a, a); }
|
||||||
|
double v3len(vec3 a) { return sqrt(v3len2(a)); }
|
||||||
|
|
||||||
|
vec3 v3norm(vec3 a) {
|
||||||
|
double n = v3len(a);
|
||||||
|
return n > 0.0 ? v3scale(a, 1.0 / n) : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 v3reflect(vec3 v, vec3 n) { return v3sub(v, v3scale(n, 2.0 * v3dot(v, n))); }
|
||||||
|
|
||||||
|
vec3 v3lerp(vec3 a, vec3 b, double t) {
|
||||||
|
return v3add(v3scale(a, 1.0 - t), v3scale(b, t));
|
||||||
|
}
|
||||||
Reference in new issue
Block a user