Source: vec.goose

SHA-256 2cac168c72047834433bfb419734c38455c9429ea045b1273898031c53faa82e · Raw source

1// The Goose standard library: `vec` (docs/stdlib.md): small vectors as
2// plain structs. Elementwise + - * / are the language's (§6.1); the
3// scalar * / broadcast too. The functions here combine components. The int aliases are
4// i32 because vectors are data (§3.1), and an i32 component widens into an
5// i64 index implicitly.
6
7import math;
8
9struct vec2<T> { x: T, y: T }
10struct vec3<T> { x: T, y: T, z: T }
11struct vec4<T> { x: T, y: T, z: T, w: T }
12
13type float2 = vec2<f32>;
14type float3 = vec3<f32>;
15type float4 = vec4<f32>;
16type double2 = vec2<f64>;
17type double3 = vec3<f64>;
18type double4 = vec4<f64>;
19type int2 = vec2<i32>;
20type int3 = vec3<i32>;
21type int4 = vec4<i32>;
22
23let float2_0 = float2 { 0.0, 0.0 };
24let float2_1 = float2 { 1.0, 1.0 };
25let float3_0 = float3 { 0.0, 0.0, 0.0 };
26let float3_1 = float3 { 1.0, 1.0, 1.0 };
27let float4_0 = float4 { 0.0, 0.0, 0.0, 0.0 };
28let float4_1 = float4 { 1.0, 1.0, 1.0, 1.0 };
29let double2_0 = double2 { 0.0, 0.0 };
30let double2_1 = double2 { 1.0, 1.0 };
31let double3_0 = double3 { 0.0, 0.0, 0.0 };
32let double3_1 = double3 { 1.0, 1.0, 1.0 };
33let double4_0 = double4 { 0.0, 0.0, 0.0, 0.0 };
34let double4_1 = double4 { 1.0, 1.0, 1.0, 1.0 };
35let int2_0 = int2 { 0, 0 };
36let int2_1 = int2 { 1, 1 };
37let int3_0 = int3 { 0, 0, 0 };
38let int3_1 = int3 { 1, 1, 1 };
39let int4_0 = int4 { 0, 0, 0, 0 };
40let int4_1 = int4 { 1, 1, 1, 1 };
41
42fn dot<T>(a: vec2<T>, b: vec2<T>) -> T { a.x * b.x + a.y * b.y }
43fn dot<T>(a: vec3<T>, b: vec3<T>) -> T { a.x * b.x + a.y * b.y + a.z * b.z }
44fn dot<T>(a: vec4<T>, b: vec4<T>) -> T { a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w }
45
46fn cross<T>(a: vec3<T>, b: vec3<T>) -> vec3<T> {
47    vec3<T> { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x }
48}
49
50fn length_sq<T>(v: vec2<T>) -> T { dot(v, v) }
51fn length_sq<T>(v: vec3<T>) -> T { dot(v, v) }
52fn length_sq<T>(v: vec4<T>) -> T { dot(v, v) }
53
54// Float vectors only: sqrt has f32 and f64 forms.
55fn length<T>(v: vec2<T>) -> T { sqrt(length_sq(v)) }
56fn length<T>(v: vec3<T>) -> T { sqrt(length_sq(v)) }
57fn length<T>(v: vec4<T>) -> T { sqrt(length_sq(v)) }
58
59fn normalize<T>(v: vec2<T>) -> vec2<T> { v / length(v) }
60fn normalize<T>(v: vec3<T>) -> vec3<T> { v / length(v) }
61fn normalize<T>(v: vec4<T>) -> vec4<T> { v / length(v) }
62
63fn distance<T>(a: vec2<T>, b: vec2<T>) -> T { length(a - b) }
64fn distance<T>(a: vec3<T>, b: vec3<T>) -> T { length(a - b) }
65fn distance<T>(a: vec4<T>, b: vec4<T>) -> T { length(a - b) }
66
67fn lerp<T>(a: vec2<T>, b: vec2<T>, t: T) -> vec2<T> {
68    vec2<T> { a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t }
69}
70fn lerp<T>(a: vec3<T>, b: vec3<T>, t: T) -> vec3<T> {
71    vec3<T> { a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t }
72}
73fn lerp<T>(a: vec4<T>, b: vec4<T>, t: T) -> vec4<T> {
74    vec4<T> { a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t,
75              a.w + (b.w - a.w) * t }
76}
77
78fn xy<T>(v: vec3<T>) -> vec2<T> { vec2<T> { v.x, v.y } }
79fn xy<T>(v: vec4<T>) -> vec2<T> { vec2<T> { v.x, v.y } }
80fn xyz<T>(v: vec4<T>) -> vec3<T> { vec3<T> { v.x, v.y, v.z } }